> Markdown version of [Datadog](https://vaadin.com/docs/next/tools/observability/integrations/datadog). Section index: [llms.txt](https://vaadin.com/docs/next/tools/llms.txt)

# Datadog Integration

Datadog is a commercial service for collecting and viewing telemetry data, with support for metrics, traces, and logs. Datadog doesn’t accept the OpenTelemetry Protocol (OTLP) directly, so an [OpenTelemetry collector](https://opentelemetry.io/docs/collector/) is used as a proxy: the kit’s metrics and traces are exported to the collector over OTLP, and the collector’s Datadog exporter converts and forwards them to Datadog’s API.

## <a id="account-setup"></a>Account Setup

To set up an account, go to the [Datadog website](https://www.datadoghq.com/) and click **Free Trial**. Select the appropriate region for storing data, fill in the remaining details, and follow the instructions.

Completing sign-up involves installing one of Datadog’s agents to send some data. That agent isn’t required for this integration, so it can be removed immediately afterwards. An easy way to run it once is the Docker option: create a container, send some data, then stop and remove the container.

## <a id="opentelemetry-collector-setup"></a>OpenTelemetry Collector Setup

Create a `collector.yaml` configuration file that receives OTLP and exports to Datadog:

collector.yaml

```yaml
receivers:
  otlp:
    protocols:
      http:
      grpc:

processors:
  batch:

exporters:
  datadog:
    api:
      site: DD_SITE
      key: DD_API_KEY

service:
  pipelines:
    metrics:
      receivers: [otlp]
      processors: [batch]
      exporters: [datadog]
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [datadog]
```

Replace the following placeholders:

- `DD_SITE`

  The domain of the Datadog region you registered for. Read it from the browser’s address bar when logged into the Datadog UI — for example `datadoghq.com` for US1, or `datadoghq.eu` for the EU region.

- `DD_API_KEY`

  An API key for authenticating against the Datadog API. To create one, open the Datadog web UI, go to **Organization Settings** then **API Keys**, and create a key.

Run the collector either by downloading the binary or with Docker:

Download the binary from the [latest release on GitHub](https://github.com/open-telemetry/opentelemetry-collector-releases/releases/latest). Download the `otelcol_contrib_` variant — it includes the Datadog exporter — for your operating system.

Then run the collector:

**Binary**

```terminal
otelcol-contrib --config collector.yaml
```

Run the OpenTelemetry collector Docker image, passing the configuration file as a volume:

**Docker**

```terminal
docker run --name otelcol -p 4317:4317 -p 4318:4318 -v collector.yaml:/etc/otelcol-contrib/config.yaml otel/opentelemetry-collector-contrib:latest
```

## <a id="configure-the-application"></a>Configure the Application

Add Actuator and the OpenTelemetry starter, which brings in the OTLP metrics registry and the tracing bridge with the OTLP exporter:

`pom.xml`

```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-opentelemetry</artifactId>
</dependency>
```

Point both pipelines at the local collector:

`application.properties`

```properties
spring.application.name=vaadin

# Metrics over OTLP to the collector
management.otlp.metrics.export.url=http://localhost:4318/v1/metrics

# Traces over OTLP to the collector
management.opentelemetry.tracing.export.otlp.endpoint=http://localhost:4318/v1/traces
management.tracing.sampling.probability=1.0
```

If the collector runs on another host, change the URLs accordingly.

## <a id="logging-setup"></a>Logging Setup

Datadog doesn’t ingest logs over OTLP. The following work-around sends logs to the Datadog logs API and correlates them with the kit’s traces.

Logback Configuration

This method uses a Logback TCP appender to send logs to Datadog while adding the metadata needed to correlate logs with traces.

Add a TCP appender for Logback:

```xml
<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>7.4</version>
</dependency>
```

Micrometer Tracing places the current `traceId` and `spanId` in the logging MDC. To correlate logs with traces, convert those to the `dd.trace_id` and `dd.span_id` fields Datadog expects. Create a `DataDogContextProvider` class:

```java
package com.example.application;

import ch.qos.logback.classic.spi.ILoggingEvent;
import com.fasterxml.jackson.core.JsonGenerator;
import net.logstash.logback.composite.AbstractJsonProvider;

import java.io.IOException;
import java.util.Map;

public class DataDogContextProvider extends AbstractJsonProvider<ILoggingEvent> {
    @Override
    public void writeTo(JsonGenerator generator, ILoggingEvent event) throws IOException {
        Map<String, String> mdc = event.getMDCPropertyMap();

        if (mdc.containsKey("traceId")) {
            String traceId = mdc.get("traceId");
            String low64 = traceId.substring(traceId.length() - 16);
            long ddTraceId = Long.parseUnsignedLong(low64, 16);
            generator.writeStringField("dd.trace_id", Long.toUnsignedString(ddTraceId));
        }

        if (mdc.containsKey("spanId")) {
            String spanId = mdc.get("spanId");
            long ddSpanId = Long.parseUnsignedLong(spanId, 16);
            generator.writeStringField("dd.span_id", Long.toUnsignedString(ddSpanId));
        }
    }
}
```

This reads the `traceId` and `spanId` from the MDC and writes the corresponding Datadog IDs into the JSON output.

Next, create a custom encoder that registers the provider. It extends `LogstashEncoder`, which produces JSON that the Datadog logging endpoint can process:

```java
package com.example.application;

import ch.qos.logback.classic.spi.ILoggingEvent;
import net.logstash.logback.LogstashFormatter;
import net.logstash.logback.composite.AbstractCompositeJsonFormatter;
import net.logstash.logback.encoder.LogstashEncoder;

public class DataDogLogstashEncoder extends LogstashEncoder {
    @Override
    protected AbstractCompositeJsonFormatter<ILoggingEvent> createFormatter() {
        AbstractCompositeJsonFormatter<ILoggingEvent> formatter = super.createFormatter();
        ((LogstashFormatter) formatter).addProvider(new DataDogContextProvider());
        return formatter;
    }
}
```

Add a TCP appender that uses the encoder to your Logback configuration:

```xml
<appender name="JsonTcp" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    <destination>tcp-intake.logs.${DD_SITE}:443</destination>
    <keepAliveDuration>20 seconds</keepAliveDuration>
    <encoder class="com.example.application.DataDogLogstashEncoder">
        <prefix class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="ch.qos.logback.classic.PatternLayout">
                <pattern>${DD_API_KEY} %mdc{keyThatDoesNotExist}</pattern>
            </layout>
        </prefix>
    </encoder>
    <ssl />
</appender>
```

The configuration references two variables, which use the same values as the collector configuration:

- `DD_SITE`

  The domain of your Datadog region.

- `DD_API_KEY`

  An API key for authenticating against the Datadog API.

Pass them when running the application, for example:

```terminal
java -DDD_SITE=datadoghq.eu -DDD_API_KEY=1234ABCD -jar myapp.jar
```

Finally, register the appender for the root logger:

```xml
<root level="info">
    <appender-ref ref="JsonTcp" />
    <!-- ...other appenders -->
</root>
```

## <a id="viewing-data"></a>Viewing Data

### <a id="viewing-traces"></a>Viewing Traces

In the Datadog web UI, select **APM** then **Traces**. The view graphs the number of requests, failed requests, and latency, along with a list of the latest traces.

The search bar filters by tags, which are span attribute values. Click a trace to see the tags recorded for its spans; click a tag to filter on that value. Clicking a trace ID opens a side panel with detailed information such as nested spans, attributes, and related logs.

See the Datadog [Trace Explorer](https://docs.datadoghq.com/tracing/trace_explorer/?tab=listview) documentation for more.

### <a id="viewing-metrics"></a>Viewing Metrics

In the Datadog web UI, select **Metrics** then **Explorer**. Enter one of the metrics collected by the kit — for example `vaadin.sessions.active` — to view it.

See the Datadog [Metrics Explorer](https://docs.datadoghq.com/metrics/explorer/) documentation for more.

### <a id="viewing-logs"></a>Viewing Logs

Log integration is limited to the Logback logging framework, as described above.

In the Datadog web UI, select **Logs**. The view lists recent log entries, which can be filtered by text or log level.

See the Datadog [Logs Explorer](https://docs.datadoghq.com/logs/explorer/) documentation for more.
