Skip to content
Draft
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,79 @@ You only need to enable the protocol your application uses (gRPC on port 4317, o

## Step 2: Configure your application

Set the following environment variable on your application, in addition to the standard [server-side feature flag configuration][1]:
Set the following environment variable in addition to the standard [server-side feature flag configuration][1]:

{{< code-block lang="bash" >}}
# Enable flag evaluation metrics
DD_METRICS_OTEL_ENABLED=true
{{< /code-block >}}

**Note**: The Java tracer does not use `DD_METRICS_OTEL_ENABLED`. Skip this variable and see [Java: Add the OpenTelemetry SDK dependencies](#java-add-the-opentelemetry-sdk-dependencies) instead.

### Java: Add the OpenTelemetry SDK dependencies

The Java provider records `feature_flag.evaluations` through the OpenTelemetry SDK and exports it over OTLP, so the `opentelemetry-sdk-metrics` and `opentelemetry-exporter-otlp` dependencies must be on your application's classpath. Add them alongside your [Java feature flag dependencies][6]. Import the OpenTelemetry BOM so the OpenTelemetry API and SDK stay on the same version:

{{< tabs >}}
{{% tab "Gradle (Groovy)" %}}
{{< code-block lang="groovy" filename="build.gradle" >}}
dependencies {
implementation platform('io.opentelemetry:opentelemetry-bom:1.47.0')
implementation 'io.opentelemetry:opentelemetry-sdk-metrics'
implementation 'io.opentelemetry:opentelemetry-exporter-otlp'
}
{{< /code-block >}}
{{% /tab %}}

{{% tab "Gradle (Kotlin)" %}}
{{< code-block lang="kotlin" filename="build.gradle.kts" >}}
dependencies {
implementation(platform("io.opentelemetry:opentelemetry-bom:1.47.0"))
implementation("io.opentelemetry:opentelemetry-sdk-metrics")
implementation("io.opentelemetry:opentelemetry-exporter-otlp")
}
{{< /code-block >}}
{{% /tab %}}

{{% tab "Maven" %}}
{{< code-block lang="xml" filename="pom.xml" >}}
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-bom</artifactId>
<version>1.47.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-metrics</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
</dependency>
</dependencies>
{{< /code-block >}}
{{% /tab %}}
{{< /tabs >}}

On the Java tracer, the provider starts its OTLP metrics exporter automatically when the OpenTelemetry SDK is on the classpath. Adding these dependencies enables the metric; `DD_METRICS_OTEL_ENABLED` is not required for Java and setting it alone has no effect. If the dependencies are missing, no metrics are emitted and the tracer logs `OpenTelemetry SDK is not on the classpath`.

<div class="alert alert-info">In Spring Boot applications, Spring Boot's OpenTelemetry autoconfiguration also creates an <code>OpenTelemetrySdk</code> bean. If the OpenTelemetry SDK version it resolves does not match the OpenTelemetry API version on the classpath, startup fails with a <code>BeanCreationException</code> for the <code>openTelemetry</code> bean and <code>NoClassDefFoundError: io/opentelemetry/sdk/internal/ScopeConfigurator</code>. Importing the <code>opentelemetry-bom</code> as shown above keeps the API and SDK on the same version and resolves the error.</div>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: This alert reads more like a troubleshooting entry than setup guidance and interrupts the setup flow. Since the preceding paragraph already tells users to import the BOM, consider moving this Spring Boot detail to a troubleshooting section (or a <details> block) so the happy-path setup stays terse.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Response from Claude: Keeping this inline for now. It's an alert-info callout (already set apart from the setup prose) and it documents the exact startup failure users hit right after adding these dependencies — the specific issue this change was written to address — so co-locating it with the dependency step maximizes discoverability. Happy to move it to a dedicated troubleshooting section in a follow-up if you'd prefer.


### Set the OTLP endpoint

By default, most tracers send OTLP metrics to the Agent at `DD_AGENT_HOST` on port `4318` (HTTP). If your application already sets `DD_AGENT_HOST` to reach the Agent, no endpoint configuration is required.

Set an OTLP endpoint explicitly in any of these cases:

- The Agent is not reachable at `DD_AGENT_HOST` on the default OTLP port (for example, a remote Agent or a non-default port).
- You use the **Java** tracer. The Java tracer does not derive the endpoint from `DD_AGENT_HOST`; it defaults to `localhost:4318`. Set the endpoint whenever the Agent is not on `localhost`.
- You use the **Java** tracer. Its flag evaluation metrics exporter supports OTLP/HTTP only (gRPC is not supported) and uses port `4318`. It does not derive the endpoint from `DD_AGENT_HOST` and defaults to `http://localhost:4318`. Set `OTEL_EXPORTER_OTLP_ENDPOINT` to the Agent's HTTP endpoint when the Agent is not on `localhost`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: This bullet has grown to four sentences and mixes protocol support, port, default endpoint, and configuration guidance. Since the Java tracer already has its own subsection above, consider trimming this bullet to just the endpoint/DD_AGENT_HOST behavior and moving the OTLP/HTTP-only + port 4318 detail into the Java subsection where it fits with the rest of the Java-specific setup.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Response from Claude: Keeping the protocol/port detail in this bullet. The sibling Python bullet documents its transport the same way (gRPC on 4317), so keeping Java's HTTP/4318 detail here is parallel and keeps the endpoint-transport facts together in this section. I already trimmed it in a503090 (four sentences to three). Happy to split it into a dedicated Java endpoint callout in a follow-up if you'd prefer.

- You use the **Python** tracer. The Python tracer defaults to gRPC on port `4317`, not HTTP. Enable the gRPC OTLP receiver on the Agent, or override the protocol to use HTTP instead:

{{< code-block lang="bash" >}}
Expand Down Expand Up @@ -151,3 +211,4 @@ The `feature_flag.evaluations` metric is a counter with the following tags:
[3]: https://app.datadoghq.com/metric/explorer
[4]: https://app.datadoghq.com/metric/summary
[5]: /dashboards/
[6]: /feature_flags/server/java/#installation
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ For more detail, see [OpenTelemetry API Support for Go](/opentelemetry/instrumen
{{< code-block lang="bash" filename=".env" >}}
DD_TRACE_OTEL_ENABLED=true
DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED=true
DD_METRICS_OTEL_ENABLED=true
DD_SERVICE=<YOUR_SERVICE_NAME>
DD_ENV=<YOUR_ENVIRONMENT>
DD_VERSION=<YOUR_APP_VERSION>
Expand All @@ -134,7 +133,7 @@ Client client = api.getClient("my-app");
/* Your existing OpenTelemetry API calls continue to work unchanged */
{{< /code-block >}}

**Note**: Depend only on the OpenTelemetry API, not the OpenTelemetry SDK. For more detail, see [OpenTelemetry API Support for Java](/opentelemetry/instrument/dd_sdks/api_support/?prog_lang=java&platform=traces).
**Note**: For tracing, depend only on the OpenTelemetry API, not the OpenTelemetry SDK. For more detail, see [OpenTelemetry API Support for Java](/opentelemetry/instrument/dd_sdks/api_support/?prog_lang=java&platform=traces). To emit flag evaluation metrics, you also need the OpenTelemetry SDK metrics and OTLP exporter dependencies; see [Set Up Server-Side Flag Evaluation Metrics](/feature_flags/guide/server_flag_evaluation_metrics/).

{{% /tab %}}
{{% tab "Node.js" %}}
Expand Down Expand Up @@ -347,7 +346,6 @@ func main() {
{{< code-block lang="bash" filename=".env" >}}
DD_APM_TRACING_ENABLED=false
DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED=true
DD_METRICS_OTEL_ENABLED=true
DD_SERVICE=<YOUR_SERVICE_NAME>
DD_ENV=<YOUR_ENVIRONMENT>
DD_VERSION=<YOUR_APP_VERSION>
Expand Down
22 changes: 14 additions & 8 deletions content/en/feature_flags/server/java.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ The Java SDK integrates feature flags directly into the Datadog Java tracer (`dd

The Datadog Feature Flags SDK for Java requires:
- **Java 11 or higher**
- **Datadog Java SDK**: Version **1.57.0** or later
- **OpenFeature SDK**: Version **1.18.2** or later
- **Datadog Java SDK** (`dd-java-agent`, added with `-javaagent`): Version **1.57.0** or later (**1.62.0** or later for flag evaluation metrics)
- **Datadog OpenFeature provider** (`com.datadoghq:dd-openfeature`, added as a build dependency): Version **1.57.0** or later (**1.62.0** or later for flag evaluation metrics)
- **OpenFeature SDK**: Version **1.20.1** or later
- **Datadog Agent**: Version **7.55 or later** with [Remote Configuration][1] enabled
Comment thread
aarsilv marked this conversation as resolved.
- **Datadog [API key][7]**: Configured on the Agent (not the application) for Remote Configuration

Expand All @@ -54,10 +55,10 @@ Add the following dependencies to your `build.gradle`:
{{< code-block lang="groovy" filename="build.gradle" >}}
dependencies {
// OpenFeature SDK for flag evaluation
implementation 'dev.openfeature:sdk:1.18.2'
implementation 'dev.openfeature:sdk:1.20.1'

// Datadog OpenFeature Provider
implementation 'com.datadoghq:dd-openfeature:1.57.0'
implementation 'com.datadoghq:dd-openfeature:1.63.0'
}
{{< /code-block >}}
{{% /tab %}}
Expand All @@ -68,10 +69,10 @@ Add the following dependencies to your `build.gradle.kts`:
{{< code-block lang="kotlin" filename="build.gradle.kts" >}}
dependencies {
// OpenFeature SDK for flag evaluation
implementation("dev.openfeature:sdk:1.18.2")
implementation("dev.openfeature:sdk:1.20.1")

// Datadog OpenFeature Provider
implementation("com.datadoghq:dd-openfeature:1.57.0")
implementation("com.datadoghq:dd-openfeature:1.63.0")
}
{{< /code-block >}}
{{% /tab %}}
Expand All @@ -85,20 +86,24 @@ Add the following dependencies to your `pom.xml`:
<dependency>
<groupId>dev.openfeature</groupId>
<artifactId>sdk</artifactId>
<version>1.18.2</version>
<version>1.20.1</version>
</dependency>

<!-- Datadog OpenFeature Provider -->
<dependency>
<groupId>com.datadoghq</groupId>
<artifactId>dd-openfeature</artifactId>
<version>1.57.0</version>
<version>1.63.0</version>
</dependency>
</dependencies>
{{< /code-block >}}
{{% /tab %}}
{{< /tabs >}}

The examples above pin `dd-openfeature:1.63.0` and the OpenFeature SDK `1.20.1`. See [Compatibility requirements](#compatibility-requirements) for the minimum supported versions.

To emit flag evaluation metrics (the `feature_flag.evaluations` metric), add the OpenTelemetry SDK dependencies and configure the OTLP endpoint. See [Set Up Server-Side Flag Evaluation Metrics][8].

## Configuration

If your Datadog Agent already has Remote Configuration enabled for other features (like Dynamic Instrumentation or Application Security), you can skip the Agent configuration and go directly to [Application configuration](#application-configuration).
Expand Down Expand Up @@ -686,3 +691,4 @@ Exposures appear in Datadog only for flags associated with an experiment. Standa
[5]: https://app.datadoghq.com/feature-flags/settings/environments
[6]: /agent/configuration/agent-commands/
[7]: /account_management/api-app-keys/#api-keys
[8]: /feature_flags/guide/server_flag_evaluation_metrics/
9 changes: 4 additions & 5 deletions content/en/getting_started/feature_flags/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,10 @@ Add the OpenFeature SDK and Datadog OpenFeature provider dependencies:
{{< code-block lang="groovy" filename="build.gradle" >}}
dependencies {
// OpenFeature SDK for flag evaluation
implementation 'dev.openfeature:sdk:1.18.2'
implementation 'dev.openfeature:sdk:1.20.1'

// Datadog OpenFeature Provider
implementation 'com.datadoghq:dd-openfeature:1.57.0'
implementation 'com.datadoghq:dd-openfeature:1.63.0'
}
{{< /code-block >}}

Expand All @@ -169,12 +169,11 @@ Enable the provider and start your application with the Java tracer:
# The EXPERIMENTAL_ prefix is historical; the provider is no longer experimental.
export DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED=true

# Optional: Enable flag evaluation metrics
export DD_METRICS_OTEL_ENABLED=true

java -javaagent:path/to/dd-java-agent.jar -jar your-application.jar
{{< /code-block >}}

To emit flag evaluation metrics, add the OpenTelemetry SDK dependencies and configure the OTLP endpoint. See [Set Up Server-Side Flag Evaluation Metrics][9].

Register the Datadog OpenFeature provider:

{{< code-block lang="java" >}}
Expand Down
Loading