DocsAvoiding Datadog Host Billing with OpenTelemetry Collector

Introduction

Running the Datadog Agent on every node is convenient, but it also means host-based billing kicks in—even if you only need a handful of custom metrics. One way to cut those costs is to replace the Agent with the OpenTelemetry (OTel) Collector Contrib build and send your metrics through the Datadog exporter.

This guide walks through a minimal proof-of-concept on an EC2 instance using:

  1. The OTel Collector Contrib RPM package
  2. A collector config.yaml that adds EC2 metadata and forwards to Datadog
  3. A tiny Python app that emits OTLP metrics
  4. Validation inside the Datadog UI

Goal: Confirm that metrics reach Datadog without the Datadog Agent so you avoid host fees.


Prerequisites

  • EC2 instance (x86-64 or ARM64) with outbound internet or proxy access to us5.datadoghq.com
  • Datadog API key exported as DD_API_KEY
  • Root or sudo privileges
  • Python 3.10+ (only for the test app)

1. Install the OpenTelemetry Collector Contrib

# For x86-64 / AMD64
sudo yum install -y \
  https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.131.1/otelcol-contrib_0.131.1_linux_amd64.rpm
 
# For ARM64 (Graviton, Apple Silicon, etc.)
# sudo yum install -y \
#   https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.131.1/otelcol-contrib_0.131.1_linux_arm64.rpm

RPMs place the binary at /usr/bin/otelcol-contrib and create a systemd unit called otelcol-contrib.service.

2, Create config.yaml

Save the following to /etc/otelcol-contrib/config.yaml.

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

processors:
  resourcedetection/env:
    detectors: [env]

  resourcedetection/ec2:
    detectors: ["ec2"]
    ec2:
      tags: ["^.*$"]
      max_attempts: 5

  transform/remove_ec2_tag_prefix:
    error_mode: ignore
    metric_statements:
      - context: resource
        statements:
          - replace_all_patterns(resource.attributes, "key", "^ec2\\.tag\\.(.*)$", "$1")

  batch:
    send_batch_size: 10
    send_batch_max_size: 100
    timeout: 10s

exporters:
  datadog:
    api:
      site: us5.datadoghq.com
      key: ${env:DD_API_KEY}
    host_metadata:
      enabled: false
    metrics:
      resource_attributes_as_tags: true
      histograms:
        mode: distributions

extensions:
  health_check: {}
  pprof: {}
  zpages: {}

service:
  extensions: [health_check, pprof, zpages]
  pipelines:
    metrics:
      receivers:  [otlp]
      processors: [resourcedetection/env, resourcedetection/ec2, transform/remove_ec2_tag_prefix, batch]
      exporters:  [datadog]

resourcedetection/ec2 adds host.name, cloud.region, and EC2 tags so your metrics retain the same context you’re used to.

3. Start (and enable) the Collector

sudo /usr/bin/otelcol-contrib --config /etc/otelcol-contrib/config.yaml

# Or run permanently via systemd
sudo systemctl enable --now otelcol-contrib
sudo systemctl status otelcol-contrib

You should see a log line similar to:

Exporter datadog/exporter is starting with endpoint us5.datadoghq.com:443

4. Send a test metric from Python

Install the required libs:

python -m pip install "opentelemetry-sdk~=1.25" \
                       "opentelemetry-exporter-otlp~=1.25"

Create send_metric.py:

from opentelemetry import metrics
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader

EXPORTER = OTLPMetricExporter(endpoint="http://localhost:4317", insecure=True)
reader = PeriodicExportingMetricReader(EXPORTER, export_interval_millis=5000)

provider = MeterProvider(metric_readers=[reader])
metrics.set_meter_provider(provider)

meter = metrics.get_meter("demo.metric.sender")

counter = meter.create_counter(
    name="demo_custom_metric",
    unit="1",
    description="Custom metric sent via OTel"
)

# Add one data point
counter.add(1, {"env": "demo", "app": "cost-savings"})
print("Metric sent!")

You should see Metric sent! and the Collector logs should show an OTLP request followed by a Datadog export.

5. Verify in Datadog

Open Metrics Explorer.

Search for demo_custom_metric.

Set the graph to Sum per minute and choose the right time window.