Logs & Monitoring
Stream, filter, and manage container logs. Monitor resource usage with docker stats. Know what your containers are doing in real time.
docker logs
Docker automatically captures everything your container writes to stdout and stderr. You can retrieve it anytime with docker logs, even after the container has stopped.
# Print all logs
docker logs my-container
# Stream logs in real time (like tail -f)
docker logs -f my-container
# Show only the last N lines
docker logs --tail 100 my-container
# Stream from the last 50 lines onward
docker logs --tail 50 -f my-container
# Show logs from the last 10 minutes
docker logs --since 10m my-container
# Show logs older than 5 minutes ago
docker logs --until 5m my-container
Filtering Docker Logs with grep
docker logs outputs plain text, so you can pipe it through any Unix tool:
# Find all error lines
docker logs my-app 2>&1 | grep -i error
# Find lines matching a specific request path
docker logs my-nginx 2>&1 | grep "POST /api"
# Count how many times an error appears
docker logs my-app 2>&1 | grep -c "ERROR"
The 2>&1 part merges stderr into stdout before piping, Docker sends some output to stderr, so without it your grep might miss lines.
Log Drivers
By default, Docker uses the json-file driver, which stores logs as JSON files on your host machine. For production environments, you can swap this out to ship logs directly to a central logging system:
# Limit log file size and rotation
docker run --log-driver json-file --log-opt max-size=10m --log-opt max-file=3 nginx
# Send to syslog
docker run --log-driver syslog nginx
Available drivers include json-file, syslog, journald, fluentd, awslogs, splunk, gcplogs, and local.
Heads up: If you switch to a non-
json-filedriver,docker logswill stop working and logs will go directly to the external system instead.
docker stats
docker stats gives you a live dashboard of CPU, memory, network, and disk I/O for every running container:
# Live stats for all running containers
docker stats
# Stats for specific containers only
docker stats my-web my-db
Keep an eye on the MEM % column. When a container hits 100% of its memory limit, Docker kills it with exit code 137 (OOM kill). If you're seeing unexpected container restarts, this is often why.
docker events
docker events streams a live feed of every action Docker takes like containers starting, stopping, crashing, images being pulled, and more. It's the closest thing Docker has to an audit log. This is especially useful when a container keeps restarting unexpectedly. docker events shows you exactly when and why it died.
# Stream all events live
docker events
# Filter to container events only
docker events --filter type=container
# Filter by a specific event
docker events --filter event=start
# Filter by container name
docker events --filter container=my-app
# Events from the last 10 minutes
docker events --since 10m
Container Health Checks
If your Dockerfile defines a HEALTHCHECK, Docker will periodically run it and mark the container as healthy or unhealthy. This is useful for load balancers, orchestration tools, and catching silent failures.
Add a health check to your Dockerfile:
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
Check health status from the host:
# See healthy/unhealthy status in the ps output
docker ps
# Get the full health check history
docker inspect --format='{{json .State.Health}}' my-container | python3 -m json.tool
{
"Status": "healthy",
"FailingStreak": 0,
"Log": [
{
"Start": "2026-02-04T10:00:00Z",
"End": "2026-02-04T10:00:00Z",
"ExitCode": 0,
"Output": "OK"
}
]
}
Quick Reference
| Command | What It Does |
|---|---|
docker logs -f my-container | Stream logs in real time |
docker logs --tail 50 my-container | Show last 50 lines |
docker logs --since 10m my-container | Logs from the last 10 minutes |
docker logs 2>&1 | grep ERROR | Filter logs for errors |
docker stats | Live CPU/memory dashboard |
docker stats --no-stream | One-time resource snapshot |
docker events | Live stream of Docker events |
docker events --filter event=die | Watch for container crashes |
Key Takeaways
docker logs -f --tail 50is your first move when something goes wrong. It streams the last 50 lines and keeps following in real time- Pipe
docker logsthroughgrepfor quick filtering; use2>&1to capture both stdout and stderr docker statsgives a live resource view. Also, note that if a container is at 100% memory then it will be OOM-killed (exit code 137)docker eventsis your audit trail which is used to understand unexpected restarts, stops, and crashes- Log drivers let you ship logs to external systems in production; switching away from
json-filedisablesdocker logs HEALTHCHECKin your Dockerfile lets Docker automatically detect and report unhealthy containers
Frequently Asked Questions
Why do my docker logs show nothing even though the container is running?
Your application might be writing logs to a file inside the container instead of to stdout/stderr. Docker only captures output sent to those two streams. Check where your app writes its logs. You may need to symlink the log file to /dev/stdout, or configure the app to log to stdout.
What's the difference between docker logs -f and docker attach?
docker logs -f streams the captured log output, it's read-only and safe. docker attach connects directly to the container's main process, which means pressing Ctrl+C can stop your container. Use docker logs -f for monitoring.
What does exit code 137 mean?
Exit code 137 means the container was killed by the OS. It's almost always because it exceeded its memory limit (OOM kill). Check docker stats to see if your container is approaching its memory limit, and consider increasing it with --memory or optimizing your app's memory usage.
Can I view logs from a stopped or crashed container?
Yes. docker logs works on stopped containers as long as they haven't been removed. Once you run docker rm, the logs are gone. If you need persistent logs beyond a container's lifecycle, configure a log driver like fluentd or awslogs.
How do I stop docker logs -f without closing my terminal?
Press Ctrl+C. Unlike docker attach, this only stops the log stream and does not affect the container in any way.
How often does HEALTHCHECK run?
By default every 30 seconds, with a 30-second timeout and 3 retries before marking the container unhealthy. You can customize all three with --interval, --timeout, and --retries in your Dockerfile.