Limen.DecisionLog.Sink behaviour (limen v0.2.1)

Copy Markdown View Source

Where Limen.DecisionLog.Flusher writes sampled decisions.

A sink gets the decisions sampled since the last flush, oldest first, in the flusher's own process, every :flush_interval milliseconds and when the instance stops. Nothing it does touches the request path, so it can take its time: write to a database, a file or a queue.

defmodule MyApp.DecisionSink do
  @behaviour Limen.DecisionLog.Sink

  @impl true
  def write(decisions, _opts) do
    rows = Enum.map(decisions, &Limen.DecisionLog.report/1)
    MyApp.Repo.insert_all("bot_decisions", rows)
    :ok
  end
end

config :my_app, Limen, decision_log: [sink: MyApp.DecisionSink]

The :sink option takes a module, or {module, opts} to pass opts to every call. Only one sink is configured; one that writes to several places can call the others. Limen.DecisionLog.report/1 turns a decision into a map of plain values.

A sink that raises or exits loses that batch: the error is logged and the next flush goes on with the decisions sampled after it. The default sink, Limen.DecisionLog.Logger, writes each decision as a Logger report.

In tests

The flusher's process is not one a test's Ecto sandbox allows, and its batches arrive after the test has moved on. With delivery: :inline in the test configuration, each sampled decision goes to the sink at once, in the process that made it, as a batch of one, and an error in the sink raises there instead of being logged; see "Decision log sinks" in the testing guide. Never use it in production: it puts the sink on the request path.

Summary

Callbacks

Writes a batch of sampled decisions, oldest first. Never called with an empty batch.

Callbacks

write(decisions, opts)

@callback write(decisions :: [Limen.Decision.t(), ...], opts :: keyword()) :: term()

Writes a batch of sampled decisions, oldest first. Never called with an empty batch.