OpenTelemetry Erlang/Elixir
OpenTelemetry distributed tracing framework for Erlang and Elixir.
These applications implement version 1.8.0 of the OpenTelemetry Specification, see the spec compliance matrix for a list of features supported.
Requirements
- Erlang/OTP 23+ (With best effort for OTP 22 support)
If using the Elixir API:
- Elixir 1.13+
Contacting Us
We hold weekly meetings. See details at community page.
We use GitHub Discussions for support or general questions. Feel free to drop us a line.
We are also present in the #otel-erlang-elixir channel in the CNCF slack. Please join us for more informal discussions.
You can also find us in the #opentelemetry channel on Elixir Slack.
Getting Started
You can find a getting started guide on opentelemetry.io.
To start capturing distributed traces from your application it first needs to be instrumented. The easiest way to do this is by using an instrumentation library, there are a number of officially supported instrumentation libraries for popular Erlang and Elixir libraries and frameworks.
Design
The 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.
When instrumenting a project your application should only depend on the
OpenTelemetry API application,
found in directory apps/opentelemetry_api
of this repo which is published as
the hex package opentelemetry_api.
The SDK implementation, found under apps/opentelemetry
and hex package
opentelemetry, should be included in an
OTP Release along with an exporter.
Example of Release configuration in rebar.config
:
{relx, [{release, {my_instrumented_release, "0.1.0"},
[opentelemetry_exporter,
{opentelemetry, temporary},
my_instrumented_app]},
...]}.
Example configuration for mix's Release task:
def project do
[
releases: [
my_instrumented_release: [
applications: [opentelemetry_exporter: :permanent, opentelemetry: :temporary]
],
...
]
]
end
Note that you also need to add opentelemetry_exporter
before your other opentelemetry
dependencies in mix.exs
so that it starts before opentelemetry
does.
In the above example opentelemetry_exporter
is first to ensure all of its
dependencies are booted before opentelemetry
attempts to start the
exporter. 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 -- opentelemetry_exporter
does not not need to be
temporary
because it does not have a startup and supervision tree. 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.
Git Dependencies
While it is recommended to use the Hex packages for the
API,
SDK and OTLP
exporter, there are times
depending on the git repo is necessary. Because the OpenTelemetry OTP
Applications are kept in a single repository, under the directory apps
, either
rebar3's git_subdir
(rebar 3.14 or above is required) or
mix's
sparse
feature must be used when using as Git dependencies in a project. The
blocks below shows how in rebar3 and mix the git repo for the API and/or SDK
Applications can be used.
{opentelemetry_api, {git_subdir, "http://github.com/open-telemetry/opentelemetry-erlang", {branch, "main"}, "apps/opentelemetry_api"}},
{opentelemetry, {git_subdir, "http://github.com/open-telemetry/opentelemetry-erlang", {branch, "main"},
"apps/opentelemetry"}},
{opentelemetry_exporter, {git_subdir, "http://github.com/open-telemetry/opentelemetry-erlang", {branch, "main"}, "apps/opentelemetry_exporter"}}
{:opentelemetry_api, github: "open-telemetry/opentelemetry-erlang", sparse:
"apps/opentelemetry_api", override: true},
{:opentelemetry, github: "open-telemetry/opentelemetry-erlang", sparse:
"apps/opentelemetry", override: true},
{:opentelemetry_exporter, github: "open-telemetry/opentelemetry-erlang", sparse: "apps/opentelemetry_exporter", override: true}
The override: true
is required because the SDK Application, opentelemetry
, has
the API in its deps
list of its rebar.config
as a hex dependency and this will
clash when mix
tries to resolve the dependencies and fail without the
override. override: true
is also used on the SDK because the
opentelemetry_exporter
application depends on it and the API as hex deps so if
it is included the override is necessary.
Benchmarks
Running benchmarks is done with benchee. Benchmark functions are in modules under samples/
. To run them open a rebar3 shell in the bench
profile:
$ rebar3 as bench shell
> otel_benchmarks:run().
If an Elixir script is wanted for the benchmarks they could be run like (after
running rebar3 as bench compile
):
$ ERL_AFLAGS="-pa ./_build/bench/extras/samples/" ERL_LIBS=_build/bench/lib/ mix run --no-mix-exs samples/run.exs
W3C Trace Context Interop Tests
Start the interop web server in a shell:
$ rebar3 as interop shell
> w3c_trace_context_interop:start().
Then, clone the W3C Trace Context repo and run the tests:
$ cd test
$ python3 test.py http://127.0.0.1:5000/test
Contributing
Approvers (@open-telemetry/erlang-approvers):
- Tristan Sloughter, Splunk
- Bryan Naegele, Simplebet
- Greg Mefford, STORD
- Fred Hebert, Honeycomb
- Łukasz Jan Niemier
- Iliia Khaprov, VMWare
Find more about the approver role in community repository.
Maintainers (@open-telemetry/erlang-maintainers):
Find more about the maintainer role in community repository.