Alchemetrics v0.5.2 Alchemetrics.CustomBackend behaviour View Source

Interface to create CustomBackends.

The backends are responsible for distributing the measurement results. When a dataset is created, it subscribes to all enabled backends and send measurement results to them.

Alchemetrics comes with a built-in backend named Alchemetrics.ConsoleBackend that prints all reported data to console. It can be very useful when debuging your metrics.

Creating a CustomBackend

The Alchemetrics.CustomBackend__using__/1 macro will already include the behavior of custom reporter in a module. The behavior has two callbacks: init/1 and report/4.

The init/1 callback is called at the moment the backend is initialized. This is where, for example, connections to external services are established, or sockets to send data via TCP/UDP are open.

The init/1 callback should return {:ok, state} or {:error, reason}. If {:ok, state} is returned, the state is passed as argument to the report/4 callback. If {:error, reason} is returned, the reporter will not be initialized, and an error will be raised.

The report/4 callback is called every time a dataset is measured. This is where the data is sent to the external service. The params for report/4 are:

Dataset subscription

For the measurements of a dataset to be sent to a backend, the dataset must subscribe to it. By default, datasets automatically subscribe to all active backends at the time of their creation.

When a backend is disabled, all datasets cancel their subscriptions. If that backend is reactivated, only the new datasets will be subscribed.


Let’s see the implementation of a backend that sends metrics to Logstash via UDP:

defmodule MyApp.Backends.UDP do
  use Alchemetrics.CustomBackend

  def init(init_opts) do
    case do
      {:ok, sock} ->
        state = [socket: sock] ++ init_opts
        {:ok, state}
      {:error, reason} ->
        {:error, reason}

  def report(metadata, measure, value, state) do
    metadata = Enum.into(metadata, %{})
    base_report = %{measure: measure, value: value}
    Map.merge(base_report, metadata)
    |> Poison.encode!
    |> send_metric(state)

  defp send_metric(data, state) do
    {sock, host, port} = extract_options(state)
    :gen_udp.send(sock, host, port, data)

  defp extract_options(opts) do
    hostname = String.to_charlist(opts[:hostname])
    {opts[:socket], hostname, opts[:port]}

You can configure your brand new reporter to be enabled when application boots. The array in the config key will be passed as argument to the init/1 function.

# config/config.exs
config :alchemetrics, backends: [
  {MyApp.Backends.UDP, [hostname: "", port: 8888]}

Link to this section Summary

Link to this section Types

Link to this section Callbacks

Link to this callback init(init_opts) View Source
init(init_opts) ::
  {:ok, state} |
  {:ok, Keyword.t} |
  {:error, String.t} |
  {:error, Atom.t}
Link to this callback report(metadata, measure, value, state) View Source
report(metadata, measure, value, state) :: any