Skip to content

Commit

Permalink
split the API into a separate application (#21)
Browse files Browse the repository at this point in the history
* split the API into a separate application

This patch moves the API modules to another application, opentelemetry_api.

This repo is now the SDK implementation and when booted will start
the ot_tracer_server which is used to serialize configuration of
the tracer and set the default_tracer through the API.

* update ctx implementations for latest api

* add http propagators for trace context

* implement add_event span function

* fix macro name for export interval

* set default tracer on boot of sdk

* small formatting changes and add sys.config for manual testing

* lock to latest erlang-api

* add test of baggage propagation

* update implementations of context to support contextmanager state

* upgrade opentelemetry api dependency
  • Loading branch information
tsloughter authored Nov 20, 2019
1 parent 7b0ae7f commit 571d4af
Show file tree
Hide file tree
Showing 37 changed files with 1,187 additions and 1,068 deletions.
36 changes: 33 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,41 @@ Requires OTP 21.3 of above.

## Design

The [OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification) defines a language library as having 2 components, the API and the SDK. The API must not only define the interfaces of any implementation in that language but also be able to function as a minimal implementation. The SDK is the default implementation of the API that must be optional.
The [OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification) defines a language library as having 2 components, the API and the SDK. The API must not only define the interfaces of any implementation in that language but also be able to function as a noop implementation of the tracer. The SDK is the default implementation of the API that must be optional.

In this library the API is defined as the behaviours `ot_tracer`, `ot_span` and `ot_ctx`. It is not a separate Erlang application from the SDK, nor are there subdirectories following the [layout described in the spec](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/library-layout.md). Not using subdirectories as the spec's layout describes is simply because the OTP application structure has all source files directly under `src/`. There is no separation of API and SDK into distinct libraries because a) there is not yet support in rebar3 for using git repos with multiple applications as dependencies b) since Erlang has a flat namespace the same module naming strategy would be used whether they are separate applications or not. Additionally, a release can be configured to drop any part of an application the user chooses. So in the unlikely event there are users who wish to not include the SDK's default implementation it is possible.
If you are instrumenting a project your application should only depend on the [OpenTelemetry API](https://github.com/open-telemetry/opentelemetry-erlang-api/) application.

### Default Tracer
This repository is the Erlang's SDK implementation and should be included in the final release and configured to setup the sampler, span processors and span exporters.

## Using

In an Erlang project add `opentelemetry` as the first element of the release's applications:

``` erlang
{relx, [{release, {<name>, <version>},
[{opentelemetry, temporary},
<your applications>]},
...]}.
```

In the above example `opentelemetry` is set to `temporary` so that if the `opentelemetry` application crashes, or is shutdown, it does not terminate the other applications in the project. This is optional, the `opentelemetry` application purposely sticks to `permanent` for the processes started by the root supervisor to leave it up to the end user whether they want the crash or shutdown or `opentelemetry` to be ignored or cause the shutdown of the rest of the applications in the release.

Doing the same for an Elixir project would be:

``` elixir
def project do
[
...
releases: [
<name>: [
applications: [opentelemetry: :temporary]
],

...
]
]
end
```

## Benchmarks

Expand Down
6 changes: 6 additions & 0 deletions config/sys.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
{opentelemetry,
[{processors, [{ot_batch_processor,
[{exporter, {ot_exporter_stdout, []}}]}]
}]}
].
151 changes: 0 additions & 151 deletions include/opentelemetry.hrl

This file was deleted.

7 changes: 5 additions & 2 deletions rebar.config
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
{erl_opts, [debug_info]}.
{deps, [{wts, "~> 0.3"}]}.
{deps, [{wts, "~> 0.3"},
{opentelemetry_api, {git, "https://github.com/tsloughter/opentelemetry-erlang-api",
{branch, "otep-66"}}}]}.

{shell, [{apps, [opentelemetry]}]}.
{shell, [{apps, [opentelemetry]},
{config, "config/sys.config"}]}.

{project_plugins, [covertool]}.

Expand Down
6 changes: 5 additions & 1 deletion rebar.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{"1.1.0",
[{<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.9.0">>},1},
[{<<"opentelemetry_api">>,
{git,"https://github.com/tsloughter/opentelemetry-erlang-api",
{ref,"f0d91bb3b1964484426051a483da8ddefd40a1aa"}},
0},
{<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.9.0">>},1},
{<<"wts">>,{pkg,<<"wts">>,<<"0.3.0">>},0}]}.
[
{pkg_hash,[
Expand Down
13 changes: 7 additions & 6 deletions src/opentelemetry.app.src
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
{applications,
[kernel,
stdlib,
wts
wts,
opentelemetry_api
]},
{env, [{tracer, {ot_tracer_default, #{span => {ot_span_ets, []},
ctx => {ot_ctx_pdict, []}}}},
{sampler, {always_on, #{}}},
{exporter, [{exporters, []},
{scheduled_delay_ms, 30000}]}]},
{env, [{sampler, {always_on, #{}}},
{processors, [%% #{id => my_processor,
%% module => ot_batch_processor,
%% config => #{}}
]}]},
{modules, []},

{licenses, ["Apache 2.0"]},
Expand Down
115 changes: 0 additions & 115 deletions src/opentelemetry.erl

This file was deleted.

25 changes: 13 additions & 12 deletions src/opentelemetry_app.erl
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,19 @@

start(_StartType, _StartArgs) ->
Opts = application:get_all_env(opentelemetry),

{sampler, {Sampler, SamplerOpts}} = lists:keyfind(sampler, 1, Opts),
SamplerFun = ot_sampler:setup(Sampler, SamplerOpts),

%% The default sampler implementation must be passed to the tracer chosen.
%% Since the tracer is started after the rest of the supervision tree has started
%% and we only get its children, we must instantiate the sampler before anything else.
%% The sampler turns out to be instantiated before any supervision tree is started.
{tracer, {Tracer, TracerOpts}} = lists:keyfind(tracer, 1, Opts),
TracerChildren = ot_tracer:setup(Tracer, TracerOpts, SamplerFun),

opentelemetry_sup:start_link(TracerChildren, Opts).
opentelemetry:set_default_context_manager({ot_ctx_pdict, []}),

{BaggageHttpExtractor, BaggageHttpInjector} = ot_baggage:get_http_propagators(),
{CorrelationsHttpExtractor, CorrelationsHttpInjector} = ot_correlations:get_http_propagators(),
{B3HttpExtractor, B3HttpInjector} = ot_tracer_default:b3_propagators(),
opentelemetry:set_http_extractor([BaggageHttpExtractor,
CorrelationsHttpExtractor,
B3HttpExtractor]),
opentelemetry:set_http_injector([BaggageHttpInjector,
CorrelationsHttpInjector,
B3HttpInjector]),

opentelemetry_sup:start_link(Opts).

stop(_State) ->
ok.
Expand Down
Loading

0 comments on commit 571d4af

Please sign in to comment.