Run an OpenTelemetry Collector locally in Docker

This is an experience report for my future reference (and yours).

The OpenTelemetry Collector is useful for receiving trace data in whatever format and exporting it to the back-end of your choice for storage and querying. For instance, I wanted to receive traces over HTTP/JSON from this sneaky browser extensionLINK and send them to Honeycomb. Honeycomb requires some headers that say whose event it is, plus it doesn’t yet receive OpenTelemetry traces over HTTP/JSON. The collector forward the traces on with the right headers and over gRPC.

I want to run the collector in Docker on my local computer. The instructions didn’t work (as of 10 Aug 2021).

Here’s what worked: one config file, and one docker command.

The simplest config I could get

One config file, called otel-local-config.yaml

receivers:
  otlp:
    protocols:
      grpc:
      http:
        cors_allowed_origins:
        - "*"

processors:
  batch:

exporters:
  logging:
    logLevel: debug
  otlp:
    endpoint: "api.honeycomb.io:443"
    headers:
      "x-honeycomb-team": "HONEYCOMB-API-KEY-GOES-HERE"
      "x-honeycomb-dataset": "DATASET-NAME-GOES-HERE"

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [logging, otlp]

This says:

“Receive OTLP events over gRPC and HTTP. For the HTTP ones, allow all cross-origin requests.” OTLP is the protocol standard specified by OpenTelemetry.

“Handle batched events.”

“Export to the log, and also send the events over OTLP to the honeycomb endpoint, with the headers I need.” Don’t forget to substitute your Honeycomb API key and dataset name.

“Wire all that together so that all incoming OTLP events go out over both the logging and OTLP-to-honeycomb exporters.”

This config is minimal, and suitable for local use, not production.

Run their docker container

Here it is, the secret command:

docker run \
-v "${PWD}/otel-local-config.yaml":/otel-local-config.yaml \
-p 55681:55681 \
otel/opentelemetry-collector \
--config otel-local-config.yaml;

This says,

“run docker” (you knew that part)

“mount this config file from my current directory into the root directory in the container.”

“map the port 55681” which happens to be the port the HTTP receiver started up on, as reported by the collector’s logs.

“Use the image otel/opentelemetry-collector from DockerHub.”

“pass into the container’s process this config argument to use that config file we mounted in from our local computer.” The container is running otelcol, assuming I found its Dockerfile.

Send traces here

Now you can send traces to http://localhost:55681/v1/traces

Be sure, be very very sure, that the content-type is application/json. Don’t include the charset (that one cost me some time). Thanks to this detailed issue for giving me a workaround to get the content type right. So tricky!