---
title: "Collect OpenTelemetry data and forward to Grafana | Grafana Alloy documentation"
description: "Learn how to collect OpenTelemetry data and forward it to the Grafana stack"
---

# Collect OpenTelemetry data and forward to Grafana

You can configure Alloy to collect [OpenTelemetry](https://opentelemetry.io)-compatible data and forward it to the Grafana stack.

This topic describes how to:

- Configure Alloy to send your data to Loki.
- Configure Alloy to send your data to Tempo.
- Configure Alloy to send your data to Mimir or Prometheus Remote Write.

## Components used in this topic

- [`loki.write`](../../reference/components/loki/loki.write/)
- [`otelcol.auth.basic`](../../reference/components/otelcol/otelcol.auth.basic/)
- [`otelcol.exporter.loki`](../../reference/components/otelcol/otelcol.exporter.loki/)
- [`otelcol.exporter.otlp`](../../reference/components/otelcol/otelcol.exporter.otlp/)
- [`otelcol.exporter.otlphttp`](../../reference/components/otelcol/otelcol.exporter.otlphttp/)
- [`otelcol.exporter.prometheus`](../../reference/components/otelcol/otelcol.exporter.prometheus/)
- [`otelcol.processor.batch`](../../reference/components/otelcol/otelcol.processor.batch/)
- [`otelcol.processor.memory_limiter`](../../reference/components/otelcol/otelcol.processor.memory_limiter/)
- [`otelcol.receiver.otlp`](../../reference/components/otelcol/otelcol.receiver.otlp/)
- [`prometheus.remote_write`](../../reference/components/prometheus/prometheus.remote_write/)

## Before you begin

- Ensure that you have basic familiarity with instrumenting applications with OpenTelemetry.
- Have a set of OpenTelemetry applications ready to push telemetry data to Alloy.
- Identify where Alloy writes received telemetry data.
- Be familiar with the concept of [Components](../../get-started/components/) in Alloy.
- Complete the [Collect open telemetry data](../opentelemetry-data/) task.

## The pipeline

You can start with the Alloy configuration you created in the [Collect open telemetry data](../opentelemetry-data/) task.

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
otelcol.receiver.otlp "example" {
  grpc {
    endpoint = "127.0.0.1:4317"
  }

  http {
    endpoint = "127.0.0.1:4318"
  }

  output {
    metrics = [otelcol.processor.batch.example.input]
    logs    = [otelcol.processor.batch.example.input]
    traces  = [otelcol.processor.batch.example.input]
  }
}

otelcol.processor.batch "example" {
  output {
    metrics = [otelcol.exporter.otlp.default.input]
    logs    = [otelcol.exporter.otlp.default.input]
    traces  = [otelcol.exporter.otlp.default.input]
  }
}

otelcol.exporter.otlp "default" {
  client {
    endpoint = "my-otlp-grpc-server:4317"
  }
}
```

The pipeline looks like this:

plaintext ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```plaintext
Metrics, Logs, Traces: OTLP Receiver → Batch Processor → OTLP HTTP Exporter
```

## Grafana Cloud

Grafana Cloud provides OTLP Endpoints that you can use directly from within Alloy.

You can find the OTLP connection details from the OpenTelemetry **Details** page in the [Grafana Cloud Portal](/docs/grafana-cloud/account-management/cloud-portal/#your-grafana-cloud-stack).

You must update the configuration file as follows:

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
otelcol.auth.basic "default" {
  username = "<ACCOUNT ID>"
  password = "<API TOKEN>"
}

otelcol.exporter.otlphttp "default" {
  client {
    endpoint = "<OTLP_ENDPOINT>"
    auth     = otelcol.auth.basic.default.handler
  }
}
```

Replace the following:

- *`<ACCOUNT ID>`* : Your Grafana Cloud account ID.
- *`<API TOKEN>`* : Your Grafana Cloud API token.
- *`<OTLP_ENDPOINT>`* : Your OTLP endpoint.

This configuration uses the credentials stored in `otelcol.auth.basic "default"` to authenticate against the Grafana Cloud OTLP endpoints, and you should start to see your data arrive.

> Note
> 
> For Grafana Cloud, use `otelcol.exporter.otlphttp` which sends data over HTTP/HTTPS. Use `otelcol.exporter.otlp` for gRPC endpoints when working with other platforms.

## Other platforms: Grafana Enterprise and Grafana Open Source

You can implement the following pipelines to send your data to Loki, Tempo, and Mimir or Prometheus.

plaintext ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```plaintext
Metrics: OTLP Receiver → Batch Processor → Prometheus Exporter → Prometheus Remote Write
Logs: OTLP Receiver → Batch Processor → Loki Exporter → Loki Write  
Traces: OTLP Receiver → Batch Processor → OTLP Exporter (gRPC/HTTP)
```

### Grafana Loki

[Grafana Loki](/oss/loki/) is a horizontally scalable, highly available, multi-tenant log aggregation system inspired by Prometheus. Similar to Prometheus, to send from OTLP to Loki, you can configure pass-through from the [`otelcol.exporter.loki`](../../reference/components/otelcol/otelcol.exporter.loki/) component to [`loki.write`](../../reference/components/loki/loki.write/) component.

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
otelcol.exporter.loki "default" {
  forward_to = [loki.write.default.receiver]
}

loki.write "default" {
  endpoint {
    url = "http://loki-endpoint:8080/loki/api/v1/push"
        }
}
```

To use Loki with basic-auth, which Grafana Cloud Logs requires, you must configure the [`loki.write`](../../reference/components/loki/loki.write/) component. You can get the Loki configuration from the Loki **Details** page in the [Grafana Cloud Portal](/docs/grafana-cloud/account-management/cloud-portal/#your-grafana-cloud-stack).

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
otelcol.exporter.loki "grafana_cloud_logs" {
  forward_to = [loki.write.grafana_cloud_logs.receiver]
}

loki.write "grafana_cloud_logs" {
  endpoint {
    url = "https://logs-prod-us-central1.grafana.net/loki/api/v1/push"

    basic_auth {
      username = "5252"
      password = sys.env("GRAFANA_CLOUD_API_KEY")
    }
  }
}
```

### Grafana Tempo

[Grafana Tempo](/oss/tempo/) is an open source, scalable distributed tracing backend. Tempo can ingest OTLP directly, and you can use the OTLP exporter to send the traces to Tempo.

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
otelcol.exporter.otlp "default" {
  client {
    endpoint = "tempo-server:4317"
  }
}
```

To use Tempo with basic-auth, which Grafana Cloud Traces requires, you must use the [otelcol.auth.basic](../../reference/components/otelcol/otelcol.auth.basic/) component. You can get the Tempo configuration from the Tempo **Details** page in the [Grafana Cloud Portal](/docs/grafana-cloud/account-management/cloud-portal/#your-grafana-cloud-stack).

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
otelcol.exporter.otlphttp "grafana_cloud_traces" {
  client {
    endpoint = "https://tempo-us-central1.grafana.net:443"
    auth     = otelcol.auth.basic.grafana_cloud_traces.handler
  }
}

otelcol.auth.basic "grafana_cloud_traces" {
  username = "4094"
  password = sys.env("GRAFANA_CLOUD_API_KEY")
}
```

### Grafana Mimir or Prometheus Remote Write

[Prometheus Remote Write](https://prometheus.io/docs/operating/integrations/#remote-endpoints-and-storage) is a popular metrics transmission protocol supported by most metrics systems, including [Grafana Mimir](/oss/mimir/) and Grafana Cloud. To send from OTLP to a Prometheus compatible `remote_write` endpoint, you can configure pass-through from the [`otelcol.exporter.prometheus`](../../reference/components/otelcol/otelcol.exporter.prometheus/) to the [`prometheus.remote_write`](../../reference/components/prometheus/prometheus.remote_write/) component. The Prometheus remote write component in Alloy is a robust protocol implementation, including a Write Ahead Log (WAL) for resiliency.

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
otelcol.exporter.prometheus "default" {
  forward_to = [prometheus.remote_write.default.receiver]
}

prometheus.remote_write "default" {
  endpoint {
    url = "http://prometheus:9090/api/v1/write"
  }
}
```

To use Prometheus with basic-auth, which Grafana Cloud Metrics requires, you must configure the [`prometheus.remote_write`](../../reference/components/prometheus/prometheus.remote_write/) component. You can get the Prometheus configuration from the Prometheus **Details** page in the [Grafana Cloud Portal](/docs/grafana-cloud/account-management/cloud-portal/#your-grafana-cloud-stack).

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
otelcol.exporter.prometheus "grafana_cloud_metrics" {
        forward_to = [prometheus.remote_write.grafana_cloud_metrics.receiver]
    }

prometheus.remote_write "grafana_cloud_metrics" {
    endpoint {
        url = "https://prometheus-us-central1.grafana.net/api/prom/push"

        basic_auth {
            username = "12690"
            password = sys.env("GRAFANA_CLOUD_API_KEY")
        }
    }
}
```

### Put it all together

Instead of referencing `otelcol.exporter.otlp.default.input` in the output of `otelcol.processor.batch`, you need to reference the three exporters you set up. For Grafana Cloud, use `otelcol.exporter.otlphttp` for traces to send data over HTTPS. The final configuration becomes:

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
otelcol.receiver.otlp "example" {
  grpc {
    endpoint = "127.0.0.1:4317"
  }

  http {
    endpoint = "127.0.0.1:4318"
  }

  output {
    metrics = [otelcol.processor.batch.example.input]
    logs    = [otelcol.processor.batch.example.input]
    traces  = [otelcol.processor.batch.example.input]
  }
}

otelcol.processor.batch "example" {
  output {
    metrics = [otelcol.exporter.prometheus.grafana_cloud_metrics.input]
    logs    = [otelcol.exporter.loki.grafana_cloud_logs.input]
    traces  = [otelcol.exporter.otlphttp.grafana_cloud_traces.input]
  }
}

otelcol.exporter.otlphttp "grafana_cloud_traces" {
  client {
    endpoint = "https://tempo-us-central1.grafana.net:443"
    auth     = otelcol.auth.basic.grafana_cloud_traces.handler
  }
}

otelcol.auth.basic "grafana_cloud_traces" {
  username = "4094"
  password = sys.env("GRAFANA_CLOUD_API_KEY")
}

otelcol.exporter.prometheus "grafana_cloud_metrics" {
        forward_to = [prometheus.remote_write.grafana_cloud_metrics.receiver]
    }

prometheus.remote_write "grafana_cloud_metrics" {
    endpoint {
        url = "https://prometheus-us-central1.grafana.net/api/prom/push"

        basic_auth {
            username = "12690"
            password = sys.env("GRAFANA_CLOUD_API_KEY")
        }
    }
}

otelcol.exporter.loki "grafana_cloud_logs" {
  forward_to = [loki.write.grafana_cloud_logs.receiver]
}

loki.write "grafana_cloud_logs" {
  endpoint {
    url = "https://logs-prod-us-central1.grafana.net/loki/api/v1/push"

    basic_auth {
      username = "5252"
      password = sys.env("GRAFANA_CLOUD_API_KEY")
    }
  }
}
```

Running Alloy gives you the following:

plaintext ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```plaintext
./alloy run alloy-config.alloy
./alloy run alloy-config.alloy
ts=2023-05-09T09:37:15.300959Z level=info msg="running usage stats reporter"
ts=2023-05-09T09:37:15.300958Z level=info msg="now listening for http traffic" addr=127.0.0.1:12345
ts=2023-05-09T09:37:15.301104Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg="starting complete graph evaluation"
ts=2023-05-09T09:37:15.301307Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg="finished node evaluation" node_id=loki.write.grafana_cloud_logs duration=188.209µs
ts=2023-05-09T09:37:15.301334Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg="finished node evaluation" node_id=otelcol.exporter.loki.grafana_cloud_logs duration=18.791µs
ts=2023-05-09T09:37:15.303138Z component=prometheus.remote_write.grafana_cloud_metrics level=info subcomponent=wal msg="replaying WAL, this may take a while" dir=data-alloy/prometheus.remote_write.grafana_cloud_metrics/wal
ts=2023-05-09T09:37:15.303257Z component=prometheus.remote_write.grafana_cloud_metrics level=info subcomponent=wal msg="WAL segment loaded" segment=0 maxSegment=1
ts=2023-05-09T09:37:15.303302Z component=prometheus.remote_write.grafana_cloud_metrics level=info subcomponent=wal msg="WAL segment loaded" segment=1 maxSegment=1
ts=2023-05-09T09:37:15.303507Z component=prometheus.remote_write.grafana_cloud_metrics subcomponent=rw level=info remote_name=7f623a url=https://prometheus-us-central1.grafana.net/api/prom/push msg="Starting WAL watcher" queue=7f623a
ts=2023-05-09T09:37:15.303515Z component=prometheus.remote_write.grafana_cloud_metrics subcomponent=rw level=info remote_name=7f623a url=https://prometheus-us-central1.grafana.net/api/prom/push msg="Starting scraped metadata watcher"
ts=2023-05-09T09:37:15.303522Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg="finished node evaluation" node_id=prometheus.remote_write.grafana_cloud_metrics duration=2.181958ms
ts=2023-05-09T09:37:15.303557Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg="finished node evaluation" node_id=otelcol.exporter.prometheus.grafana_cloud_metrics duration=30.083µs
ts=2023-05-09T09:37:15.303611Z component=prometheus.remote_write.grafana_cloud_metrics subcomponent=rw level=info remote_name=7f623a url=https://prometheus-us-central1.grafana.net/api/prom/push msg="Replaying WAL" queue=7f623a
ts=2023-05-09T09:37:15.303618Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg="finished node evaluation" node_id=otelcol.auth.basic.grafana_cloud_traces duration=52.5µs
ts=2023-05-09T09:37:15.303694Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg="finished node evaluation" node_id=otelcol.exporter.otlphttp.grafana_cloud_traces duration=70.375µs
ts=2023-05-09T09:37:15.303782Z component=otelcol.processor.memory_limiter.default level=info msg="Memory limiter configured" limit_mib=150 spike_limit_mib=30 check_interval=1s
ts=2023-05-09T09:37:15.303802Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg="finished node evaluation" node_id=otelcol.processor.memory_limiter.default duration=100.334µs
ts=2023-05-09T09:37:15.303853Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg="finished node evaluation" node_id=otelcol.processor.batch.default duration=44.75µs
ts=2023-05-09T09:37:15.303948Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg="finished node evaluation" node_id=otelcol.receiver.otlp.default duration=87.333µs
ts=2023-05-09T09:37:15.303968Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg="finished node evaluation" node_id=tracing duration=10.792µs
ts=2023-05-09T09:37:15.303981Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg="finished node evaluation" node_id=logging duration=9µs
ts=2023-05-09T09:37:15.303987Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg="finished complete graph evaluation" duration=2.960333ms
ts=2023-05-09T09:37:15.304Z level=info msg="scheduling loaded components"
ts=2023-05-09T09:37:15.304109Z component=otelcol.receiver.otlp.default level=info msg="Starting GRPC server" endpoint=0.0.0.0:4317
ts=2023-05-09T09:37:15.304234Z component=otelcol.receiver.otlp.default level=info msg="Starting HTTP server" endpoint=0.0.0.0:4318
```

You can check the pipeline graphically by visiting [http://localhost:12345/graph](http://localhost:12345/graph)

[](/media/docs/alloy/otlp-lgtm-graph.png)
