Current section
Files
Jump to
Current section
Files
src/otel_tracer_provider.erl
%%%------------------------------------------------------------------------
%% 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(otel_tracer_provider).
-behaviour(gen_server).
-export([start_link/2,
resource/0,
register_application_tracer/1,
register_tracer/2]).
-export([init/1,
handle_call/3,
handle_cast/2,
code_change/3]).
-type cb_state() :: term().
-callback init(term()) -> {ok, cb_state()}.
-callback register_tracer(atom(), string(), cb_state()) -> boolean().
-callback resource(cb_state()) -> term() | undefined.
-record(state, {callback :: module(),
cb_state :: term()}).
start_link(ProviderModule, Opts) ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [ProviderModule, Opts], []).
-spec resource() -> term() | undefined.
resource() ->
try
gen_server:call(?MODULE, resource)
catch exit:{noproc, _} ->
%% ignore because no SDK has been included and started
undefined
end.
-spec register_tracer(atom(), string()) -> boolean().
register_tracer(Name, Vsn) ->
try
gen_server:call(?MODULE, {register_tracer, Name, Vsn})
catch exit:{noproc, _} ->
%% ignore register_tracer because no SDK has been included and started
false
end.
-spec register_application_tracer(atom()) -> boolean().
register_application_tracer(Name) ->
try
{ok, Vsn} = application:get_key(Name, vsn),
{ok, Modules} = application:get_key(Name, modules),
gen_server:call(?MODULE, {register_tracer, Name, Vsn, Modules})
catch exit:{noproc, _} ->
%% ignore register_tracer because no SDK has been included and started
false
end.
init([ProviderModule, Opts]) ->
case ProviderModule:init(Opts) of
{ok, CbState} ->
{ok, #state{callback=ProviderModule,
cb_state=CbState}};
Other ->
Other
end.
handle_call({register_tracer, Name, Vsn, Modules}, _From, State=#state{callback=Cb,
cb_state=CbState}) ->
_ = Cb:register_tracer(Name, Vsn, Modules, CbState),
{reply, true, State};
handle_call({register_tracer, Name, Vsn}, _From, State=#state{callback=Cb,
cb_state=CbState}) ->
_ = Cb:register_tracer(Name, Vsn, CbState),
{reply, true, State};
handle_call(resource, _From, State=#state{callback=Cb,
cb_state=CbState}) ->
Resource = Cb:resource(CbState),
{reply, Resource, State};
handle_call(_Msg, _From, State) ->
{noreply, State}.
handle_cast(_Msg, State) ->
{noreply, State}.
%% TODO: Use `Extra' as options to update the state like the sampler?
code_change(_OldVsn, State=#state{callback=Cb,
cb_state=CbState}, _Extra) ->
NewCbState = Cb:code_change(CbState),
{ok, State#state{cb_state=NewCbState}}.
%%