Sending OpenTelemetry traces to LaunchDarkly
This feature is for Early Access Program customers only
Sending OpenTelemetry traces to LaunchDarkly is only available to members of LaunchDarkly’s Early Access Program (EAP). If you want access to this feature, join the EAP.
Enabling OpenTelemetry traces in your server-side SDKs is available to all customers. To learn more, read OpenTelemetry.
Overview
This topic explains how to send OpenTelemetry traces to LaunchDarkly. LaunchDarkly converts this data into events that LaunchDarkly metrics track over time. Experimentation and guarded rollouts use these metrics to measure flag performance.
This topic covers:
- how to send trace data to LaunchDarkly
- how to configure your collector to receive, process, and export telemetry data
- how LaunchDarkly automatically creates metrics from OpenTelemetry trace data
About OpenTelemetry
OpenTelemetry (OTel) is an open source observability framework and toolkit designed to create and manage telemetry data such as traces, metrics, and logs. You can use LaunchDarkly’s OpenTelemetry protocol (OTLP) endpoint to send OpenTelemetry traces to LaunchDarkly.
LaunchDarkly converts the information contained in these traces to produce events for use with Experimentation and guarded rollouts. Typically the information you collect in the traces is related to API performance and errors.
Because OpenTelemetry is vendor- and tool-agnostic, you can reuse the instrumentation that may already exist in your code to create LaunchDarkly metrics without changing application code.
LaunchDarkly supports receiving trace data over gRPC, HTTP/protobuf, and HTTP/JSON.
Send trace data to LaunchDarkly
To send OpenTelemetry trace data to LaunchDarkly, we recommend using the OpenTelemetry Collector. The OpenTelemetry Collector is a vendor-agnostic proxy that can receive, process, and export telemetry data. You can configure an OpenTelemetry pipeline with a processor to filter out data that is not relevant to LaunchDarkly, reducing data transport costs, and to send data to LaunchDarkly in addition to other OTLP backends that you may already be using.
LaunchDarkly processes two types of data from your OpenTelemetry traces:
- HTTP span attributes, including latency, 5xx occurrences, and other errors, where the span has or overlaps with another span that has at least one feature flag span event. This includes nested spans.
- Exception span events that occur after a feature flag span event on the same trace. If the exception occurs before the feature flag event, LaunchDarkly does not capture it.
A feature flag span event is defined as any span event that contains a feature_flag.context.key
attribute. LaunchDarkly ignores traces that do not include span events with this attribute.
To ensure your spans have compatible feature flag events, configure your SDK to use the OpenTelemetry tracing hook.
Sending feature flag event data requires feature flag evaluation
The OpenTelemetry tracing hook automatically attaches feature flag event data to your OTel traces for you. Feature flag event data, including the feature_flag.context.key
attribute, is only generated when your application uses the LaunchDarkly SDK to evaluate a feature flag.
In most SDKs, the OTel traces are specific to the LaunchDarkly project and environment that you specify in the Collector configuration described below. In the .NET (server-side) SDK, you can provide the LaunchDarkly client-side ID in the tracing hook. This enables you to send traces for multiple projects and environments using one Collector.
Try it in your SDK: OpenTelemetry
Generate a new LaunchDarkly service token
All trace data sent to LaunchDarkly must be authenticated with a LaunchDarkly personal or service API access token with a Writer role, or a custom role that allows the token to perform the importEventData
action on the LaunchDarkly environment you are targeting.
Here’s how to create an API service token with the appropriate inline policy:
-
Click the gear icon in the left sidenav to view Organization settings. The General settings page appears.
-
Click Authorization.
-
Click Create token. The “Create access token” dialog appears.
-
Give your token a human-readable Name, such as “Compass integration.”
-
Give your token an “Inline policy” Role.
-
Click the Advanced editor button and specify the following policy in the Editor field to allow the token to perform the
importEventData
action on all LaunchDarkly environment resources:OpenTelemetry Import Inline policy -
Select This is a service token.
- Click Save token and copy the newly created token to your clipboard. You will need it to configure the OpenTelemetry collector in the following section.
Collector configuration
Collector pipelines consists of three components: receivers, exporters, and processors.
The exporter requires specific headers:
Header | Description | Example value |
---|---|---|
Authorization | The LaunchDarkly access token that the exporter should use when sending data to LaunchDarkly. This must be a personal or service API access token with the Required. | ${env:LD_ACCESS_TOKEN} |
X-LaunchDarkly-Project | The project key for the project collecting the traces. Should not be included if you are using .NET (server-side) SDK v8.7 or above. Required for older versions of the .NET (server-side) SDK and for all other SDKs. | example-project-key |
X-LaunchDarkly-Environment | The environment key for the environment collecting the traces. Should not be included if you are using .NET (server-side) SDK v8.7 or above. Required for older versions of the .NET (server-side) SDK and for all other SDKs. | example-environment-key |
If you are using the .NET (server-side) SDK v8.6 or earlier, or any other SDK, then you must provide the X-LaunchDarkly-Project
and X-LaunchDarkly-Environment
headers. When you do, LaunchDarkly imports all traces into the environment specified by these headers. This is shown in the “single environment” examples, below. To import traces into multiple environments when using these headers, you must set up a separate OpenTelemetry Collector for each environment, and configure each of your services to send OTel traces to the correct Collector.
If you are using the .NET (server-side) SDK v8.7 or above, then you should omit the X-LaunchDarkly-Project
and X-LaunchDarkly-Environment
headers. In this version of the SDK, LaunchDarkly automatically imports each trace into the correct environment based on an environment field generated by the LaunchDarkly OTel Hook. If you send traces this way, you may set up a single OTel Collector that accepts traces from all of your services across environments. This is shown in the “multiple environment” examples, below.
To configure a pipeline to send trace data to LaunchDarkly, modify the Collector’s config file, otel-collector-config.yaml
, as follows:
Autogenerated LaunchDarkly metrics from OpenTelemetry trace data
When LaunchDarkly receives OpenTelemetry trace data, it processes and converts this data into events that LaunchDarkly metrics track over time. Experimentation and guarded rollouts use these metrics to measure flag performance.
There are two types of events that LaunchDarkly creates from OpenTelemetry traces: route-specific events and global events. Route-specific events are useful when you are experimenting with a change that is known to impact a small subset of your server’s HTTP routes. Global events are useful when you believe your change may impact all routes, or when you are not sure of the impact of your change.
LaunchDarkly automatically creates the following metrics from the events that LaunchDarkly produces from your OpenTelemetry trace data. This trace data includes the feature flag and the context for which you evaluated the flag. You can also create these metrics manually if you wish. To learn more, read Metrics autogenerated from server-side SDKs using OpenTelemetry.
Event type | LaunchDarkly metric properties | Event name template and examples |
---|---|---|
per-route HTTP request latency |
| http.latency;method={http.request.method};route={http.route} Examples: http.latency;method=GET;route=/api/v2/flags http.latency;method=PATCH;route=/api/v2/flags/{id} |
global HTTP request latency |
| otel.http.latency Example: otel.http.latency |
per-route HTTP request errors |
| http.error;method={http.request.method};route={http.route} Examples: http.error;method=GET;route=/api/v2/flags http.error;method=PATCH;route=/api/v2/flags/{id} |
global exceptions |
| otel.exception Example: otel.exception |
global HTTP 5xxs |
| otel.http.5XX Example: otel.http.5XX |
per-route HTTP 5xxs |
| http.5XX;method={http.request.method};route={http.route} Examples: http.5XX;method=GET;route=/api/v2/flags http.5XX;method=PATCH;route=/api/v2/flags/{id} |
LaunchDarkly supports both the 1.20.0
and 1.23.0
versions of the OpenTelemetry semantic conventions, so you can use http.request
and http.status_code
instead of http.request.method
and http.response.status_code
if you are using 1.20.0
. To learn more, read OpenTelemetry’s HTTP semantic convention migration guide.
When you create a per-route metric, you must provide the http.request.method
and http.route
for each metric in the string templates specified in the table above. It is important that the method and route match the corresponding HTTP semantic convention attributes in the spans you are sending to LaunchDarkly.