This LaunchDarkly observability plugin is available for early accessThis LaunchDarkly observability plugin is currently available in Early Access, and APIs are subject to change until a 1.x version is released.
SDK quick linksLaunchDarkly SDKs are open source. In addition to this reference guide, we provide source, a sample application, and a published module:
| Resource | Location |
|---|---|
| GitHub repository | @launchdarkly/observability-java |
| Sample application | Spring Boot web backend |
| Published module | Maven Central |
Prerequisites and dependencies
This reference guide assumes that you are somewhat familiar with the LaunchDarkly Java SDK. The observability plugin has the following requirements:- The Java SDK, version 7.10.1 or later. This is the first version that supports plugins. The observability plugin does not include the SDK as a dependency. You must declare it yourself.
- Java 11 or later.
- The OpenTelemetry Java SDK, version 1.38.0 or later, on your application’s runtime classpath. The plugin is built against version 1.51.0.
java.net.http.HttpClient. It does not add OkHttp, Okio, the Kotlin standard library, or a JSON library to your classpath. It records flag evaluations with its own hook. You do not need the launchdarkly-java-server-sdk-otel package.
OpenTelemetry versions
Dependency management bills of materials (BOMs), such as the one Spring Boot provides, override the OpenTelemetry version that the plugin requests. If your build resolves an OpenTelemetry version older than 1.38.0, the plugin logs an error and does not start. Your LaunchDarkly client and application continue to run. To check which version your build resolves, run./gradlew dependencies --configuration runtimeClasspath or mvn dependency:tree -Dincludes=io.opentelemetry.
This table lists the OpenTelemetry version that each Spring Boot release manages:
| Spring Boot | OpenTelemetry version | Compatible with plugin |
|---|---|---|
| 3.2 | 1.31.0 | No. Override the OpenTelemetry version. |
| 3.3 | 1.38.0 | Yes |
| 3.4 | 1.43.0 | Yes |
| 3.5 | 1.49.0 | Yes |
| 4.1 | 1.62.0 | Yes |
opentelemetry.version property.
Here’s how:
io.opentelemetry artifact on the same version. If you add OpenTelemetry instrumentation libraries, such as the Logback appender, choose the release that is built on the same core version, or override opentelemetry.version to match it. For example, OpenTelemetry instrumentation 2.17.x is built on OpenTelemetry 1.51.0. Mixing versions causes AbstractMethodError or NoSuchMethodError exceptions at runtime.
Get started
Follow these steps to get started:- Install the plugin
- Initialize the Java SDK client
- Configure the plugin options
- Shut down the plugin
- Explore supported features
- Review observability data in LaunchDarkly
Install the plugin
LaunchDarkly uses a plugin to the Java SDK to provide observability. The first step is to make both the SDK and the observability plugin available as dependencies. The plugin does not include the SDK, so declare both. Here’s how:io.opentelemetry:opentelemetry-api as a compile-scoped dependency, because its public methods take OpenTelemetry API types such as Attributes and Severity. You do not need to declare it yourself.
Then, import the SDK and the plugin in your application code:
Initialize the client
Next, initialize the SDK and the plugin. To initialize, you need your LaunchDarkly environment’s SDK key. This authorizes your application to connect to a particular environment within LaunchDarkly. To learn more, read Initialize the client in the Java SDK reference guide. Here’s how to initialize the SDK and plugin:- Sets up OpenTelemetry tracer, logger, and meter providers that export to LaunchDarkly over OTLP/HTTP.
- Registers a hook that records a span for each flag evaluation and adds a
feature_flagevent to the current span. LaunchDarkly uses these events for guarded rollouts and observability. - Fetches sampling configuration from LaunchDarkly to control the volume of telemetry it exports.
Network requirementsThe observability plugin sends data to LaunchDarkly using port 4318 by default. If your network restricts outbound traffic to port 443, read Network requirements to override the OTLP endpoint.
Configure the plugin options
You can configure options for the observability plugin when you initialize the SDK. The plugin constructor takes anObservabilityOptions object with the configuration details.
Here is an example:
Use the plugin with Spring Boot
In a Spring Boot application, build oneLDClient bean that includes the plugin, and let Spring close it.
Spring Boot shuts down from its own Java Virtual Machine (JVM) shutdown hook, after it drains in-flight requests. Turn off the plugin’s shutdown hook with shutdownHook(false), and shut down the plugin from a bean instead. Otherwise, the plugin may stop before Spring finishes draining requests, and you lose telemetry from those requests.
Here’s how:
Export request spans and errors
Spring Boot’s Micrometer tracing creates a span for each HTTP request and records unhandled exceptions on it. To export these request spans to LaunchDarkly, add the Micrometer OpenTelemetry bridge and provide the plugin’s OpenTelemetry instance as a bean. Spring Boot then exports request spans with flag evaluation spans as their children,feature_flag events on the request span, and exceptions as error events.
First, add the dependencies:
OpenTelemetry bean that returns the plugin’s instance. The LDClient parameter makes Spring start the plugin first:
management.tracing.sampling.probability setting does not apply. The sampling rules you configure in LaunchDarkly determine which spans the plugin exports.
Export application logs
LDObserve.recordLog exports a single log record. To learn more, read Sending logs.
To export the logs you already write through SLF4J and Logback, add the OpenTelemetry Logback appender and install it on the plugin’s OpenTelemetry instance. Choose the appender version that matches your OpenTelemetry version. To learn more, read OpenTelemetry versions.
First, add the dependency:
OpenTelemetry bean:
logsApiLevel option still applies to these records.
If you use Log4j 2 through spring-boot-starter-log4j2, use the io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17 appender instead. Add <OpenTelemetry name="OpenTelemetryAppender"/> to the appenders in log4j2-spring.xml, add packages="io.opentelemetry.instrumentation.log4j.appender.v2_17" to the <Configuration> element, and reference the appender from the root logger. Then call io.opentelemetry.instrumentation.log4j.appender.v2_17.OpenTelemetryAppender.install(openTelemetry) in the bean.
Use the plugin with other OpenTelemetry setups
The plugin registers its OpenTelemetry SDK asGlobalOpenTelemetry when it can. If another component has already registered the global instance, the plugin keeps its own providers. Examples include the OpenTelemetry Java agent, your own OpenTelemetry SDK, or a library that called GlobalOpenTelemetry.get() first.
In either case, the plugin sends flag evaluation spans and all data you record through LDObserve to LaunchDarkly. The plugin adds the feature_flag event to whichever span is current. The component that owns that span exports the event.
To send data from other instrumentation to LaunchDarkly through the plugin, pass it the instance that LDObserve.getOpenTelemetry() returns. This method returns the plugin’s OpenTelemetry instance whether or not it is the global instance. Call it after you build the LDClient. Before the plugin starts, the instance provides no-op tracers, meters, and loggers, and anything you create from them in that window stays a no-op.
Use the OpenTelemetry Java agent
When you attach the OpenTelemetry Java agent, the agent owns the global instance, creates the request spans, and exports them to its own endpoint. The plugin’s flag evaluation spans reference those request spans as parents. To review complete traces in LaunchDarkly, configure the agent to send its data to LaunchDarkly as well. Here’s how:highlight.project_id resource attribute is the attribute that the plugin itself sets to your SDK key. The agent also captures Logback and Log4j records and exports them the same way.
Shut down the plugin
The plugin’s OpenTelemetry providers are process-wide. Closing anLDClient does not stop them.
Call LDObserve.shutdown() when your application stops, for example after you close the client. This flushes any pending telemetry and stops the providers. By default, the plugin also registers a JVM shutdown hook that does the same thing. To turn off the hook, call shutdownHook(false) when you build the plugin options. We recommend turning it off when you use a framework that manages shutdown, such as Spring Boot. To learn more, read Use the plugin with Spring Boot.
Here’s how:
Use multiple clients
The firstLDClient that registers the plugin starts the providers, and its SDK key identifies the LaunchDarkly project for all exported data. Another LDClient with the same SDK key shares the providers. If you register the plugin on an LDClient with a different SDK key, the plugin logs a warning and does not start anything for that client. The plugin still records that client’s flag evaluations, under the first client’s SDK key.