defmodule Membrane.TelemetryMetrics do
@moduledoc """
Defines macros for executing telemetry events and registering processes with events.
Provided macros evalueates to meaningful code or to nothing, depending on config values, in order to achieve performance boost, when specific event or whole telemetry is not in use.
"""
@type label() :: list()
@doc """
Evaluates to conditional call to `:telemetry.execute/3` or to nothing, depending on if specific event is enabled in config file.
If event is enabled, `:telemetry.execute/3` will be executed only if value returned by call to `func` will be truthly.
"""
defmacro conditional_execute(func, event_name, measurements, metadata, label) do
if emit_event?(event_name) do
quote do
if unquote(func).() do
metadata = Map.put(unquote(metadata), :membrane_telemetrymetrics_label, unquote(label))
:telemetry.execute(
unquote(event_name),
unquote(measurements),
metadata
)
end
end
else
quote do
fn ->
_unused = unquote(func)
_unused = unquote(event_name)
_unused = unquote(measurements)
_unused = unquote(metadata)
_unused = unquote(label)
end
end
end
end
@doc """
Evaluates to call to `:telemetry.execute/3` or to nothing, depending on if specific event is enabled in config file.
"""
defmacro execute(event_name, measurments, metadata, label) do
if emit_event?(event_name) do
quote do
metadata = Map.put(unquote(metadata), :membrane_telemetrymetrics_label, unquote(label))
:telemetry.execute(
unquote(event_name),
unquote(measurments),
metadata
)
end
else
quote do
fn ->
_unused = unquote(event_name)
_unused = unquote(measurments)
_unused = unquote(metadata)
_unused = unquote(label)
end
end
end
end
@doc """
Evalueates to call to `Membrane.TelemetryMetrics.Monitor.start/3` or to nothing, depending on if specific event is enabled in config file.
Should be called in every process, that will execute event linked with metric aggregated by some instance of `Membrane.TelemetryMetrics.Reporter`.
"""
defmacro register(event_name, label) do
if emit_event?(event_name) do
quote do
Membrane.TelemetryMetrics.Monitor.start(unquote(event_name), unquote(label))
end
else
quote do
fn ->
_unused = unquote(event_name)
_unused = unquote(label)
end
end
end
end
enabled = Application.compile_env(:membrane_telemetry_metrics, :enabled, false)
events = Application.compile_env(:membrane_telemetry_metrics, :events, :all)
cond do
not enabled -> defp emit_event?(_event), do: false
events == :all -> defp emit_event?(_event), do: true
is_list(events) -> defp emit_event?(event), do: event in events
true -> defp emit_event?(_event), do: false
end
end