LinkMesh

Search docs, blog and changelog

ENDE

Snippets · Destinations

Send to Grafana Cloud over OTLP

Grafana Cloud takes all three signals on one OTLP endpoint, authenticated with the stack's instance ID and an access token. The basicauth extension holds the credentials (from the environment) and the otlphttp exporter refers to it.

Signals
LogsMetricsTraces
Source
OTLP
Components
otlpbatchmemory_limiterotlphttp
Destination
Grafana Cloud

OpenTelemetry Collector

OpenTelemetry Collector YAML
extensions:
  basicauth/grafana-cloud:
    client_auth:
      username: ${env:GRAFANA_CLOUD_INSTANCE_ID}
      password: ${env:GRAFANA_CLOUD_API_TOKEN}


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

processors:
  memory_limiter:
    check_interval: 1s
    limit_percentage: 80
    spike_limit_percentage: 25
  batch:
    timeout: 5s

exporters:
  otlphttp/grafana-cloud:
    endpoint: https://otlp-gateway-prod-eu-west-2.grafana.net/otlp
    auth:
      authenticator: basicauth/grafana-cloud
    compression: gzip
    sending_queue:
      enabled: true
      queue_size: 5000
    retry_on_failure:
      enabled: true
      initial_interval: 5s
      max_interval: 30s
      max_elapsed_time: 300s

service:
  extensions: [basicauth/grafana-cloud]
  pipelines:
    logs:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [otlphttp/grafana-cloud]
    metrics:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [otlphttp/grafana-cloud]
    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [otlphttp/grafana-cloud]

LinkMesh

Library › Destinations › Grafana Cloud

OTLP Endpoint
https://otlp-gateway-prod-eu-west-2.grafana.net/otlp
Instance ID
<instance-id>
API Token
<access-policy-token>
Compression
gzip
Durable Delivery
true

What LinkMesh then pushes to the collector, under exporters:

Pushed to the collector
otlphttp/output_dst_00000502:
  compression: gzip
  endpoint: https://otlp-gateway-prod-eu-west-2.grafana.net/otlp
  headers:
    Authorization: Basic PGluc3RhbmNlLWlkPjo8YWNjZXNzLXBvbGljeS10b2tlbj4=
  sending_queue:
    block_on_overflow: false
    enabled: true
    storage: file_storage/output_dst_00000502

# extensions:
file_storage/output_dst_00000502:
  create_directory: true
  directory: /var/lib/otelcol-supervisor/sending-queue/output_dst_00000502

The same, as an API call (see automation recipes):

API call
curl -X POST "$LINKMESH/destinations" \
  -H "Authorization: Bearer $LMSAT" \
  -H "Content-Type: application/json" \
  -d '{
  "defaultConfig": {
    "api_token": "<access-policy-token>",
    "compression": "gzip",
    "durable_queue": true,
    "instance_id": "<instance-id>",
    "otlp_endpoint": "https://otlp-gateway-prod-eu-west-2.grafana.net/otlp"
  },
  "exporterType": "grafanacloud",
  "name": "Grafana Cloud",
  "signalTypes": [
    "logs",
    "metrics",
    "traces"
  ]
}'

The rest of the collector config above (otlp, memory_limiter, batch) is not part of this template: in LinkMesh those are separate sources, processors and destinations on the route.

Generated from LinkMesh's template catalogue by linkmesh-server snippet-render 1.464.3, not written by hand.

Download config.yamlValidated with otelcol-contrib v0.161.0 on 2026-10-26

Complete config files, each checked with the collector's own validate command (otelcol-contrib v0.161.0).

The gotcha

The authenticator must also be listed under service.extensions, and validate does not check that. In our test the config without it passed otelcol-contrib validate, then the collector exited at start with "failed to resolve authenticator \"basicauth/grafana-cloud\": authenticator not found".

Manage this across a fleet

LinkMesh manages collector configuration across a fleet from one self-hosted control plane, so a change like this is made once rather than host by host. The first 25 Collectors are free after a no-card registration in the OpenSight Customer Portal (5 without one).

Doing this in LinkMesh: Destinations