Skip to Content
Tares

How do I line up logs from Docker containers with OpenTelemetry metric series for one service?

Tares lines them up when both sources carry the same primary service label. Give the docker_logs source a constant service value, make sure your OpenTelemetry exporter sets service.name to that same value, and one read of the service returns the log lines and the metric values on one clock. The otlp source takes its service label from service.name, so you only need to match the Docker side to it.

How it works

Tares correlates events by label. Every source declares labels, and one of them is marked primary. Sources that share the same primary key and value land on one timeline for that service.

  • The Docker logs connector tails a running container’s logs, one event per line. You set the service label as a constant in the source config, for example api-server.
  • The OpenTelemetry connector receives OTLP logs, traces and metrics. One otlp source ingests every service. Resource attributes such as service.name become labels, and the service label is read from service.name.
  • When both carry service as the primary label with the same value, the container’s log lines and the metric points sit together on that service’s timeline, merged on one clock.

The value is what ties them together. If the container label says api-server and the exporter sends service.name as checkout, you get two separate timelines. Pick one name and use it on both sides.

This is the same per-service pattern the AI SRE guide builds on: sources keyed by one service label, read as a single timeline by you or by an agent.

Set it up

  1. Start Tares locally and open the console.
tares up
  1. Add the Docker logs source. Go to Sources → Add source → docker_logs, or ask a connected agent to find your containers and ingest the logs. Set container to the container name from docker ps, and give it a constant service label marked primary. Tares needs access to the Docker daemon: run taresd on the host, or mount the Docker socket and include the Docker CLI in the image.
- name: logs connector: docker_logs poll: 5s config: container: tares-demo-api-server # the container name (docker ps) labels: - { name: service, const: api-server, primary: true }
  1. Add the OpenTelemetry source. Go to Sources → Add source → otlp. It has no required config. The service label, read from service.name, is the key, and you mark it primary.
- name: otel connector: otlp config: labels: - { name: service, field: service, primary: true }
  1. Point your exporter at Tares and set the service name to the value you used in the Docker source. Here the endpoint is OTLP/HTTP, and the gRPC alternative needs the otlp-grpc extra.
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:8787 # OTLP/HTTP → /v1/{logs,traces,metrics} # or gRPC (otlp-grpc extra): OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317

In your app or Collector, make service.name equal api-server, matching the constant in step 2. If Tares runs with auth on, the exporter sends a Bearer Authorization header holding an ingest-scoped API key. Without auth, no header is needed.

  1. Check both sides. Open each source in the console and look at Recent events: the Docker source shows lines on the next poll, and the OTLP source shows metric points as they arrive. If the Docker source stays empty, check that taresd can run docker logs on the container.

  2. Read the service. In Explore, the services are listed under the service key. Pick api-server and you see log lines and metric values merged on one clock. A connected MCP client gets the same view when it calls read for that service.

What you get

  • One timeline per service that holds the container’s log lines and the OpenTelemetry metric points together, ordered on one clock.
  • A single read for an agent or for you. You do not query the log source and the metric source separately and line up timestamps by hand.
  • No per-service setup on the OpenTelemetry side. The one otlp source takes every service your exporters send, and each new service shows up under the service key as soon as it exports.
  • A Docker side you can tune without touching the correlation: match keeps only lines that match a regex, such as ERROR|WARN, and drop skips noisy lines such as access logs. The service label stays the same.
  • A base for triggers and agents. Because the sources are keyed by service, a trigger or an agent in the AI SRE flow works from the same correlated timeline.

When something else fits

  • If the metrics live in a Prometheus server rather than arriving as OTLP, use the Prometheus connector and give it the same primary service label. The correlation works the same way.
  • If your logs already reach Tares through OpenTelemetry, you do not need docker_logs. The otlp source takes logs and metrics together and keys both by service.name.
  • If the container name or service name differs between the two worlds and you cannot change it, set the constant in the docker_logs label to whatever service.name the exporter sends.

Still stuck? Get help

Last updated on