Skip to content
This repository has been archived by the owner on Oct 26, 2020. It is now read-only.

Commit

Permalink
Merge pull request #4 from tsloughter/otep-66
Browse files Browse the repository at this point in the history
separate context propagation otep
  • Loading branch information
tsloughter authored Nov 20, 2019
2 parents 8d4ef06 + f0d91bb commit cf03475
Show file tree
Hide file tree
Showing 10 changed files with 490 additions and 43 deletions.
77 changes: 76 additions & 1 deletion src/opentelemetry.erl
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,14 @@
-module(opentelemetry).

-export([set_default_tracer/1,
set_default_context_manager/1,
get_context_manager/0,
get_tracer/0,
get_tracer/1,
set_http_extractor/1,
get_http_extractor/0,
set_http_injector/1,
get_http_injector/0,
timestamp/0,
links/1,
link/4,
Expand All @@ -43,6 +49,7 @@
generate_span_id/0]).

-include("opentelemetry.hrl").
-include_lib("kernel/include/logger.hrl").

-export_type([tracer/0,
trace_id/0,
Expand Down Expand Up @@ -103,15 +110,50 @@

-type http_headers() :: [{unicode:unicode_binary(), unicode:unicode_binary()}].

-spec set_default_tracer(tracer()) -> boolean().
set_default_tracer(Tracer) ->
persistent_term:put({?MODULE, default_tracer}, Tracer).
verify_and_set_term(Tracer, default_tracer, ot_tracer).

-spec set_default_context_manager(ot_ctx:context_manager()) -> boolean().
set_default_context_manager(ContextManager) ->
verify_and_set_term(ContextManager, context_manager, ot_ctx).

-spec get_context_manager() -> ot_ctx:context_manager().
get_context_manager() ->
persistent_term:get({?MODULE, context_manager}, {ot_ctx_noop, []}).

-spec get_tracer() -> tracer().
get_tracer() ->
persistent_term:get({?MODULE, default_tracer}, {ot_tracer_noop, []}).

-spec get_tracer(unicode:unicode_binary()) -> tracer().
get_tracer(_Name) ->
persistent_term:get({?MODULE, default_tracer}, {ot_tracer_noop, []}).

set_http_extractor(List) ->
Fun = fun(Headers) ->
lists:foldl(fun(Extract, ok) ->
Extract(Headers),
ok
end, ok, List),
ok
end,
persistent_term:put({?MODULE, http_extractor}, Fun).

set_http_injector(List) ->
Fun = fun(Headers) ->
lists:foldl(fun(Inject, HeadersAcc) ->
Inject(HeadersAcc)
end, Headers, List)
end,
persistent_term:put({?MODULE, http_injector}, Fun).

get_http_extractor() ->
persistent_term:get({?MODULE, http_extractor}, fun(Headers) -> Headers end).

get_http_injector() ->
persistent_term:get({?MODULE, http_injector}, fun(_Headers) -> ok end).

-spec timestamp() -> integer().
timestamp() ->
erlang:system_time(nanosecond).
Expand Down Expand Up @@ -212,3 +254,36 @@ generate_span_id() ->

uniform(X) ->
rand:uniform(X).

%% internal functions

-spec verify_and_set_term(module() | {module(), term()}, term(), atom()) -> boolean().
verify_and_set_term(Module, TermKey, Behaviour) ->
case verify_behaviour(Module, Behaviour) of
true ->
persistent_term:put({?MODULE, TermKey}, Module),
true;
false ->
?LOG_WARNING("Module ~p does not implement behaviour ~p. "
"A noop ~p will be used until a module, implementing "
"the behaviour is configured.",
[Module, Behaviour, Behaviour]),
false
end.

-spec verify_behaviour(module() | {module(), term()}, atom()) -> boolean().
verify_behaviour({Module, _}, Behaviour) ->
verify_behaviour(Module, Behaviour);
verify_behaviour(Module, Behaviour) ->
try Module:module_info(attributes) of
Attributes ->
case lists:keyfind(behaviour, 1, Attributes) of
{behaviour, Behaviours} ->
lists:member(Behaviour, Behaviours);
_ ->
false
end
catch
error:undef ->
false
end.
82 changes: 82 additions & 0 deletions src/ot_baggage.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
%%%------------------------------------------------------------------------
%% Copyright 2019, OpenTelemetry Authors
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
%% @doc
%% @end
%%%-------------------------------------------------------------------------
-module(ot_baggage).

-export([ctx_key/0,
set/2,
get/1,
remove/1,
clear/0,
get_http_propagators/0]).

-type key() :: string().
-type value() :: string().

-export_type([key/0,
value/0]).

-define(BAGGAGE_KEY, '$__ot_baggage_ctx_key').
-define(BAGGAGE_HEADER, <<"Baggage-Context">>).
ctx_key() ->
?BAGGAGE_KEY.

-spec set(key(), value()) -> ok.
set(Key, Value) ->
ot_ctx:set_value(?BAGGAGE_KEY, Key, Value).

-spec get(key()) -> value().
get(Key)->
ot_ctx:get_value(?BAGGAGE_KEY, Key).

-spec remove(key()) -> ok.
remove(Key) ->
ot_ctx:remove(?BAGGAGE_KEY, Key).

-spec clear() -> ok.
clear() ->
ot_ctx:clear(?BAGGAGE_KEY).

-spec get_http_propagators() -> {ot_propagation:http_extractor(), ot_propagation:http_injector()}.
get_http_propagators() ->
ToText = fun(_Headers, undefined) ->
[];
(_Headers, Baggage) ->
case maps:fold(fun(Key, Value, Acc) ->
[$,, [Key, "=", Value] | Acc]
end, [], Baggage) of
[$, | List] ->
[{?BAGGAGE_HEADER, List}];
_ ->
[]
end
end,
FromText = fun(Headers, CurrentBaggage) ->
case lists:keyfind(?BAGGAGE_HEADER, 1, Headers) of
{_, String} ->
Pairs = string:lexemes(String, [","]),
lists:foldl(fun(Pair, Acc) ->
[Key, Value] = string:split(Pair, "="),
Acc#{Key => {Value, unlimited_propagation}}
end, CurrentBaggage, Pairs);
_ ->
CurrentBaggage
end
end,
Inject = ot_ctx:http_injector(?BAGGAGE_KEY, ToText),
Extract = ot_ctx:http_extractor(?BAGGAGE_KEY, FromText),
{Extract, Inject}.
69 changes: 69 additions & 0 deletions src/ot_correlations.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
%%%------------------------------------------------------------------------
%% Copyright 2019, OpenTelemetry Authors
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
%% @doc
%% @end
%%%-------------------------------------------------------------------------
-module(ot_correlations).

-export([ctx_key/0,
set/3,
get_http_propagators/0]).

-type key() :: string().
-type value() :: string().
-type hop_limit() :: no_propagation | unlimited_propagation.

-export_type([key/0,
value/0]).

-define(CORRELATIONS_KEY, '$__ot_correlations_ctx_key').
-define(CORRELATIONS_HEADER, <<"Correlation-Context">>).

ctx_key() ->
?CORRELATIONS_KEY.

-spec set(key(), value(), hop_limit()) -> ok.
set(Key, Value, HopLimit) ->
ot_ctx:set_value(?CORRELATIONS_KEY, Key, {Value, HopLimit}).

-spec get_http_propagators() -> {ot_propagation:http_extractor(), ot_propagation:http_injector()}.
get_http_propagators() ->
ToText = fun(_Headers, Correlations) ->
case maps:fold(fun(Key, {Value, unlimited_propagation}, Acc) ->
[$,, [Key, "=", Value] | Acc];
(_Key, {_Value, no_propagation}, Acc) ->
Acc
end, [], Correlations) of
[$, | List] ->
[{?CORRELATIONS_HEADER, List}];
_ ->
[]
end
end,
FromText = fun(Headers, CurrentCorrelations) ->
case lists:keyfind(?CORRELATIONS_HEADER, 1, Headers) of
{_, String} ->
Pairs = string:lexemes(String, [","]),
lists:foldl(fun(Pair, Acc) ->
[Key, Value] = string:split(Pair, "="),
Acc#{Key => {Value, unlimited_propagation}}
end, CurrentCorrelations, Pairs);
_ ->
CurrentCorrelations
end
end,
Inject = ot_ctx:http_injector(?CORRELATIONS_KEY, ToText),
Extract = ot_ctx:http_extractor(?CORRELATIONS_KEY, FromText),
{Extract, Inject}.
Loading

0 comments on commit cf03475

Please sign in to comment.