PrimaOpentelemetryEx
This is your one-stop source of all things opentelemetry in elixir. You can stop getting headaches figuring out which opentelemetry_beam library you need or resolving dependencies conflicts. Just add
{:prima_opentelemetry_ex, "~> 1.0.0-rc.2"}
to your dependencies and you are good to go.
What's covered:
- HTTPoison - to trace the http calls you make to external system and to pass along the trace context
- Plug - to link your phoenix/plug handled requests with their http clients traces
- Absinthe - to trace your GraphQL resolutions in a single span
- Ecto - to trace your database transactions in a single span
Usage
To start collecting traces just put
PrimaOpentelemetryEx.setup()
in your application start function.
To trace your outgoing http calls you need to use the Telepoison
module as a drop-in replacement for HTTPoison
.
e.g.
Telepoison.post("https://example.com/", "{'example': 1}", %{"content-type" => "application/json"}, [timeout: 5_000])
For more informations see telepoison usage
To emit server spans (from plug) you need to add Teleplug
to your plug pipeline either in your phoenix endpoint module or in every pipeline you want to trace (contained in your router module if you are using phoenix).
e.g.
pipeline :example do
plug Teleplug
plug Plug.Logger
end
GraphQL and database spans are emitted automatically.
To see emitted traces on your local dev machine, you can use jaeger all-in-one image.
NOTE: This is a discontinued jaeger image but it exposes the otel collector (that is compatible with the exporter prima_opentelemetry_ex
uses).
To add it to your local docker compose simply add a service (which your web container should depend on):
jaeger:
image: jaegertracing/opentelemetry-all-in-one:latest
ports:
- 16686:16686
You can then use the jaeger UI to search for your traces.
Be advised that prima_opentelemetry_ex
uses ENV vars to set service name and version inside the exported traces. Those values are important, for example, to make datadog correctly recognize services and their relative deployments (through version tracking); the two ENV var currently used are:
APP_NAME
for service nameVERSION
for service version
These are supposed to be correctly set up inside prima containers in production; if you want to you can set them up for local development through docker-compose, for example:
services:
web:
build: .
volumes:
- "~/.ssh:/home/app/.ssh"
- "~/.aws:/home/app/.aws"
- "~/.gitconfig:/home/app/.gitconfig"
- .:$PWD
ports:
- 230:4000
depends_on:
- jaeger
working_dir: $PWD
environment:
APP_NAME: MY_SERVICE_NAME
VERSION: 0.0.0-dev
env_file:
- biscuit.env
Configuration
General
If you want to disable tracing via configuration (if you need to turn it off for a particular environment, for example) like so:
config :prima_opentelemetry_ex, :enabled, false
To configure the endpoint to send traces to, you can use the :endpoint
configuration key to set protocol, host and port of the destination endpoint (agent or collector).
In this example you can see the default value for every configuration:
config :prima_opentelemetry_ex, :endpoint,
protocol: :http,
host: "jaeger",
port: 55681
These values get used to build the configuration for the opentelemetry_exporter (through a batch processor). If you want to have a bit more freedom and set opentelemetry configuration by yourself feel free to do so, it won't get overwritten. Example opentelemetry configuration:
config :opentelemetry, :processors,
otel_batch_processor: %{
exporter: {:opentelemetry_exporter, %{endpoints: [{:http, "jaeger", 55681, []}]}}
}
GraphQL
You can change the default span name and choose which informations about your graphql you want traced; e.g.
config :prima_opentelemetry_ex, :graphql,
span_name: "graphql resolution",
trace_request_variables: false
All the :graphql
configurations get passed directly to OpentelemetryAbsinthe
. For more informations about what you can do with them, see opentelemetry_absinthe readme
Copyright and License
Copyright (c) 2020 Prima.it
This work is free. You can redistribute it and/or modify it under the terms of the MIT License. See the LICENSE.md file for more details.