Current section
Files
Jump to
Current section
Files
src/otter_filter.erl
-module(otter_filter).
-export([span/1, pre_span/1]).
-include_lib("otter_lib/include/otter.hrl").
%%----------------------------------------------------------------------
%% @doc Invoke the span filter on active span
%% @end
%%----------------------------------------------------------------------
-spec span(Span :: span()) -> span().
span(#span{timestamp = 0} = Span) ->
Span;
span(Span) ->
run(span, Span).
%%----------------------------------------------------------------------
%% @doc Invoke the span pre filter. If the filter result is to discard
%% the span in this phase (when the start_with_tags/1 API function is
%% called), then the timestamp or the span is set to 0, indicating that
%% the span is not active.
%% @end
%%----------------------------------------------------------------------
-spec pre_span(Span :: span()) -> span().
pre_span(Span) ->
run(prefilter, Span).
%%----------------------------------------------------------------------
%% Internal functions
%%----------------------------------------------------------------------
run(Type, Span) ->
Config = case Type of
prefilter -> prefilter_rules;
_ -> filter_rules
end,
case otter_config:read(Config, []) of
[{_,_}|_] = Rules ->
run_rules(Type, Span, Rules);
{Module, Function, ExtraArgs} ->
{NewSpan, Actions} = Module:Function(Span, ExtraArgs),
do_actions(Type, NewSpan, make_tags(NewSpan), Actions, Span);
[] ->
Span
end.
run_rules(Type, Span, Rules) ->
BreakOrContinue = case Type of prefilter -> break; _ -> continue end,
Tags = make_tags(Span),
Actions = otter_lib_filter:run(Tags, Rules, BreakOrContinue),
do_actions(Type, Span, Tags, Actions, Span).
do_actions(Type, Span, Tags, [{snapshot_count, Prefix, TagNames} | Rest], Return) ->
SnapCountKey = Prefix ++ [
case lists:keyfind(Key, 1, Tags) of
{Key, Value} -> Value;
_ -> undefined
end ||
Key <- TagNames
],
otter_lib_snapshot_count:snapshot(SnapCountKey, Span),
do_actions(Type, Span, Tags, Rest, Return);
do_actions(prefilter, Span, Tags, [allow | Rest], _Return) ->
do_actions(prefilter, Span, Tags, Rest, Span);
do_actions(prefilter, Span, Tags, [discard | Rest], _Return) ->
do_actions(prefilter, Span, Tags, Rest, deactivate_span(Span));
do_actions(span, Span, Tags, [send_to_zipkin | Rest], Return) ->
otter_conn_zipkin:store_span(Span),
do_actions(span, Span, Tags, Rest, Return);
do_actions(Type, Span, Tags, [UnknownAction| Rest], Return) ->
otter_lib_snapshot_count:snapshot(unknown_filter_action, {UnknownAction, Span}),
do_actions(Type, Span, Tags, Rest, Return);
do_actions(_Type, _Span, _Tags, [], Return) ->
Return.
make_tags(#span{tags = Tags, name = Name, duration = Duration}) ->
[
{otter_span_name, Name},
{otter_span_duration, Duration}|
Tags
].
%% In case of prefiltering return a span with timestamp set to 0
deactivate_span(Span) ->
Span#span{timestamp = 0}.