A Developer's Guide to OpenTelemetry Collector
open-telemetry/opentelemetry-collector
From an engineering perspective, the Collector solves a lot of common problems
Vendor Lock-in
By using the Collector, you can switch your backend (e.g., from one cloud provider's service to another) without changing the instrumentation in your application code. The Collector acts as a buffer, decoupling your application from the final destination of the data. This flexibility is a big win.
Reduced Overhead
Instead of sending telemetry data directly from your application to a remote backend, the Collector can be run locally or on a sidecar. This offloads the processing, batching, and retrying logic from your application, which can significantly reduce network latency and resource consumption.
Data Transformation
The Collector can filter, sample, and transform your data before it's sent. For example, you can drop sensitive PII from logs, aggregate metrics to reduce cardinality, or sample traces to control costs. This gives you fine-grained control over what data you collect and how much you send.
Unified Pipeline
It provides a single, consistent way to handle all types of telemetry data. Whether it's metrics from your service, traces from a microservice architecture, or logs from a Kubernetes cluster, they all flow through the same pipeline.
Getting the Collector up and running is pretty straightforward. The simplest way is to use a pre-built binary or a Docker container.
Download the Binary or Docker Image
Docker
docker pull otel/opentelemetry-collector-contrib
Binary
You can find releases on the official GitHub page.
Create a Configuration File
The Collector's behavior is defined by a YAML configuration file. This file specifies what data to receive (receivers), how to process it (processors), and where to send it (exporters).
Run the Collector
Docker
docker run -v /path/to/your/config.yaml:/etc/otel-collector-config.yaml otel/opentelemetry-collector-contrib --config=/etc/otel-collector-config.yaml
Binary
./otelcol --config /path/to/your/config.yaml
Let's walk through a simple example of a config.yaml that receives data via the OTLP (OpenTelemetry Protocol) and exports it to a couple of common backends
Prometheus and a file.
receivers:
otlp:
protocols:
grpc:
http:
processors:
batch:
send_batch_size: 1000
timeout: 5s
exporters:
# Exporter to Prometheus, exposing a metrics endpoint
prometheus:
endpoint: "0.0.0.0:8889"
namespace: "my_app_metrics"
# Exporter to a file for debugging logs
file:
path: /tmp/telemetry-data.log
service:
pipelines:
metrics:
receivers: [otlp]
processors: [batch]
exporters: [prometheus]
logs:
receivers: [otlp]
processors: [batch]
exporters: [file]
traces:
receivers: [otlp]
processors: [batch]
exporters: [file]
receivers
The otlp receiver is configured to listen for data sent via gRPC and HTTP. This is how your applications will send telemetry to the Collector.
processors
The batch processor is a crucial component. It buffers data and sends it in batches to the exporters, which is much more efficient than sending each data point individually.
exporters
The prometheus exporter makes the collected metrics available at a specific endpoint (0.0.0.0:8889), which a Prometheus server can then scrape.
The file exporter simply writes data to a local file, which is great for debugging or local testing.
service
This is where you define the pipelines.
Each pipeline (metrics, logs, traces) links a receiver to one or more processors and exporters. This allows you to have different processing and export logic for different types of telemetry data.