Skip to Content
Tares

How does an AI SRE read logs from Docker containers while investigating slow database queries?

Tares tails a running container’s logs with the docker_logs connector, one event per line, and labels them by service so they sit on the same timeline as that service’s alerts. When an alert fires, your agent reads the log lines from the same window instead of querying the container itself. Point the connector at your database container, or the service that logs its queries, and the slow-query lines arrive next to the alert that woke the agent.

How it works

The docker_logs connector polls a running container and turns each log line into an event. By default every line is kept. You can narrow the stream with two optional regex filters:

  • match keeps only lines that match, for example ERROR|WARN.
  • drop skips lines that match, for example HTTP/1.1" to drop access logs.

Every source that carries the same service label lands on one timeline for that service. Metrics, logs and alerts are merged on one clock, so a log line from 14:04 sits next to the alert that fired at 14:04. A trigger watches those sources. When an alert event arrives, it wakes your agent, and the agent reads the correlated timeline for that service. It does not need a separate tool per system. The same read is available on demand from any connected MCP client.

This is the pattern from Build an AI SRE. Prometheus keeps owning alerting, and Tares ingests what fired and correlates it with the logs. The Docker logs connector page covers the connector itself.

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.

Set it up

  1. Start Tares on the host that runs your containers.

    tares up
  2. Add the log source. The quickest way is to ask a connected agent: “Use tares to find my running containers and ingest the api-server’s logs.” The agent calls discover_docker to scan running containers, runs test_source as a dry run that tails a few lines, then calls create_source. In the console, go to Sources → Add source → docker_logs, set container to the container or compose service name, and use Discover to pick from the running containers.

  3. Label the source by service. Give the source a primary service label so its lines join that service’s timeline. Use the same label name on your metrics and alert sources.

    - 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 }
  4. If the container runs under Compose without a fixed container_name, set container to the service name and add compose_file, an absolute path or one relative to where the daemon runs. The tail then follows restarts.

  5. Narrow the stream if the container is noisy. Set match to a regex that keeps the lines you care about, such as the lines your database writes for slow statements, or set drop to skip routine lines. Use label_pattern, a regex with named groups, to pull per-line label context out of the line.

  6. Verify. Open the source in the console. Recent events shows lines on the next poll. If nothing arrives, check that taresd can run docker logs for that container, because that is the access it needs.

  7. Connect your agent. Start the MCP endpoint in a second shell, point your client at it, and ask about the service.

    tares mcp

    For example: “Use tares: what happened to api-server in the last 15 minutes?” The client calls read for that service and answers from the correlated timeline. You can see the same view yourself in the console at http://127.0.0.1:8787, under Explore.

What you get

  • Container log lines arrive as events, labeled by service, on the same clock as that service’s alerts and metrics.
  • When an alert fires, a trigger wakes your agent, and the agent reads the log lines from the alert window in one correlated read.
  • Your agent can tie its conclusion to specific log lines. It writes a finding back onto the service’s timeline, so the next investigation starts from that conclusion.
  • You can ask the same question interactively from a connected MCP client and get the same evidence.
  • Filters keep the stream readable. match and drop cut the noise before it reaches the agent.

When something else fits

  • If your logs go through an OpenTelemetry pipeline instead of a container on the local Docker daemon, use the OTLP connector for the log source.
  • If the database writes its slow queries to a table instead of to stdout, the Postgres connector reads rows from a table. The Docker logs connector reads only what the container prints.

Still stuck? Get help

Last updated on