---
title: Install the Standalone DDOT Collector as a Kubernetes DaemonSet
description: >-
  Deploy the standalone Datadog Distribution of the OpenTelemetry (DDOT)
  Collector on Kubernetes using the OpenTelemetry Operator or Helm chart.
breadcrumbs: >-
  Docs > OpenTelemetry in Datadog > Send OpenTelemetry Data to Datadog > Datadog
  Distribution of OpenTelemetry Collector > Install > Install the Standalone
  DDOT Collector as a Kubernetes DaemonSet
---

> For the complete documentation index, see [llms.txt](https://docs.datadoghq.com/llms.txt).

# Install the Standalone DDOT Collector as a Kubernetes DaemonSet

{% callout %}
Installing the standalone DDOT Collector with OpenTelemetry tooling is in Preview.
{% /callout %}

## Overview{% #overview %}

Follow this guide to deploy the Datadog Distribution of OpenTelemetry (DDOT) Collector using the OpenTelemetry Operator or Helm chart.

{% alert level="info" %}
**Need additional OpenTelemetry components?** If you need components beyond those included in the default package, follow [Use Custom OpenTelemetry Components](https://docs.datadoghq.com/opentelemetry/setup/ddot_collector/custom_components.md) to extend DDOT's capabilities. For a list of components included by default, see [OpenTelemetry Collector components](https://docs.datadoghq.com/opentelemetry/agent.md#opentelemetry-collector-components).
{% /alert %}

## Requirements{% #requirements %}

To complete this guide, you need the following:

**Datadog account**:

1. [Create a Datadog account](https://www.datadoghq.com/free-datadog-trial/) if you don't have one.
1. Find or create your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys/).

**Software**: Install and set up the following on your machine:

- A Kubernetes cluster (v1.29+)
- [Helm (v4+)](https://helm.sh)
- [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl)

**Network**:

| Protocol | Transport | Port |
| -------- | --------- | ---- |
| gRPC     | TCP       | 4317 |
| HTTP     | TCP       | 4318 |

## Install the Datadog Distribution of the OpenTelemetry Collector{% #install-the-datadog-distribution-of-the-opentelemetry-collector %}

### Select installation method{% #select-installation-method %}

Choose one of the following installation methods:

- [OpenTelemetry Operator](https://opentelemetry.io/docs/platforms/kubernetes/operator/): A [Kubernetes-native](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) approach that automatically reconciles and maintains your OTel Collector setup.
- [Helm chart](https://opentelemetry.io/docs/platforms/kubernetes/helm/collector/): A straightforward way to deploy OTel Collectors.

{% tab title="Operator" %}
### Install the OpenTelemetry Operator{% #install-the-opentelemetry-operator %}

You can install the OpenTelemetry Operator in your cluster using the [OpenTelemetry Operator Helm chart](https://github.com/open-telemetry/opentelemetry-helm-charts/blob/main/charts/opentelemetry-operator/README.md):

```shell
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
helm repo update
helm install opentelemetry-operator open-telemetry/opentelemetry-operator   \
     --set "manager.createRbacPermissions=true"                             \
     --set "manager.collectorImage.repository=datadog/ddot-collector"       \
     --set "manager.collectorImage.tag=7.80.4"
```

{% callout %}
# Important note for users on the following Datadog sites: app.ddog-gov.com, us2.ddog-gov.com



{% alert level="info" %}
For FED, set the tag to `7.80.4-fips` to use the FIPS-compliant DDOT image. See [FIPS compliance](https://docs.datadoghq.com/agent/configuration/fips-compliance.md).
{% /alert %}


{% /callout %}

{% /tab %}

{% tab title="Helm" %}
### Add the OpenTelemetry Helm repository{% #add-the-opentelemetry-helm-repository %}

To add the OpenTelemetry repository to your Helm repositories:

```shell
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
helm repo update
```

{% /tab %}

### Set up Datadog API key{% #set-up-datadog-api-key %}

1. Get the Datadog [API key](https://app.datadoghq.com/organization-settings/api-keys/).
1. Confirm the **DATADOG SITE** selected on the right (Current value: **{% placeholder "user-datadog-site-name" /%}**) corresponds to your [Datadog site](https://docs.datadoghq.com/getting_started/site.md).
1. Store the API key as a Kubernetes secret:
   ```shell
   kubectl create secret generic datadog-secret \
     --from-literal api-key=<DD_API_KEY>        \
     --from-literal site=<YOUR_DATADOG_SITE>
   ```
Replace `<DD_API_KEY>` with your actual Datadog API key.

### Configure the OTel Collector{% #configure-the-otel-collector %}

{% tab title="Operator" %}
After deploying the OTel Operator, create the `OpenTelemetryCollector` resource that triggers the deployment of the Collector.

1. Use the `node-collector.yaml` file to specify your `OpenTelemetryCollector` daemonset configuration.

In the `node-collector.yaml` file:

```yaml
apiVersion: opentelemetry.io/v1beta1
kind: OpenTelemetryCollector
metadata:
  name: node-collector
spec:
  # Deploy 1 instance per node, that will collect telemetry from that node's pods
  mode: daemonset
  command: ['otel-agent', 'run'] # Will no longer be necessary from 7.82.0 onwards
  config:
    exporters:
      datadog:
        api:
          key: ${env:DD_API_KEY}
          site: ${env:DD_SITE}
        sending_queue:
          batch:
            flush_timeout: 10s
    service:
      telemetry:
        resource:
          k8s.cluster.name: ${env:K8S_CLUSTER_NAME}
  env:
    - name: DD_API_KEY
      valueFrom:
        secretKeyRef:
          key: api-key
          name: datadog-apikey
    - name: DD_SITE
      valueFrom:
        secretKeyRef:
          key: site
          name: datadog-apikey
    - name: DD_OTELCOLLECTOR_CONVERTER_FEATURES
      value: datadog,pprof,zpages,prometheus,infraattributes
    - name: K8S_CLUSTER_NAME
      value: <CLUSTER_NAME>
    # vvv Will no longer be necessary from 7.83.0 onwards vvv
    - name: DD_OTEL_STANDALONE
      value: 'true'
    # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    # vvv Will no longer be necessary from 7.82.0 onwards vvv
    - name: DD_OTELCOLLECTOR_ENABLED
      value: 'true'
    # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

Replace `<CLUSTER_NAME>` with a name for your cluster.
Add an OTLP receiver and the Datadog exporter for all desired signals. Publish the OTLP ports on the node with `hostPort` so that application pods can reach the Collector instance running on the same node:
In the `node-collector.yaml` file:

```yaml
# [...]
spec:
  # [...]
  # Publish the OTLP ports on the node's network interface
  ports:
    - name: otlp-grpc
      port: 4317
      protocol: TCP
      hostPort: 4317
    - name: otlp-http
      port: 4318
      protocol: TCP
      hostPort: 4318
  config:
    receivers:
      otlp:
        protocols:
          grpc:
            endpoint: 0.0.0.0:4317
          http:
            endpoint: 0.0.0.0:4318
    # [...]
    service:
      # [...]
      pipelines:
        logs:
          receivers: ['otlp']
          exporters: ['datadog']
        metrics:
          receivers: ['otlp']
          exporters: ['datadog']
        traces:
          receivers: ['otlp']
          exporters: ['datadog']
```
(Optional) Enable additional features:
{% alert level="warning" %}
Enabling these features may incur additional charges. Review the [pricing page](https://www.datadoghq.com/pricing/) and talk to your Customer Success Manager before proceeding.
{% /alert %}

In the `node-collector.yaml` file:

```yaml
spec:
  config:
    receivers:
      host_metrics:
        collection_interval: 15s
        scrapers:
          cpu: {}
          load: {}
          memory: {}
          network: {}
          disk: {}
      kubelet_stats:
        auth_type: serviceAccount
        collection_interval: 15s
        endpoint: ${env:K8S_NODE_NAME}:10250
        node: ${env:K8S_NODE_NAME}
        metric_groups:
          - pod
          - container
          - volume
    processors:
      infraattributes:
        cardinality: 2
      resource/add-cluster-name:
        attributes:
          - key: k8s.cluster.name
            value: ${env:K8S_CLUSTER_NAME}
            action: upsert
    connectors:
      datadog/connector:
        traces:
          compute_top_level_by_span_kind: true
          peer_tags_aggregation: true
          compute_stats_by_span_kind: true
    extensions:
      health_check:
        endpoint: "${env:K8S_POD_IP}:13133"
    # [...]
    service:
      # [...]
      extensions: ['health_check']
      pipelines:
        logs:
          # [...]
          processors: ['resource/add-cluster-name', 'infraattributes']
        metrics:
          receivers: ['host_metrics', 'otlp', 'kubelet_stats', 'datadog/connector']
          processors: ['resource/add-cluster-name', 'infraattributes']
          # [...]
        traces:
          # [...]
          processors: ['resource/add-cluster-name', 'infraattributes']
          exporters: ['datadog', 'datadog/connector']
  env:
    # [...]
    - name: K8S_POD_IP
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: status.podIP
    # K8S_NODE_NAME is added automatically by the operator
```
(Optional) Collect container logs from the node's file system:
{% alert level="warning" %}
Enabling log collection may incur additional charges. Review the [pricing page](https://www.datadoghq.com/pricing/) and talk to your Customer Success Manager before proceeding.
{% /alert %}

The `filelog` receiver reads container logs from the node. Because the Operator does not mount host paths automatically, add the log directories as read-only volumes:

In the `node-collector.yaml` file:

```yaml
spec:
  config:
    receivers:
      filelog:
        include:
          - /var/log/pods/*/*/*.log
        # Exclude the Collector's own logs to avoid a feedback loop
        exclude:
          - /var/log/pods/*_node-collector-collector-*_*/otc-container/*.log
        start_at: end
        include_file_path: true
        include_file_name: false
        retry_on_failure:
          enabled: true
        operators:
          - id: container-parser
            type: container
            max_log_size: 102400
    # [...]
    service:
      # [...]
      pipelines:
        logs:
          receivers: ['otlp', 'filelog']
          # [...]
  # Mount the node's log directories into the Collector pod (read-only)
  volumes:
    - name: varlogpods
      hostPath:
        path: /var/log/pods
    - name: varlibdockercontainers
      hostPath:
        path: /var/lib/docker/containers
  volumeMounts:
    - name: varlogpods
      mountPath: /var/log/pods
      readOnly: true
    - name: varlibdockercontainers
      mountPath: /var/lib/docker/containers
      readOnly: true
```

{% collapsible-section %}
Completed node-collector.yaml file
Your `node-collector.yaml` file should look something like this:

In the `node-collector.yaml` file:

```yaml
apiVersion: opentelemetry.io/v1beta1
kind: OpenTelemetryCollector
metadata:
  name: node-collector
spec:
  # Deploy 1 instance per node, that will collect telemetry from that node's pods
  mode: daemonset
  command: ['otel-agent', 'run'] # Will no longer be necessary from 7.82.0 onwards
  # Publish the OTLP ports on the node's network interface
  ports:
    - name: otlp-grpc
      port: 4317
      protocol: TCP
      hostPort: 4317
    - name: otlp-http
      port: 4318
      protocol: TCP
      hostPort: 4318
  config:
    receivers:
      otlp:
        protocols:
          grpc:
            endpoint: 0.0.0.0:4317
          http:
            endpoint: 0.0.0.0:4318
      host_metrics:
        collection_interval: 15s
        scrapers:
          cpu: {}
          load: {}
          memory: {}
          network: {}
          disk: {}
      kubelet_stats:
        auth_type: serviceAccount
        collection_interval: 15s
        endpoint: ${env:K8S_NODE_NAME}:10250
        node: ${env:K8S_NODE_NAME}
        metric_groups:
          - pod
          - container
          - volume
      filelog:
        include:
          - /var/log/pods/*/*/*.log
        exclude:
          - /var/log/pods/*_node-collector-collector-*_*/otc-container/*.log
        start_at: end
        include_file_path: true
        include_file_name: false
        retry_on_failure:
          enabled: true
        operators:
          - id: container-parser
            type: container
            max_log_size: 102400
    processors:
      infraattributes:
        cardinality: 2
      resource/add-cluster-name:
        attributes:
          - key: k8s.cluster.name
            value: ${env:K8S_CLUSTER_NAME}
            action: upsert
    connectors:
      datadog/connector:
        traces:
          compute_top_level_by_span_kind: true
          peer_tags_aggregation: true
          compute_stats_by_span_kind: true
    exporters:
      datadog:
        api:
          key: ${env:DD_API_KEY}
          site: ${env:DD_SITE}
        sending_queue:
          batch:
            flush_timeout: 10s
    extensions:
      health_check:
        endpoint: "${env:K8S_POD_IP}:13133"
    service:
      telemetry:
        resource:
          k8s.cluster.name: ${env:K8S_CLUSTER_NAME}
      extensions: ['health_check']
      pipelines:
        logs:
          receivers: ['otlp', 'filelog']
          processors: ['resource/add-cluster-name', 'infraattributes']
          exporters: ['datadog']
        metrics:
          receivers: ['host_metrics', 'otlp', 'kubelet_stats', 'datadog/connector']
          processors: ['resource/add-cluster-name', 'infraattributes']
          exporters: ['datadog']
        traces:
          receivers: ['otlp']
          processors: ['resource/add-cluster-name', 'infraattributes']
          exporters: ['datadog', 'datadog/connector']
  env:
    - name: DD_API_KEY
      valueFrom:
        secretKeyRef:
          key: api-key
          name: datadog-apikey
    - name: DD_SITE
      valueFrom:
        secretKeyRef:
          key: site
          name: datadog-apikey
    - name: DD_OTELCOLLECTOR_CONVERTER_FEATURES
      value: datadog,pprof,zpages,prometheus,infraattributes
    - name: K8S_CLUSTER_NAME
      value: <CLUSTER_NAME>
    - name: K8S_POD_IP
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: status.podIP
    # K8S_NODE_NAME is added automatically by the operator
    # vvv Will no longer be necessary from 7.83.0 onwards vvv
    - name: DD_OTEL_STANDALONE
      value: 'true'
    # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    # vvv Will no longer be necessary from 7.82.0 onwards vvv
    - name: DD_OTELCOLLECTOR_ENABLED
      value: 'true'
    # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  # Mount the node's log directories for the filelog receiver (read-only)
  volumes:
    - name: varlogpods
      hostPath:
        path: /var/log/pods
    - name: varlibdockercontainers
      hostPath:
        path: /var/lib/docker/containers
  volumeMounts:
    - name: varlogpods
      mountPath: /var/log/pods
      readOnly: true
    - name: varlibdockercontainers
      mountPath: /var/lib/docker/containers
      readOnly: true
```

Replace `<CLUSTER_NAME>` with a name for your cluster.
{% /collapsible-section %}

{% /tab %}

{% tab title="Helm" %}
Use a YAML file to specify the Helm chart parameters for the [Collector chart](https://github.com/open-telemetry/opentelemetry-helm-charts/blob/main/charts/opentelemetry-collector/README.md).

1. Create an empty `node-collector-values.yaml` file:

```shell
touch node-collector-values.yaml
```

{% alert level="info" %}
Unspecified parameters use defaults from [values.yaml](https://github.com/open-telemetry/opentelemetry-helm-charts/blob/main/charts/opentelemetry-collector/values.yaml).
{% /alert %}
Choose the daemonset mode and use DDOT as the collector:
In the `node-collector-values.yaml` file:

```yaml
mode: daemonset
image:
  repository: datadog/ddot-collector
  tag: 7.80.4
ports:
  jaeger-compact:
    enabled: false
  jaeger-grpc:
    enabled: false
  jaeger-thrift:
    enabled: false
  zipkin:
    enabled: false
# Can be removed from 7.82.0 onwards
command:
  name: opt/datadog-agent/embedded/bin/otel-agent
```

{% callout %}
# Important note for users on the following Datadog sites: app.ddog-gov.com, us2.ddog-gov.com



{% alert level="info" %}
For FED, set `tag: 7.80.4-fips` to use the FIPS-compliant DDOT image. See [FIPS compliance](https://docs.datadoghq.com/agent/configuration/fips-compliance.md).
{% /alert %}


{% /callout %}

{% alert level="info" %}
The Collector Helm chart publishes the OTLP ports on each node by default (`hostPort: 4317` for gRPC and `hostPort: 4318` for HTTP), so application pods can reach the Collector instance running on the same node. See Configure the application.
{% /alert %}
Configure the Datadog exporter and API key secret:
In the `node-collector-values.yaml` file:

```yaml
config:
  exporters:
    datadog:
      api:
        key: ${env:DD_API_KEY}
        site: ${env:DD_SITE}
      sending_queue:
        batch:
          flush_timeout: 10s
extraEnvs:
  - name: DD_API_KEY
    valueFrom:
      secretKeyRef:
        key: api-key
        name: datadog-apikey
  - name: DD_SITE
    valueFrom:
      secretKeyRef:
        key: site
        name: datadog-apikey
  - name: DD_OTELCOLLECTOR_CONVERTER_FEATURES
    value: datadog,pprof,zpages,prometheus,infraattributes
  - name: K8S_CLUSTER_NAME
    value: <CLUSTER_NAME>
    # vvv Will no longer be necessary from 7.83.0 onwards vvv
  - name: DD_OTEL_STANDALONE
    value: 'true'
    # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    # vvv Will no longer be necessary from 7.82.0 onwards vvv
  - name: DD_OTELCOLLECTOR_ENABLED
    value: 'true'
    # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

Replace `<CLUSTER_NAME>` with a name for your cluster.
Enable presets:
In the `node-collector-values.yaml` file:

```yaml
presets:
  hostMetrics:
    enabled: true
  kubeletMetrics:
    enabled: true
  logsCollection:
    enabled: true
    includeCollectorLogs: false
```
Define pipelines for desired signals, with an OTLP receiver:
In the `node-collector-values.yaml` file:

```yaml
config:
  # [...]
  receivers:
    otlp:
      protocols:
        grpc:
          endpoint: 0.0.0.0:4317
        http:
          endpoint: 0.0.0.0:4318
  service:
    pipelines:
      logs:
        receivers: ['otlp']
        exporters: ['datadog']
      metrics:
        receivers: ['otlp']
        exporters: ['datadog']
      traces:
        receivers: ['otlp']
        exporters: ['datadog']
    telemetry:
      resource:
        k8s.cluster.name: ${env:K8S_CLUSTER_NAME}
```
(Optional) Enable additional Datadog features:
{% alert level="warning" %}
Enabling these features may incur additional charges. Review the [pricing page](https://www.datadoghq.com/pricing/) and talk to your Customer Success Manager before proceeding.
{% /alert %}

In the `node-collector-values.yaml` file:

```yaml
config:
  # [...]
  processors:
    infraattributes:
      cardinality: 2
    resource/add-cluster-name:
      attributes:
        - key: k8s.cluster.name
          value: ${env:K8S_CLUSTER_NAME}
          action: upsert
  connectors:
    datadog/connector:
      traces:
        compute_top_level_by_span_kind: true
        peer_tags_aggregation: true
        compute_stats_by_span_kind: true
  service:
    pipelines:
      logs:
	    # [...]
        processors: ['resource/add-cluster-name', 'infraattributes']
      metrics:
        receivers: ['otlp', 'datadog/connector']
        processors: ['resource/add-cluster-name', 'infraattributes']
	    # [...]
      traces:
	    # [...]
        processors: ['resource/add-cluster-name', 'infraattributes']
        exporters: ['datadog', 'datadog/connector']
```

{% collapsible-section %}
Completed node-collector-values.yaml file
Your `node-collector-values.yaml` file should look something like this:

In the `node-collector-values.yaml` file:

```yaml
mode: daemonset
# vvv To be removed from 7.82.0 onwards vvv
command:
  name: opt/datadog-agent/embedded/bin/otel-agent
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
image:
  repository: datadog/ddot-collector
  tag: 7.80.4
presets:
  hostMetrics: # Add an hostmetrics receiver to the metrics pipeline
    enabled: true
  kubeletMetrics: # Add a kubeletstats receiver to the metrics pipeline
    enabled: true
  logsCollection: # Add a filelog receiver to the logs pipeline
    enabled: true
    includeCollectorLogs: false
config:
  connectors:
    datadog/connector:
      traces:
        compute_top_level_by_span_kind: true
        peer_tags_aggregation: true
        compute_stats_by_span_kind: true
  exporters:
    datadog:
      api:
        key: ${env:DD_API_KEY}
        site: ${env:DD_SITE}
      sending_queue:
        batch:
          flush_timeout: 10s
  processors:
    infraattributes:
      cardinality: 2
    resource/add-cluster-name:
      attributes:
        - key: k8s.cluster.name
          value: ${env:K8S_CLUSTER_NAME}
          action: upsert
  receivers:
    otlp:
      protocols:
        grpc:
          endpoint: 0.0.0.0:4317
        http:
          endpoint: 0.0.0.0:4318
  service:
    extensions:
      - health_check
    pipelines:
      logs:
        receivers:
          - otlp
        processors:
          - resource/add-cluster-name
          - infraattributes
        exporters:
          - datadog
      metrics:
        receivers:
          - otlp
          - datadog/connector
        processors:
          - resource/add-cluster-name
          - infraattributes
        exporters:
          - datadog
      traces:
        receivers:
          - otlp
        processors:
          - resource/add-cluster-name
          - infraattributes
        exporters:
          - datadog
          - datadog/connector
    telemetry:
      resource:
        k8s.cluster.name: ${env:K8S_CLUSTER_NAME}
extraEnvs:
  - name: DD_API_KEY
    valueFrom:
      secretKeyRef:
        key: api-key
        name: datadog-apikey
  - name: DD_SITE
    valueFrom:
      secretKeyRef:
        key: site
        name: datadog-apikey
  - name: DD_OTELCOLLECTOR_CONVERTER_FEATURES
    value: datadog,pprof,zpages,prometheus,infraattributes
  - name: K8S_CLUSTER_NAME
    value: <CLUSTER_NAME>
    # vvv Will no longer be necessary from 7.83.0 onwards vvv
  - name: DD_OTEL_STANDALONE
    value: 'true'
    # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    # vvv Will no longer be necessary from 7.82.0 onwards vvv
  - name: DD_OTELCOLLECTOR_ENABLED
    value: 'true'
    # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ports:
  jaeger-compact:
    enabled: false
  jaeger-grpc:
    enabled: false
  jaeger-thrift:
    enabled: false
  zipkin:
    enabled: false
```

{% /collapsible-section %}

{% /tab %}

### Deploy the Collector{% #deploy-the-collector %}

{% tab title="Operator" %}
Apply the `node-collector.yaml` file to create the `OpenTelemetryCollector` resource. The Operator deploys the Collector as a DaemonSet, running one instance per node:

```shell
kubectl apply -f node-collector.yaml
```

{% /tab %}

{% tab title="Helm" %}
Install the OpenTelemetry Collector chart with your values file:

```shell
helm install node-collector open-telemetry/opentelemetry-collector -f node-collector-values.yaml
```

To apply later changes, run `helm upgrade node-collector open-telemetry/opentelemetry-collector -f node-collector-values.yaml`.
{% /tab %}

## Send your telemetry to Datadog{% #send-your-telemetry-to-datadog %}

To send your telemetry data to Datadog:

1. Instrument your application
1. Configure the application
1. Correlate observability data
1. Run your application

### Instrument the application{% #instrument-the-application %}

Instrument your application [using the OpenTelemetry API](https://docs.datadoghq.com/tracing/trace_collection/custom_instrumentation/otel_instrumentation.md).

{% collapsible-section %}
Example application instrumented with the OpenTelemetry API
As an example, you can use the [Calendar sample application](https://github.com/DataDog/opentelemetry-examples/tree/main/apps/rest-services/java/calendar) that's already instrumented for you. The following code instruments the [CalendarService.getDate()](https://github.com/DataDog/opentelemetry-examples/blob/main/apps/rest-services/java/calendar/src/main/java/com/otel/service/CalendarService.java#L27-L48) method using the OpenTelemetry annotations and API:

In the `CalendarService.java` file:

```java
@WithSpan(kind = SpanKind.CLIENT)
public String getDate() {
    Span span = Span.current();
    span.setAttribute("peer.service", "random-date-service");
    ...
}
```

{% /collapsible-section %}

### Configure the application{% #configure-the-application %}

Your application container must send data to the DDOT Collector running on the same node. Because the Collector publishes the OTLP ports on the node with `hostPort`, the application can reach the local Collector through the node's IP address (`status.hostIP`).

If the `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable is not already set, add it to your application's Deployment manifest file:

In the `deployment.yaml` file:

```yaml
env:
  ...
  - name: HOST_IP
    valueFrom:
     fieldRef:
        fieldPath: status.hostIP
  - name: OTLP_GRPC_PORT
    value: "4317"
  - name: OTEL_EXPORTER_OTLP_ENDPOINT
    value: 'http://$(HOST_IP):$(OTLP_GRPC_PORT)'
  - name: OTEL_EXPORTER_OTLP_PROTOCOL
    value: 'grpc'
   
```



### Correlate observability data{% #correlate-observability-data %}

[Unified service tagging](https://docs.datadoghq.com/getting_started/tagging/unified_service_tagging.md) ties observability data together in Datadog so you can navigate across metrics, traces, and logs with consistent tags.

In containerized environments, set `env`, `service`, and `version` using OpenTelemetry Resource Attributes environment variables. The DDOT Collector detects this tagging configuration and applies it to the data it collects from containers.

Add the following environment variables to your application's deployment manifest:

In the `deployment.yaml` file:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: <SERVICE>
spec:
  template:
    spec:
      containers:
      - name: <SERVICE>
        env:
          - name: OTEL_SERVICE_NAME
            value: "<SERVICE>"
          - name: OTEL_RESOURCE_ATTRIBUTES
            value: "service.version=<VERSION>,deployment.environment.name=<ENV>"
```

### Run the application{% #run-the-application %}

Redeploy your application to apply the changes made in the deployment manifest. After the updated configuration is active, Unified Service Tagging is fully enabled for your metrics, traces, and logs.

## Explore observability data in Datadog{% #explore-observability-data-in-datadog %}

Use Datadog to explore the observability data for your application.

### Fleet automation{% #fleet-automation %}

Explore your Collector configuration.

{% image
   source="https://docs.dd-static.net/images/opentelemetry/embedded_collector/fleet_automation.baf78a14f2401833d04f1b19c38ddcf4.png?auto=format&fit=max&w=850 1x, https://docs.dd-static.net/images/opentelemetry/embedded_collector/fleet_automation.baf78a14f2401833d04f1b19c38ddcf4.png?auto=format&fit=max&w=850&dpr=2 2x"
   alt="Review your Collector configuration from the Fleet Automation page." /%}

### Live container monitoring{% #live-container-monitoring %}

Monitor your container health using Live Container Monitoring capabilities.

{% image
   source="https://docs.dd-static.net/images/opentelemetry/embedded_collector/containers.14b4025c2f3b0e554692286e4a01f383.png?auto=format&fit=max&w=850 1x, https://docs.dd-static.net/images/opentelemetry/embedded_collector/containers.14b4025c2f3b0e554692286e4a01f383.png?auto=format&fit=max&w=850&dpr=2 2x"
   alt="Monitor your container health from the Containers page." /%}

### Infrastructure node health{% #infrastructure-node-health %}

View runtime and infrastructure metrics to visualize, monitor, and measure the performance of your nodes.

{% image
   source="https://docs.dd-static.net/images/opentelemetry/embedded_collector/infrastructure.c8fe3b51603bf26daef58b0c3fbdbb6d.png?auto=format&fit=max&w=850 1x, https://docs.dd-static.net/images/opentelemetry/embedded_collector/infrastructure.c8fe3b51603bf26daef58b0c3fbdbb6d.png?auto=format&fit=max&w=850&dpr=2 2x"
   alt="View runtime and infrastructure metrics from the Host List." /%}

### Logs{% #logs %}

View logs to monitor and troubleshoot application and system operations.

{% image
   source="https://docs.dd-static.net/images/opentelemetry/embedded_collector/logs.3399501b14c5a2c7bf9ab8dd4aa8bf52.png?auto=format&fit=max&w=850 1x, https://docs.dd-static.net/images/opentelemetry/embedded_collector/logs.3399501b14c5a2c7bf9ab8dd4aa8bf52.png?auto=format&fit=max&w=850&dpr=2 2x"
   alt="View logs from the Log Explorer." /%}

### Traces{% #traces %}

View traces and spans to observe the status and performance of requests processed by your application, with infrastructure metrics correlated in the same trace.

{% image
   source="https://docs.dd-static.net/images/opentelemetry/embedded_collector/traces.0dfe8b50575dbfcea5b0d06131826db9.png?auto=format&fit=max&w=850 1x, https://docs.dd-static.net/images/opentelemetry/embedded_collector/traces.0dfe8b50575dbfcea5b0d06131826db9.png?auto=format&fit=max&w=850&dpr=2 2x"
   alt="View traces from the Trace Explorer." /%}

### Runtime metrics{% #runtime-metrics %}

Monitor your runtime (JVM) metrics for your applications.

{% image
   source="https://docs.dd-static.net/images/opentelemetry/embedded_collector/metrics.1f91a119276f91ecfb2976f16eed58ef.png?auto=format&fit=max&w=850 1x, https://docs.dd-static.net/images/opentelemetry/embedded_collector/metrics.1f91a119276f91ecfb2976f16eed58ef.png?auto=format&fit=max&w=850&dpr=2 2x"
   alt="View JVM metrics from the JVM Metrics dashboard" /%}

### Collector health metrics{% #collector-health-metrics %}

View metrics from the DDOT Collector to monitor the Collector health.

{% image
   source="https://docs.dd-static.net/images/opentelemetry/embedded_collector/dashboard.f6e65b6b9a8708b1a7e172da215947af.png?auto=format&fit=max&w=850 1x, https://docs.dd-static.net/images/opentelemetry/embedded_collector/dashboard.f6e65b6b9a8708b1a7e172da215947af.png?auto=format&fit=max&w=850&dpr=2 2x"
   alt="View Collector health metrics from the OTel dashboard." /%}

## Further reading{% #further-reading %}

Additional helpful documentation, links, and articles:

- [Use Custom OpenTelemetry Components in DDOT](https://docs.datadoghq.com/opentelemetry/setup/ddot_collector/custom_components.md)
