Grafana Tempo’s OTLP Collector Exporter doesn’t just send traces; it’s a sophisticated traffic cop for your distributed tracing data.
Let’s see this bad boy in action. Imagine you’ve got a microservice spitting out traces. You’re not sending them directly to Tempo, oh no. You’re sending them to an OpenTelemetry Collector, which is acting as your central ingestion point. From there, you want those traces to land in Tempo. That’s where the OTLP Exporter for Tempo comes in.
Here’s a simplified otel-collector-config.yaml demonstrating this flow:
receivers:
otlp:
protocols:
grpc:
http:
processors:
batch:
send_batch_size: 1000
timeout: 10s
exporters:
tempo:
endpoint: "tempo.grafana.local:55681" # Your Tempo instance's OTLP gRPC endpoint
tls:
insecure: true # Set to false in production with proper certificates
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [tempo]
In this setup:
- Receivers (
otlp): This is how the collector listens for incoming traces. It’s configured to accept traces via gRPC and HTTP, the standard OTLP protocols. - Processors (
batch): This is a crucial optimization. Instead of sending each trace individually, thebatchprocessor groups them up (up to 1000 traces or after 10 seconds) before sending. This dramatically reduces overhead. - Exporters (
tempo): This is the star of our show. Thetempoexporter is specifically designed to send trace data to a Tempo backend using the OTLP (gRPC) protocol. - Service (
pipelines.traces): This ties it all together, defining the path traces take: receive viaotlp, process withbatch, and export totempo.
The collector, armed with this config, becomes a reliable conduit. It ingests traces from various sources (your microservices, other collectors), batches them efficiently, and then pushes them over OTLP gRPC to your Tempo instance. Tempo, in turn, indexes and stores these traces for later querying and visualization.
The real magic here is the abstraction. Your microservices don’t need to know anything about Tempo’s internal storage or API. They just speak OTLP. The collector, with its Tempo exporter, handles the translation and delivery. This decouples your application from your observability backend, making it far more flexible. You could swap Tempo for Jaeger or another backend that speaks OTLP without touching your services, just by reconfiguring the collector’s exporter.
The endpoint in the exporter configuration is paramount. It’s the address your collector uses to talk to Tempo. If this is wrong, or Tempo isn’t listening on that port, your traces will just evaporate. The tls section is about security; insecure: true is for quick testing, but you’ll want proper TLS setup for anything serious.
What most people miss is the subtle but critical distinction between the OTLP receiver on the collector and the OTLP exporter to Tempo. The receiver is what the collector listens to. The exporter is how the collector speaks to the next hop. In this case, the collector is acting as a client to Tempo’s OTLP server endpoint.
The next step is understanding how to configure the Tempo backend itself to receive these OTLP traces efficiently.