Skip to content

Commit 730124e

Browse files
authored
Merge pull request #287 from tsloughter/single-tracer-term
separate application tracer registration from user named tracers
2 parents 51ce24e + 64cbc0a commit 730124e

File tree

15 files changed

+120
-162
lines changed

15 files changed

+120
-162
lines changed

apps/opentelemetry/include/otel_span.hrl

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@
1616
%% @end
1717
%%%-------------------------------------------------------------------------
1818

19-
%% Holds information about the instrumentation library specified when
20-
%% getting a Tracer from the TracerProvider.
21-
-record(instrumentation_library, {name :: unicode:unicode_binary() | undefined,
22-
version :: unicode:unicode_binary() | undefined}).
23-
2419
%% The name, version and language of this OpenTelemetry library
2520
-record(telemetry_library, {name :: unicode:unicode_binary() | undefined,
2621
language :: unicode:unicode_binary() | undefined,
@@ -70,5 +65,5 @@
7065
%% trace flags lowest bit is 1 but simply not propagated.
7166
is_recording :: boolean() | undefined,
7267

73-
instrumentation_library :: #instrumentation_library{} | undefined
68+
instrumentation_library :: opentelemetry:instrumentation_library() | undefined
7469
}).

apps/opentelemetry/src/opentelemetry_app.erl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,9 @@ register_loaded_application_tracers(Opts) ->
6262
register_loaded_applications_(RegisterLoadedApplications).
6363

6464
register_loaded_applications_(true) ->
65+
%% TODO: filter out OTP apps that will not have any instrumentation
6566
LoadedApplications = application:loaded_applications(),
66-
[opentelemetry:register_application_tracer(Name) || {Name, _, _} <- LoadedApplications],
67+
opentelemetry:register_application_tracers(LoadedApplications),
6768
ok;
6869
register_loaded_applications_(_) ->
6970
ok.

apps/opentelemetry/src/otel_tracer_server.erl

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
-behaviour(otel_tracer_provider).
2121

2222
-export([init/1,
23-
register_tracer/4,
2423
register_tracer/3,
24+
get_tracer/2,
2525
resource/1,
2626
code_change/1]).
2727

