Current section

Files

Jump to
peep lib peep codegen.ex
Raw

lib/peep/codegen.ex

defmodule Peep.Codegen do
@moduledoc false
alias Peep.Options
alias Peep.Persistent
def module(peep_name) do
:"Peep.Codegen.#{peep_name}"
end
def create(%Options{} = peep_options) do
%Options{name: name, global_tags: global_tags} = peep_options
module_name = module(name)
handle_event_ast = build_handle_event_ast(name)
other_funs_ast = other_funs_ast()
module_ast =
quote do
defmodule unquote(module_name) do
require Persistent
@compile {:inline, global_tags: 0}
def global_tags(), do: unquote(Macro.escape(global_tags))
def name(), do: unquote(name)
unquote(handle_event_ast)
unquote(other_funs_ast)
end
end
[{_module, _bin}] = Code.compile_quoted(module_ast)
:ok
end
def purge(peep_name) do
:code.purge(module(peep_name))
end
defp build_handle_event_ast(peep_name) do
quote do
def handle_event(event, measurements, metadata, _) do
global_tags = global_tags()
%Persistent{
events_to_metrics: %{^event => metrics},
storage: {storage_mod, storage}
} = Persistent.fast_fetch(unquote(peep_name))
:lists.foreach(
fn {metric, id} ->
%{
measurement: measurement,
tag_values: tag_values,
tags: tags,
keep: keep
} = metric
if keep?(keep, metadata, measurement) do
# credo:disable-for-next-line Credo.Check.Refactor.Nesting
case fetch_measurement(measurement, measurements, metadata) do
value when is_number(value) ->
tag_values = tag_values.(metadata)
tags = Map.merge(global_tags, Map.take(tag_values, tags))
storage_mod.insert_metric(storage, id, metric, value, tags)
_ ->
nil
end
end
end,
metrics
)
end
end
end
# credo:disable-for-next-line Credo.Check.Refactor.CyclomaticComplexity
defp other_funs_ast() do
quote do
defp keep?(keep, metadata, measurement) when is_function(keep, 2),
do: keep.(metadata, measurement)
defp keep?(keep, metadata, _measurement) when is_function(keep, 1), do: keep.(metadata)
defp keep?(_keep, _metadata, _measurement), do: true
defp fetch_measurement(%Telemetry.Metrics.Counter{}, _measurements, _metadata) do
1
end
defp fetch_measurement(measurement, measurements, metadata) do
case measurement do
nil ->
nil
fun when is_function(fun, 1) ->
fun.(measurements)
fun when is_function(fun, 2) ->
fun.(measurements, metadata)
key ->
case measurements do
%{^key => nil} -> 1
%{^key => false} -> 1
%{^key => value} -> value
_ -> 1
end
end
end
end
end
end