> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bronto.io/llms.txt
> Use this file to discover all available pages before exploring further.

# AWS Distribution for OpenTelemetry (ADOT)

> Send application logs, metrics, and traces from Amazon ECS, EKS, or EC2 to Bronto with AWS Distro for OpenTelemetry (ADOT), avoiding CloudWatch fees.

## When to Use ADOT

ADOT is a good fit when you are running containerised workloads on ECS or EKS and want to:

* Send application **logs, metrics, and traces** to Bronto through one Collector
* Avoid CloudWatch log ingestion fees entirely
* Use an AWS-supported, pre-built distribution of the OpenTelemetry Collector without managing it yourself

If you need full control over collector configuration — custom processors, fan-out to multiple backends, or advanced transformation — consider the [Self-Managed OTel Collector](./aws-custom-otel) instead.

***

## Supported AWS Services

ADOT collects application logs, metrics, and traces from containerised workloads on:

| Service                      | Data types                                        |
| ---------------------------- | ------------------------------------------------- |
| Amazon ECS (EC2 launch type) | Application logs, metrics, and traces (sidecar)   |
| AWS Fargate (ECS)            | Application logs, metrics, and traces (sidecar)   |
| Amazon EKS (EC2 node groups) | Application logs, metrics, and traces (DaemonSet) |
| Amazon EKS (Fargate)         | Application logs, metrics, and traces (sidecar)   |

For Lambda traces, use the [ADOT Lambda Layer](./aws-adot-lambda). For non-containerised AWS services, see the [overview](./aws-overview).

<Note>
  ADOT forwards the telemetry your workload sends it — it does not automatically discover application telemetry. Instrument your app with the [OpenTelemetry SDK](/opentelemetry/overview) so it exports logs, metrics, and traces to the ADOT sidecar or DaemonSet.
</Note>

***

## What is ADOT?

