Opentelemetry instrumentation for ExUnit.Formatter
.
Telemetry handler that creates Opentelemetry spans from ExUnit.Formatter
events.
Add :opentelemetry_ex_unit_formatter
to your application dependencies list:
# mix.exs
defp deps do
[
{:opentelemetry_ex_unit_formatter, "~> 0.1.0"}
]
end
Add OpentelemetryExUnitFormatter
to the ExUnit
formatters list:
# test/test_helper.exs
ExUnit.configure(formatters: [ExUnit.CLIFormatter, OpentelemetryExUnitFormatter])
ExUnit.start()
By default OpentelemetryExUnitFormatter has Opentelemetry tracer set to :none
and telemetry spans
are not exported.
If you want to export telemetry spans, please add :opentelemetry_exporter
to your application
dependencies list:
# mix.exs
defp deps do
[
{
:opentelemetry_ex_unit_formatter,
"~> 0.1.0",
github: "Recruitee/opentelemetry_ex_unit_formatter", only: :test, runtime: false
},
{:opentelemetry, "~> 1.2"},
{:opentelemetry_exporter, "~> 1.4", only: :test, runtime: false}
]
end
Additionally you need to configure Opentelemetry tracer as described in the :tracer_provider_config section below.
OpentelemetryExUnitFormatter configuration usually should be provided in the config/test.exs
file.
Available configuration options are described below.
User provided single arity anonymous function executed before starting and sending a new telemetry span. Function should accept span attributes map as an argument and should return user modified span attributes map.
Default: nil
.
Example:
# config/test.exs
config :opentelemetry_ex_unit_formatter,
before_send: &MyApp.Test.Support.OpentelemetryExUnitFormatterHelper.before_send/1,
# test/support/opentelemetry_ex_unit_formatter_helper.ex
defmodule MyApp.Test.Support.OpentelemetryExUnitFormatterHelper do
@attr_prefix "code.ci"
@undefined "undefined"
def before_send(attributes) do
attributes
|> Map.put(:"#{@attr_prefix}.ref_name", System.get_env("GITHUB_REF_NAME", @undefined))
|> Map.put(:"#{@attr_prefix}.repository", System.get_env("GITHUB_REPOSITORY", @undefined))
end
end
Opentelemetry processors might process telemetry spans asynchronously.
After entire testing suite is completed by ExUnit
, some spans might still be buffered by
Opentelemetry processor and never exported.
If :register_after_suite?
is set to true
OpentelemetryExUnitFormatter will register a
callback function using ExUnit.after_suite/1
. Registered callback function will use configuration
provided with :tracer_provider_config
key to flush processor using its :name
and then sleep for
the amount of time provided by :bsp_scheduled_delay_ms
key (default 5000ms), waiting for a
processor to flush all pending spans.
In many cases built-in after_suite
callback might not be sufficient or optimal and you should
consider registering your own callback depending on your Opentelemetry processor configuration.
Default: false
.
Name of the root span attribute. By default it is set to the Source Code Attribute.
Default: "code"
.
Name of the emitted spans (see: :otel_tracer_default.with_span/5
).
Default: "ex_unit"
.
To emit telemetry spans OpentelemetryExUnitFormatter will run its own tracer provider, independent
of your application tracer defined in this case for the :test
environment.
Example tracer provider configuration with :otel_simple_processor
processor :ex_unit_processor
and :opentelemetry_exporter
exporter:
# config/test.exs
config :opentelemetry_ex_unit_formatter,
tracer_provider_config: %{
deny_list: [],
id_generator: :otel_id_generator,
sampler: {:otel_sampler_always_on, []},
processors: [
{
:otel_simple_processor,
%{
bsp_scheduled_delay_ms: 1000,
exporter: {:opentelemetry_exporter, %{}},
name: :ex_unit_processor
}
}
]
}
For large projects you might consider using :otel_batch_processor
. When using batch processor, be
aware that spans are batched before being processed and it requires special attention as discussed
in the :register_after_suite?
section.
For debugging purposes :opentelemetry_exporter
can be set to :otel_exporter_stdout
.
Default: :none
.