diff --git a/content/en/opentelemetry/instrument/dd_sdks/api_support.mdoc.md b/content/en/opentelemetry/instrument/dd_sdks/api_support.mdoc.md index d57fdc6eac9..a7b43bdb122 100644 --- a/content/en/opentelemetry/instrument/dd_sdks/api_support.mdoc.md +++ b/content/en/opentelemetry/instrument/dd_sdks/api_support.mdoc.md @@ -12,6 +12,7 @@ aliases: - /opentelemetry/instrument/api_support/go/metrics - /opentelemetry/instrument/api_support/go/traces - /opentelemetry/instrument/api_support/java + - /opentelemetry/instrument/api_support/java/logs - /opentelemetry/instrument/api_support/java/metrics - /opentelemetry/instrument/api_support/java/traces - /opentelemetry/instrument/api_support/nodejs/ @@ -57,15 +58,6 @@ further_reading: - -{% if equals($prog_lang, "java") %} -{% if equals($platform, "logs") %} -{% alert level="danger" %} -OpenTelemetry API support for logs is not available for this language. Use [Datadog Log Collection][210] instead. -{% /alert %} -{% /if %} -{% /if %} - {% if equals($prog_lang, "php") %} {% if equals($platform, "logs") %} @@ -190,7 +182,7 @@ The OpenTelemetry Metrics SDK for Ruby is currently in [alpha implementation](ht - **Rust**: MSRV 1.84 or later. {% /if %} {% if equals($prog_lang, "java") %} -- **Datadog SDK**: dd-trace-java version 1.61.0 or later. +- **Datadog SDK**: `dd-trace-java` version 1.61.0 or later. {% /if %} - **An OTLP-compatible destination**: You must have a destination (Agent or Collector) listening on ports 4317 (gRPC) or 4318 (HTTP) to receive OTel metrics. {% if includes($prog_lang, ["dot_net", "node_js", "python", "ruby", "go", "java"]) %} @@ -838,7 +830,7 @@ If you are currently using the Datadog DogStatsD client and want to migrate to t - Verify `DD_METRICS_OTEL_ENABLED=true` is set before initializing the meter provider. {% /if %} {% if equals($prog_lang, "java") %} -- Verify Datadog automatic instrumentation is active. This feature relies on Datadog's automatic instrumentation to function. +- Verify the `dd-trace-java` javaagent is running. The javaagent registers itself as the global OTel MeterProvider at startup; without it, OTel API calls fall through to no-op providers and no data is sent. {% /if %} {% if equals($prog_lang, "dot_net") %} @@ -875,14 +867,14 @@ Here is the minimum version required for each instrument type: {% if equals($platform, "logs") %} -{% if includes($prog_lang, ["dot_net", "node_js", "python", "go", "rust"]) %} +{% if includes($prog_lang, ["dot_net", "node_js", "python", "go", "rust", "java"]) %} ## Overview Use the OpenTelemetry Logs API with Datadog SDKs to send custom application logs. This is an alternative to Datadog's traditional log injection. - -{% if includes($prog_lang, ["dot_net", "node_js", "go", "rust"]) %} + +{% if includes($prog_lang, ["dot_net", "node_js", "go", "rust", "java"]) %} The Datadog SDK provides a native implementation of the OpenTelemetry API. This means you can write code against the standard OTel interfaces without needing the official OpenTelemetry SDK. @@ -924,6 +916,12 @@ If you encounter an issue after upgrading `@opentelemetry/api-logs`, [open an is - **Rust**: MSRV 1.84.1 or later. - **OpenTelemetry Rust SDK**: The SDK provides the logs implementation automatically. {% /if %} +{% if equals($prog_lang, "java") %} +- **Datadog SDK**: `dd-trace-java` version 1.62.0 or later. + + +- **OpenTelemetry API**: `opentelemetry-api` version 1.27.0 (the version that introduced the stable Logs API) or later. +{% /if %} - **An OTLP-compatible destination**: You must have a destination (Agent or Collector) listening on ports 4317 (gRPC) or 4318 (HTTP) to receive OTel logs. ## Setup @@ -1050,6 +1048,15 @@ Follow these steps to enable OTel Logs API support in your application. ``` {% /if %} +{% if equals($prog_lang, "java") %} +1. Add the Datadog SDK (`dd-trace-java`) to your project and [enable its instrumentation][207]. +2. Make sure you only depend on the OpenTelemetry API (and not the OpenTelemetry SDK). +3. Enable OTel logs by setting the following environment variable: + ```sh + export DD_LOGS_OTEL_ENABLED=true + ``` +{% /if %} + ## Examples {% if equals($prog_lang, "dot_net") %} @@ -1342,6 +1349,57 @@ logger.emit(log_record); ``` {% /if %} +{% if equals($prog_lang, "java") %} +### Emitting a log {% #emitting-log-java %} + +After the Datadog SDK is initialized, you can use the standard OpenTelemetry Logs API to get a logger and emit log records. + +```java +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.logs.Logger; +import io.opentelemetry.api.logs.Severity; + +Logger logger = GlobalOpenTelemetry.get().getLogsBridge().get("my-service"); + +logger.logRecordBuilder() + .setBody("User clicked the checkout button.") + .setSeverity(Severity.INFO) + .setSeverityText("INFO") + .setAttribute(AttributeKey.stringKey("cart.id"), "c-12345") + .setAttribute(AttributeKey.stringKey("user.id"), "u-54321") + .emit(); +``` + +### Trace and log correlation {% #trace-log-correlation-java %} + +Trace and log correlation is automatic. When you emit a log using the OTel Logs API within an active Datadog trace, the `trace_id` and `span_id` are automatically added to the log record. + +```java +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.logs.Logger; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.Scope; + +Tracer tracer = GlobalOpenTelemetry.getTracer("my-service"); +Logger logger = GlobalOpenTelemetry.get().getLogsBridge().get("my-service"); + +Span span = tracer.spanBuilder("process.user.request").startSpan(); +try (Scope scope = span.makeCurrent()) { + // This log is automatically correlated with the active span + logger.logRecordBuilder() + .setBody("Processing user request for ID: 12345") + .setSeverity(Severity.INFO) + .setSeverityText("INFO") + .emit(); +} finally { + span.end(); +} +``` +{% /if %} + ## Supported configuration To enable this feature, you must set `DD_LOGS_OTEL_ENABLED=true`. @@ -1398,6 +1456,12 @@ The Datadog SDK programmatically configures the OTel SDK for you. 4. Set the `DD_LOGS_OTEL_ENABLED=true` environment variable. {% /if %} +{% if equals($prog_lang, "java") %} +1. Add the Datadog SDK (`dd-trace-java`) to your project and [enable its instrumentation][207]. +2. Make sure you only depend on the OpenTelemetry API (and not the OpenTelemetry SDK). +3. Set the `DD_LOGS_OTEL_ENABLED=true` environment variable. +{% /if %} + ### Existing Datadog log injection If you are using Datadog's traditional log injection (where `DD_LOGS_INJECTION=true` adds trace context to text logs) and an Agent to tail log files: @@ -1434,6 +1498,9 @@ If you are using Datadog's traditional log injection (where `DD_LOGS_INJECTION=t - Verify `datadog_opentelemetry::logs().init()` is called before using the logger. - Check protocol configuration. Only `grpc` and `http/protobuf` protocols are supported. HTTP/JSON is not supported. {% /if %} +{% if equals($prog_lang, "java") %} +- Verify the `dd-trace-java` javaagent is running. The javaagent registers itself as the global OTel LoggerProvider at startup; without it, OTel API calls fall through to no-op providers and no data is sent. +{% /if %} {% /if %}