The [AWS Distribution for OpenTelemetry](https://aws-otel.github.io/) (ADOT) is an AWS-supported build of the OpenTelemetry Collector. It is available as a Docker image and can be deployed as a sidecar container (ECS) or a daemonset (EKS). It collects logs, metrics, and traces from your application via OTLP and forwards them to any OTLP-compatible backend — including Bronto.

ADOT itself is free. You pay only for the compute running the container.

***

## Bronto Ingestion Endpoints

| Signal  | EU Region                                   | US Region                                   |
| ------- | ------------------------------------------- | ------------------------------------------- |
| Logs    | `https://ingestion.eu.bronto.io/v1/logs`    | `https://ingestion.us.bronto.io/v1/logs`    |
| Metrics | `https://ingestion.eu.bronto.io/v1/metrics` | `https://ingestion.us.bronto.io/v1/metrics` |
| Traces  | `https://ingestion.eu.bronto.io/v1/traces`  | `https://ingestion.us.bronto.io/v1/traces`  |

<Note>
  The `/v1/logs`, `/v1/metrics`, and `/v1/traces` endpoints accept **OTLP protobuf only**.
</Note>

All requests require the header:

```
x-bronto-api-key: <YOUR_API_KEY>
```

See [API Keys](/Account-Management/API-Keys) for how to generate a key.

***

## Setup on ECS (Sidecar)

Add the ADOT container as a sidecar to your ECS task definition. The typical local defaults are `localhost:4317` for OTLP/gRPC and `localhost:4318` for OTLP/HTTP. Use the receiver address, protocol, and TLS settings configured for your task when they differ; the sidecar then forwards the telemetry to Bronto.

### ADOT Collector Configuration

Create a collector config file and make it available to the container (via S3, SSM Parameter Store, or a custom image).

```yaml theme={"dark"}
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

processors:
  batch:

exporters:
  otlphttp/bronto:
    logs_endpoint: "https://ingestion.<REGION>.bronto.io/v1/logs"
    metrics_endpoint: "https://ingestion.<REGION>.bronto.io/v1/metrics"
    traces_endpoint: "https://ingestion.<REGION>.bronto.io/v1/traces"
    compression: none
    headers:
      x-bronto-api-key: ${env:BRONTO_API_KEY}

service:
  pipelines:
    logs:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlphttp/bronto]
    metrics:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlphttp/bronto]
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlphttp/bronto]
```

Replace `<REGION>` with `eu` or `us`. In production, do not bake the API key into the YAML. Inject it into the container from AWS Secrets Manager as `BRONTO_API_KEY`, then use `${env:BRONTO_API_KEY}` as the header value. ADOT also accepts the complete configuration through `AOT_CONFIG_CONTENT`, which can be populated from a protected SSM parameter at deployment time.

<Warning>
  ADOT does not include every upstream Collector component. In particular, its standard image does not include the `transform` processor. For simple GenAI compatibility rewrites—such as copying or renaming legacy `gen_ai.system` to `gen_ai.provider.name`—use the `attributes` processor, or choose the upstream Collector distribution after verifying its component manifest.
</Warning>

### ECS Task Definition (sidecar container)

```json theme={"dark"}
{
  "name": "adot-collector",
  "image": "public.ecr.aws/aws-observability/aws-otel-collector:latest",
  "essential": false,
  "command": ["--config", "/etc/otel/config.yaml"],
  "portMappings": [
    { "containerPort": 4317, "protocol": "tcp" },
    { "containerPort": 4318, "protocol": "tcp" }
  ]
}
```

In a multi-container task, add a container dependency so the application starts only after the Collector is healthy. Grant the **task role** (not only the execution role) any permissions the application needs for Bedrock, and grant the execution role access to the Secrets Manager/SSM values injected into the task definition.

With the receiver configuration above, an application sharing the task network can normally export to `http://localhost:4317` over gRPC or `http://localhost:4318` over HTTP. The exact host, port, protocol, and TLS settings depend on the task's network mode and your Collector configuration.

***

## Setup on EKS (DaemonSet)

Deploy ADOT as a DaemonSet so one collector pod runs per node. Application pods export telemetry to the node's collector via the node IP or a local service.

```yaml theme={"dark"}
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: adot-collector
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: adot-collector
  template:
    metadata:
      labels:
        app: adot-collector
    spec:
      containers:
        - name: adot-collector
          image: public.ecr.aws/aws-observability/aws-otel-collector:latest
          args: ["--config", "/etc/otel/config.yaml"]
          volumeMounts:
            - name: otel-config
              mountPath: /etc/otel
      volumes:
        - name: otel-config
          configMap:
            name: adot-config
```

Store the collector configuration above in a `ConfigMap` named `adot-config`.

***

## Data Organization

ADOT uses OpenTelemetry resource attributes for routing. Bronto maps `service.name` to a **Dataset** and `service.namespace` to a **Collection** — see [Data Organization](/Search-and-Visualize/Partitions) for how datasets, collections, and tags work.

Set these in the `resource` block of your collector config:

```yaml theme={"dark"}
processors:
  resource:
    attributes:
      - key: service.name
        value: <YOUR_DATASET_NAME>
        action: upsert
      - key: service.namespace
        value: <YOUR_COLLECTION_NAME>
        action: upsert
```

You can also override routing per-exporter using HTTP headers, which is useful when one collector ships to multiple datasets:

| Header                | Description                              |
| --------------------- | ---------------------------------------- |
| `x-bronto-dataset`    | Overrides `service.name`                 |
| `x-bronto-collection` | Overrides `service.namespace`            |
| `x-bronto-tags`       | Comma-separated tags to attach to events |

```yaml theme={"dark"}
exporters:
  otlphttp/bronto:
    logs_endpoint: https://ingestion.<REGION>.bronto.io/v1/logs
    headers:
      x-bronto-api-key: <YOUR_API_KEY>
      x-bronto-dataset: <YOUR_DATASET_NAME>
      x-bronto-collection: <YOUR_COLLECTION_NAME>
      x-bronto-tags: env=prod,team=platform
```

***

## Cost Notes

* **No CloudWatch ingestion fees** — logs, metrics, and traces go directly from ADOT to Bronto over OTLP/HTTP.
* **Compute cost only** — you pay for the ECS task or EKS pod running the collector, which is typically small relative to CloudWatch PUT and ingestion charges at scale.
* Compare with the [CloudWatch Log Forwarder](./aws-client-cloudwatch) if your services already write to CloudWatch and the migration cost outweighs the savings.

***

For assistance, contact [support@bronto.io](mailto:support@bronto.io).
