What should I look for in logs from Docker containers when the problem is crash loops?
Tares tails a container’s logs into one event per line, so a crash loop shows up as the same startup line repeating, each time preceded by an error. The docker_logs connector follows restarts when you set compose_file. You can also add a trigger that counts matching lines in a time window and wakes an agent when the count passes your threshold.
How it works
A crash loop leaves a pattern in a container’s log stream, and the docker_logs connector keeps every line of it as its own event.
- One event per line. Tares tails the running container and stores each line. All lines are kept by default, so a restart cycle is visible line by line.
- The telltale lines. Look for your application’s startup message appearing again and again, and for an error or stack trace just before each repeat. Short gaps between repeats and the same error every cycle point to a crash loop. A single error followed by a long quiet stretch does not.
- Restarts are followed. If the container runs under Compose, set
compose_fileso the tail keeps following the container across restarts. Without a fixedcontainer_name, setcontainerto the service name. - Filters.
matchkeeps only lines that match a regex, for exampleERROR|WARN.dropskips lines that match a regex, which is useful for access logs that bury the crash lines. - One timeline per service. Give the log source the same
servicelabel as your other sources. Logs, metrics and alerts for that service then sit on one timeline. An agent starts from that correlated timeline and writes a finding back to it: what broke, since when, the likely cause tied to evidence lines, and a next action. - Triggers. A trigger watches the sources for a service and fires on a condition you choose. A trigger condition can count events over a window with
aggregate,predicateandwindow.
Set it up
- Start Tares on the host that can reach the Docker daemon.
taresdneeds the same access asdocker logs <container>.
tares up- Ask a connected agent to find the container and ingest its logs: “Use tares to find my running containers and ingest the api-server’s logs.” The agent calls
discover_docker, dry-runs the source withtest_source, then callscreate_source. You can also use Sources → Add source → docker_logs in the console. - Set
containerto the container or Compose service name. If it runs under Compose, addcompose_fileas an absolute path, or a path relative to where the daemon runs. - Add a
matchfilter so the source keeps the lines that matter for a crash loop. Give the source a primaryservicelabel.
- name: logs
connector: docker_logs
poll: 5s
config:
container: tares-demo-api-server # the container name (docker ps)
match: ERROR|WARN
labels:
- { name: service, const: api-server, primary: true }- Add a trigger that counts lines from that source over a window. When the count passes your predicate, the trigger fires and wakes an agent. Tune the predicate, window and cooldown to your container.
- name: crash-loop-lines
sources: [logs]
condition: { aggregate: count, predicate: "> 5", window: 5m }
cooldown: 5m- Verify the source. Open it in the console. Recent events shows lines on the next poll. If nothing arrives, check that
taresdcan rundocker logs <container>.
To see how a trigger wakes an agent and how the finding lands on the timeline, follow Build an AI SRE. The Docker logs connector page has the full field list.
What you get
- Every log line from the crashing container as its own event, so you can find the repeated startup line and the error before it.
- A tail that keeps following the container across restarts when you set
compose_file. - Noise filtered at the source with
matchanddrop, so access logs do not hide the crash lines. - A trigger that fires when matching lines pass your threshold in a window, instead of you watching the stream.
- A finding on the service’s timeline that states what broke, since when, the likely cause tied to evidence lines and a next action. You and any MCP client you connect read the same finding, so the next investigation starts from it.
When something else fits
- If the signal you need is an alert rather than log lines, use the Prometheus alerts or Alertmanager connectors alongside the logs, and keep alerting where it is.
- If your container logs through an OpenTelemetry pipeline instead of the local Docker daemon, use the OTLP connector for the log stream.
Related
Last updated on