@@ -86,18 +86,11 @@ init(Opts) ->
8686
resource(#state{resource=Resource}) ->
8787
Resource.
8888

89-
register_tracer(Name, Vsn, Modules, #state{shared_tracer=Tracer,
90-
deny_list=DenyList}) ->
91-
%% TODO: support semver constraints in denylist
92-
case proplists:is_defined(Name, DenyList) of
93-
true ->
94-
opentelemetry:set_tracer(Name, {otel_tracer_noop, []});
95-
false ->
96-
InstrumentationLibrary = otel_utils:instrumentation_library(Name, Vsn),
97-
TracerTuple = {Tracer#tracer.module,
98-
Tracer#tracer{instrumentation_library=InstrumentationLibrary}},
99-
[opentelemetry:set_tracer(M, TracerTuple) || M <- Modules]
100-
end.
89+
get_tracer(InstrumentationLibrary, #state{shared_tracer=Tracer,
90+
deny_list=_DenyList}) ->
91+
92+
{Tracer#tracer.module,
93+
Tracer#tracer{instrumentation_library=InstrumentationLibrary}}.
10194

10295
register_tracer(Name, Vsn, #state{shared_tracer=Tracer,
10396
deny_list=DenyList}) ->
@@ -106,7 +99,7 @@ register_tracer(Name, Vsn, #state{shared_tracer=Tracer,
10699
true ->
107100
opentelemetry:set_tracer(Name, {otel_tracer_noop, []});
108101
false ->
109-
InstrumentationLibrary = otel_utils:instrumentation_library(Name, Vsn),
102+
InstrumentationLibrary = opentelemetry:instrumentation_library(Name, Vsn),
110103
TracerTuple = {Tracer#tracer.module,
111104
Tracer#tracer{instrumentation_library=InstrumentationLibrary}},
112105
opentelemetry:set_tracer(Name, TracerTuple)

apps/opentelemetry/src/otel_utils.erl

Lines changed: 0 additions & 29 deletions
This file was deleted.

apps/opentelemetry/test/opentelemetry_SUITE.erl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,25 @@ end_per_testcase(_, _Config) ->
6565
ok.
6666

6767
disable_auto_registration(_Config) ->
68-
{_, #tracer{instrumentation_library=Library}} = opentelemetry:get_tracer(kernel),
68+
{_, #tracer{instrumentation_library=Library}} = opentelemetry:get_application_tracer(kernel),
6969
?assertEqual(undefined, Library),
7070
ok.
7171

7272
registered_tracers(_Config) ->
73-
{_, #tracer{instrumentation_library=Library}} = opentelemetry:get_tracer(kernel),
73+
{_, #tracer{instrumentation_library=Library}} = opentelemetry:get_application_tracer(kernel),
7474
?assertEqual(<<"kernel">>, Library#instrumentation_library.name),
7575

7676
%% register a new tracer with the same name but different version
7777
opentelemetry:register_tracer(kernel, <<"fake-version">>),
7878
{_, #tracer{instrumentation_library=NewLibrary}} = opentelemetry:get_tracer(kernel),
7979
?assertEqual(<<"kernel">>, NewLibrary#instrumentation_library.name),
8080
?assertEqual(<<"fake-version">>, NewLibrary#instrumentation_library.version),
81+
82+
%% tracer registered on startup for a particular application is the same
83+
{_, #tracer{instrumentation_library=Library1}} = opentelemetry:get_application_tracer(kernel),
84+
?assertEqual(<<"kernel">>, Library1#instrumentation_library.name),
85+
?assertNotEqual(<<"fake-version">>, Library1#instrumentation_library.version),
86+
8187
ok.
8288

8389
propagator_configuration(_Config) ->

apps/opentelemetry_api/README.md

Lines changed: 4 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -30,64 +30,12 @@ def deps do
3030
end
3131
```
3232

33-
### Registering and Using Tracers Directly
34-
35-
If it is a runnable application then this registration should happen in `start/2`, example below is adding `Tracer` registration to the Postgres library [pgo](https://github.com/erleans/pgo):
36-
37-
``` erlang
38-
start(_StartType, _StartArgs) ->
39-
_ = opentelemetry:register_application_tracer(pgo),
40-
...
41-
```
42-
43-
Or for an Elixir Application named `MyApp`:
44-
45-
``` elixir
46-
defmodule MyApp do
47-
use Application
48-
49-
def start(_type, _args) do
50-
_ = OpenTelemetry.register_application_tracer(:my_app)
51-
...
52-
end
53-
end
54-
```
55-
56-
Then when the spans are started and finished in the application's code the `Tracer` is fetched with `get_tracer/1` and passed to `with_span/3` or `start_span/3`:
57-
58-
``` erlang
59-
Tracer = opentelemetry:get_tracer(pgo),
60-
otel_tracer:with_span(Tracer, <<"pgo:query/3">>, fun() -> ... end).
61-
```
62-
63-
A `Tracer` variable can be passed through your Application's calls so `get_tracer` only has to be called once, it is safe to store it in the state of a `gen_server` and to pass across process boundaries.
64-
65-
If the application does not have a `start/2` there may be another function that is always called before the library would create any spans. For example, the [Elli](https://github.com/elli-lib/elli) middleware for OpenTelemetry instrumentation registers the `Tracer` during Elli startup:
66-
67-
``` erlang
68-
handle_event(elli_startup, _Args, _Config) ->
69-
_ = opentelemetry:register_application_tracer(opentelemetry_elli),
70-
ok;
71-
```
72-
73-
When there is no startup of any kind to hook into in the library itself it should export a function `register_application_tracer/0` to be used by any application that depends on it to do the registration:
74-
75-
``` erlang
76-
-module(mylib).
77-
78-
-export([register_tracer/0]).
79-
80-
register_tracer() ->
81-
_ = opentelemetry:register_application_tracer(mylib),
82-
ok.
83-
```
84-
85-
Not registering does not cause any issues or crashes, OpenTelemetry simply will fallback to the default `Tracer` if `get_tracer/1` is called with a name that is not registered.
86-
87-
8833
### Helper Macros for Application Tracers
8934

90-
When `register_application_tracer/1` is used to register a Tracer there are both Erlang and Elixir macros that make use of the current module's name to lookup the Tracer for you and can be used for Trace and Span operations:
35+
There are both Erlang and Elixir macros that make use of the current module's
36+
name to lookup a Named Tracer -- a Named Tracer is created for each Application
37+
loaded in the system at start time -- for you and can be used for Trace and Span
38+
operations:
9139

9240
``` erlang
9341
-include_lib("opentelemetry_api/include/otel_tracer.hrl").

apps/opentelemetry_api/include/opentelemetry.hrl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@
3434
-define(OTEL_STATUS_OK, ok).
3535
-define(OTEL_STATUS_ERROR, error).
3636

37+
%% Holds information about the instrumentation library specified when
38+
%% getting a Tracer from the TracerProvider.
39+
-record(instrumentation_library, {name :: unicode:unicode_binary() | undefined,
40+
version :: unicode:unicode_binary() | undefined}).
41+
3742
-record(span_ctx, {
3843
%% 128 bit int trace id
3944
trace_id :: opentelemetry:trace_id(),

apps/opentelemetry_api/include/otel_tracer.hrl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
%% macros for tracing
22
%% register a tracer for an application with opentelemetry:register_application_tracer(AppName)
33

4-
-define(current_tracer, opentelemetry:get_tracer(?MODULE)).
4+
-define(current_tracer, opentelemetry:get_application_tracer(?MODULE)).
55
-define(current_span_ctx, otel_tracer:current_span_ctx()).
66

77
-define(start_span(SpanName),

apps/opentelemetry_api/lib/open_telemetry.ex

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ defmodule OpenTelemetry do
1313
require OpenTelemetry.Tracer
1414
require OpenTelemetry.Span
1515
16-
OpenTelemetry.register_application_tracer(:this_otp_app)
17-
1816
Tracer.start_span("some-span")
1917
...
2018
event = "ecto.query"
@@ -118,17 +116,6 @@ defmodule OpenTelemetry do
118116
"""
119117
@type status() :: :opentelemetry.status()
120118

121-
@doc """
122-
Registering a [Named Tracer](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/api-tracing.md#obtaining-a-tracer) with the name of an OTP Application enables each module in
123-
the Application to be mapped to the Named Tracer, named for the Application and using the
124-
version of the currently loaded Application by that name.
125-
126-
Macros in `OpenTelemetry.Tracer` use the name of the module they are being used in in order
127-
to lookup the Named Tracer registered for that module and using it for trace operations.
128-
"""
129-
@spec register_application_tracer(atom()) :: boolean()
130-
defdelegate register_application_tracer(otp_app), to: :opentelemetry
131-
132119
defdelegate get_tracer(name), to: :opentelemetry
133120
defdelegate register_tracer(name, vsn), to: :opentelemetry
134121
defdelegate set_default_tracer(t), to: :opentelemetry

apps/opentelemetry_api/lib/open_telemetry/tracer.ex

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ defmodule OpenTelemetry.Tracer do
66
a different Span to be the current Span by passing the Span's context, end a Span or run a code
77
block within the context of a newly started span that is ended when the code block completes.
88
9-
The macros use the Tracer registered to the Application the module using the macro is included in,
10-
assuming `OpenTelemetry.register_application_tracer/1` has been called for the Application. If
11-
not then the default Tracer is used.
9+
The macros `start_span` and `with_span` use the Tracer registered to the Application the module
10+
is included in. These Tracers are created at boot time for each loaded Application.
1211
1312
require OpenTelemetry.Tracer
1413

0 commit comments

Comments
 (0)