Current section
Files
Jump to
Current section
Files
src/telemetry_registry.erl
-module(telemetry_registry).
%% API
-export([discover_all/0,
discover_all/1,
list_events/0,
spannable_events/0]).
-define(KEY, ?MODULE).
-type application() :: atom().
-type event_name() :: [atom(), ...].
-type event_description() :: binary().
-type event_measurements_definition() :: binary().
-type event_metadata_definition() :: binary().
list_events() ->
persistent_term:get(?KEY, []).
spannable_events() ->
AllEvents = list_events(),
ReversedEvents = reverse_events(AllEvents),
Filtered = filter_events(ReversedEvents),
{_, Spans} = event_spans(Filtered),
Spans.
reverse_events(Events) ->
[lists:reverse(Event) || {Event, _} <- Events].
filter_events(Events) ->
lists:filter(fun([Suffix | _]) -> lists:member(Suffix, [start, stop, exception]) end, Events).
event_spans(Events) ->
lists:foldl(fun([start | Event], {AllEvents, Spans}) ->
case lists:member([stop | Event], AllEvents) of
true ->
SpanPrefix = lists:reverse(Event),
case lists:member([exception | Event], AllEvents) of
true ->
UpdatedSpans = maps:put(SpanPrefix, [start, stop, exception], Spans),
{AllEvents, UpdatedSpans};
false ->
{Events, maps:put(SpanPrefix, [start, stop], Spans)}
end;
false ->
{AllEvents, Spans}
end;
(_, Acc) ->
Acc
end, {Events, #{}}, Events).
-spec discover_all() -> ok.
discover_all() ->
discover_all([App || {App, _, _} <- application:loaded_applications()]).
-spec discover_all(application() | [application()]) -> ok.
discover_all(Applications) ->
Events = maps:keys(maps:from_list([{Event, []} || Event <- gather_all_events(Applications)])),
persistent_term:put(?KEY, Events).
gather_all_events(Applications) when is_list(Applications) ->
lists:flatmap(fun gather_all_events/1, Applications);
gather_all_events(Application) ->
Applications = child_applications(Application),
lists:flatmap(fun gather_application_events/1, [Application | Applications]).
child_applications(Application) ->
{ok, ChildApplications} = application:get_key(Application, applications),
{ok, ChildIncludedApplications} = application:get_key(Application, included_applications),
ChildApplications ++ ChildIncludedApplications.
gather_application_events(Application) ->
case application:get_key(Application, modules) of
{ok, Modules} -> lists:flatmap(fun events_for_module/1, Modules);
_ -> []
end.
-spec events_for_module(atom()) -> [telemetry:event_name()].
events_for_module(Module) ->
Info = Module:module_info(),
Attributes = proplists:get_value(attributes, Info),
Events = proplists:get_all_values(telemetry_event, Attributes),
[{Event, Module} || Event <- Events].