opentelemetry_honeycomb
provides an in-process OpenTelemetry exporter for Honeycomb.
Add opentelemetry
, opentelemetry_api
, and opentelemetry_honeycomb
to your deps
in
mix.exs
:
{:opentelemetry, "~> 0.5.0"},
{:opentelemetry_api, "~> 0.5.0"},
{:opentelemetry_honeycomb, "~> 0.5.0-rc.1"},
If you're using the default back ends, you'll also need hackney
and poison
:
{:hackney, ">= 1.11.0"},
{:poison, ">= 1.5.0"},
A compact config/config.exs
for opentelemetry_honeycomb
is:
use Config
# You can also supply opentelemetry resources using environment variables, eg.:
# OTEL_RESOURCE_ATTRIBUTES=service.name=name,service.namespace=namespace
config :opentelemetry, :resource,
service: [
name: "service-name",
namespace: "service-namespace"
]
config :opentelemetry,
processors: [
otel_batch_processor: %{
exporter:
{OpenTelemetry.Honeycomb.Exporter, write_key: System.get_env("HONEYCOMB_WRITEKEY")}
}
]
processors
specifies otel_batch_processor
, which specifies exporter
, a 2-tuple of the
exporter's module name and options to be supplied to its init/1
. Our exporter takes a list of
t:OpenTelemetry.Honeycomb.Config.config_opt/0
as its options.
OpenTelemetry supports a flat map of attribute keys to string, number, and boolean values (see
t.OpenTelemetry.attribute_value/0
). The API does not enforce this, implicitly supporting other
attribute value types eg. maps until export time.
Honeycomb expects a flat JSON-serialisable object, but can be configured to flatten maps and stringify arrays at import time.
The data models being quite similar, we:
- Pass string, number, and boolean values through unmodified
- Flatten map values as described below
- Convert most other values to strings using
inspect/1
with a shortlimit
- Trim string values longer than 49127 bytes
When trimming strings, we replace the last 3-7 characters of the trimmed string or so with an
ellipsis ("..."
) of equal length. We choose the length of the ellipsis to avoid ending the
trimmed string with a high-bit character, eg. splitting a UTF-8 code point.
We drop:
- Entire attribute lists that don't start as a list or map
- Entire list members that don't resemble key/value pairs
When flattening maps, we use periods (.
) to delimit keys, for example this input:
%{
http: %{
host: "localhost",
method: "POST",
path: "/api"
}
}
... to this output:
%{
"http.host" => "localhost",
"http.method" => "POST",
"http.path" => "/api",
}
First, we need to check :opentelemetry
and :opentelemetry_api
. Fire up iex -S mix
and paste
in the following code to install the :otel_exporter_stdout
exporter:
:otel_batch_processor.set_exporter(:otel_exporter_stdout, [])
After a delay, you should see:
*SPANS FOR DEBUG*
*SPANS FOR DEBUG*
*SPANS FOR DEBUG*
Now, paste in some trace-sending code:
require OpenTelemetry.Tracer
OpenTelemetry.Tracer.with_span "example" do
IO.inspect(OpenTelemetry.Tracer.current_span_ctx())
OpenTelemetry.Tracer.set_attribute(:a, 1)
OpenTelemetry.Tracer.set_attributes(b: 2, c: 3)
OpenTelemetry.Tracer.set_attributes(d: %{e: "f"})
end
You should get output resembling:
{span,142297071326187490948809128380223875835,10977461588491893807,undefined,
undefined,<<"example">>,'INTERNAL',-576460738804789000,
-576460738804601000,
[{a,1},{b,2},{c,3},{d,#{e => <<"f">>}}],
[],[],undefined,1,false,undefined}
Next, we need to check OpenTelemetry.Honeycomb.Exporter
. Paste in:
# hard way
:otel_batch_processor.set_exporter(OpenTelemetry.Honeycomb.Exporter,
http_module: OpenTelemetry.Honeycomb.Http.ConsoleBackend,
write_key: "HONEYCOMB_WRITEKEY"
)
# easy way
OpenTelemetry.Honeycomb.Http.ConsoleBackend.activate()
Paste in the trace-sending code again to see what the OpenTelemetry Honeycomb Exporter would have sent to Honeycomb:
POST /1/batch/opentelemetry HTTP/1.1
Host: api.honeycomb.io
Content-Type: application/json
User-Agent: opentelemetry_honeycomb/0.3.0-rc.0
X-Honeycomb-Team: HONEYCOMB_WRITEKEY
[
{
"time": "2020-04-24T06:12:16.698425Z",
"samplerate": 1,
"data": {
"trace.trace_id": "6c14288156831d40602dc1f5a61489c0",
"trace.span_id": "377fce3346b92811",
"trace.parent_id": null,
"service.namespace": "service-namespace",
"service.name": "service-name",
"name": "example",
"duration_ms": 6.06005859375,
"d.e": "f",
"c": 3,
"b": 2,
"a": 1
}
}
]
Restore your configured exporter by pasting:
OpenTelemetry.Honeycomb.Http.ConsoleBackend.deactivate()
Dependency management:
mix deps.get
to get your dependenciesmix deps.compile
to compile themmix licenses
to check their license declarations, recursively
Finding problems:
mix compile
to compile your codemix credo
to suggest more idiomatic style for itmix dialyzer
to find problems static typing might spot... slowlymix test
to run unit testsmix test.watch
to run the tests again whenever you change somethingmix coveralls
to check test coverage
Documentation:
mix docs
to generate documentation for this projectmix help
to find out what else you can do withmix
- Removed decorator: use resources or extra processors.