Current section

Files

Jump to
mobius lib mobius events.ex
Raw

lib/mobius/events.ex

defmodule Mobius.Events do
@moduledoc false
alias Mobius.MetricsTable
alias Telemetry.Metrics
alias Telemetry.Metrics.{Counter, LastValue}
require Logger
@typedoc """
The configuration that is passed to every handle call
* `:table` - the metrics table name used to store metrics
* `:metrics` - the list of metrics that Mobius is to listen for
"""
@type handler_config() :: %{
table: Mobius.name(),
metrics: [Metrics.t()]
}
@doc """
Handle telemetry events
"""
@spec handle(
:telemetry.event_name(),
:telemetry.event_measurements(),
:telemetry.event_metadata(),
handler_config()
) :: :ok
def handle(_event, measurements, metadata, config) do
for metric <- config.metrics do
try do
if value = keep?(metric, metadata) && extract_measurement(metric, measurements, metadata) do
tags = extract_tags(metric, metadata)
handle_metric(metric, value, tags, config)
end
rescue
e ->
Logger.error("Could not format metric #{inspect(metric)}")
Logger.error(Exception.format(:error, e, __STACKTRACE__))
end
end
:ok
end
defp handle_metric(%Counter{} = metric, _value, labels, config) do
MetricsTable.inc_counter(config.table, metric.name, labels)
end
defp handle_metric(%LastValue{} = metric, value, labels, config) do
MetricsTable.put(config.table, metric.name, :last_value, value, labels)
end
defp keep?(%{keep: keep}, metadata) when keep != nil, do: keep.(metadata)
defp keep?(_metric, _metadata), do: true
defp extract_measurement(%Counter{}, _measurements, _metadata) do
1
end
defp extract_measurement(metric, measurements, metadata) do
get_measurement(metric, measurements, metadata)
end
defp get_measurement(metric, measurements, metadata) do
case metric.measurement do
fun when is_function(fun, 1) -> fun.(measurements)
fun when is_function(fun, 2) -> fun.(measurements, metadata)
key -> measurements[key]
end
end
defp extract_tags(metric, metadata) do
tag_values = metric.tag_values.(metadata)
Map.take(tag_values, metric.tags)
end
end