Skip to content

Send through the OpenTelemetry Collector

A standard Collector config that receives OTLP gRPC/HTTP from your apps and forwards to Belvador with otlphttp, a memory limit, batching, a queue and retries.

Markdown
On this page

The OpenTelemetry Collector is a standard process that receives telemetry from your apps and forwards it. Use it when an exporter speaks only gRPC, when a runtime's exporter does not retry, when you want one place that holds the Belvador key, or for any language Belvador has not run itself.

Tested on 2026-10-27 with otelcol-contrib 0.163.1, telemetrygen v0.163.0: traces passed, logs passed, metrics passed.

Configure#

Use the contrib distribution (otelcol-contrib). This configuration uses standard components only:

collector.yaml
receivers:  otlp:    protocols:      grpc:        endpoint: localhost:4317      http:        endpoint: localhost:4318processors:  memory_limiter:    check_interval: 1s    limit_percentage: 80    spike_limit_percentage: 20  batch: {}exporters:  otlphttp/belvador:    endpoint: ${env:BELVADOR_OTLP_ENDPOINT}    headers:      Authorization: Bearer ${env:BELVADOR_INGEST_KEY}    compression: gzip    retry_on_failure:      enabled: true    sending_queue:      enabled: trueservice:  pipelines:    traces:      receivers: [otlp]      processors: [memory_limiter, batch]      exporters: [otlphttp/belvador]    logs:      receivers: [otlp]      processors: [memory_limiter, batch]      exporters: [otlphttp/belvador]    metrics:      receivers: [otlp]      processors: [memory_limiter, batch]      exporters: [otlphttp/belvador]
  • Receivers accept OTLP over gRPC (4317) and HTTP (4318) from your apps. They listen on localhost; in a container, use 0.0.0.0:4317 and 0.0.0.0:4318 so other containers can reach them, and do not publish those ports to the internet.

  • memory_limiter refuses new data before the Collector runs out of memory, so your apps' exporters back off instead of the Collector crashing.

  • batch groups records into fewer, larger requests (well under the 4 MiB request limit).

  • otlphttp/belvador sends to Belvador with gzip; retry_on_failure retries 429, 502, 503 and 504 with backoff, and sending_queue holds data in memory meanwhile.

Run#

Terminal
export BELVADOR_OTLP_ENDPOINT=https://ingest.belvador.dev/otlp/<project-id>export BELVADOR_INGEST_KEY=<your-ingest-key>otelcol-contrib --config collector.yaml

With Docker, use the otel/opentelemetry-collector-contrib image with the same file mounted at /etc/otelcol-contrib/config.yaml and the two variables passed with -e.

Point your apps at it#

Apps send to the Collector without a key:

Terminal
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf   # or grpc with port 4317export OTEL_SERVICE_NAME=my-serviceexport OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=productionexport OTEL_METRICS_EXPORTER=none   # otlp to send metrics too (key with Metrics)

Each app keeps its own OTEL_SERVICE_NAME and environment; the Collector passes resource attributes through unchanged.

Surviving restarts#

The queue above lives in memory: if the Collector restarts while Belvador is unreachable, queued data is lost. To keep it on disk, add the contrib file_storage extension and set sending_queue.storage to it. Belvador's run does not cover that setup.

Log files#

Apps that only write log files can be read by the contrib filelog receiver and sent through the same logs pipeline. Records read from files carry no trace id unless your log lines contain one and you parse it out; this receiver is not part of what is marked tested.

Spotted something wrong or missing? Tell us: hello@belvador.dev