Introduction
Logging is an essential part of containerizing applications as it helps developers keep track of patterns, troubleshoot issues, and fix bugs. Docker offers built-in logging solutions and additional features that ensure effective log management.
Read on to learn about Docker container logs, the commands they relate to, and best practices developers can apply.
Where Are Docker Container Logs Stored?
Docker logs fetch the command’s stdout (normal output) and stderr (error messages) streams. All output and error messages are logged, passed to the container’s logging driver and forwarded to the desired location (a file, a log collector, or a log management service).
The default logging driver for Docker is the JSON-file driver that stores logs on the host. Locate the files in the following directory:
/var/lib/docker/containers/ID/ID-json.log
Replace the ID in the path with the ID of the container.
Docker Command for Checking Container Logs
The docker logs
command instructs Docker to fetch the logs for a running container at the time of execution. It only works with containers utilizing the JSON-file or journald logging driver.
The command syntax for retrieving container logs is:
sudo docker container logs [option] container_id
Replace container_id
with the ID number of the container you want to inspect. To find the container ID, use the docker ps
command to list running containers.
In the example below, Docker is running a MySQL container with the ID ebebb5c7ae0d
. To display its logs, run:
sudo docker logs ebebb5c7ae0d
As in the image below, Docker responds by listing the event logs for that specific container in the output.
Docker Container Logs Command Options
Docker allows adding options to the command to configure the output according to individual needs.
The available command options include:
Command Option | Description |
---|---|
--details |
Display additional details provided to logs. |
--follow , -f |
Follow log output. |
--since |
Display logs since a specified timestamp (e.g. 2022-05-06T14:48:33Z) or relative (e.g. 20m). |
--tail , -n |
Specify the number of lines to show from the end of the logs. |
--timestamps , -t |
Show timestamp. |
--until |
Display logs before a specified timestamp. |
Docker Container Logging Best Practices
Docker provides multiple logging mechanisms for tracking and managing logs, some of which are built-in and set up by default.
Consider the following recommended approaches and best practices that help keep container logs on-point and secure.
Choose a Docker Logging Driver
Docker provides built-in logging drivers within containers to serve as log management systems. The driver reads the container output (the data broadcast by its stdout
and stderr
streams), formats the logs, and stores them in a file on the host machine or a defined endpoint.
The type of driver determines the format of the logs and where they are stored. By default, Docker uses the JSON-file driver, which writes JSON-formatted logs on the container’s host machine. You can use other built-in drivers to forward collected records to logging services, log shippers, or a centralized management service.
If none of the existing drivers meet your requirements, Docker allows you to create a custom logging driver, add it as a plugin to a container and even distribute it through a Docker registry.
Note: To run a container and use a different logging driver, add the --log-driver
option to the docker run
command and specify the wanted driver.
Select a Delivery Mode
Delivery modes determine how messages are prioritized and delivered to the log driver from the container.
Docker has two delivery modes:
- Direct, blocking delivery. Blocking is the default mode that sends all messages directly to the driver, interrupting the application when a new message occurs. This option ensures all output is immediately logged, but it can potentially affect application performance and cause latency if the logging driver requires more time to block.
- Non-blocking delivery. Non-blocking is a delivery mode that includes an intermediate ring buffer within the container where logs are stored until the logging driver processes them. If the logging driver is busy, the logs are kept in the in-memory ring buffer and passed on only until the driver is ready to process them.
Important: Although non-blocking helps prevent latency, it can potentially lead to data loss. If the buffer memory is full, the oldest message is dropped, even if it has not been delivered to the logging driver.
Note: Docker utilizes the blocking delivery mode by default. To log messages in the non-blocking mode, add the mode=non-blocking
attribute to the docker run
command when spinning up the container.
Logging via Application
Application-based Docker logging includes managing and analyzing logging events using the application’s framework. This means Docker logs are handled and stored inside the application’s containers.
The main advantage of utilizing logging via application is that developers gain more control over the logging events. On the other hand, saving logs inside a container is not recommended because of its transient nature. If a container shuts down, its filesystem is destroyed.
Configure persistent storage or transmit logs to a remote management solution to ensure persistency.
Logging Using Data Volumes
Keeping Docker logs within a container may result in data loss if the container shuts down. One way of solving this issue is to use data volumes as persistent storage for log events.
Docker volumes are file systems stored on the host and mounted on Docker containers to preserve data generated by the running container. Volumes are independent of the container life cycle, which means the data is secure even if the container fails. Additionally, its independence means you can easily copy, backup, and share file systems between containers.
Use Dedicated Logging Container
Collect and manage Docker logs using a dedicated logging container that is not dependent on the host machine. This container collects the log files from the Docker environment, monitors and inspects the logs before sending them to a centralized location.
As the logging container is an independent unit, you can easily move it between different environments. What’s more, scaling the logging infrastructure is straightforward – if needed, add new logging containers to the existing setup.
Another great advantage to utilizing dedicated logging containers is that they do not require installing a configuration code. On the other hand, the application and logging containers must be correctly defined to ensure smooth automated loggings.
Note: Check out our recommendations for the best tools for Docker container monitoring.
Apply the Sidecar Approach
The sidecar approach is one of the most popular methods of managing microservice architecture for more complex deployments.
Sidecars are services deployed alongside the parent application within a container as a secondary process. They share the volume and network with the primary container and ultimately increase the app’s functionality.
Each application has its own dedicated container as a log service customized for and tailored to the program. The logging container saves log files to the volume, labels, and ships them to a third-party log management solution.
Important: The primary (application) container and the sidecar (logging) container must work as a single unit to prevent any potential data loss.
Managing Docker logs using the sidecar approach simplifies identifying and tracking the origin of each log through the use of custom tags. On the other hand, the sidecar method is more complex and requires more resources than the dedicated logging solution.
Conclusion
After reading this article, you should have a better understanding of how Docker logs work, how to use the basic commands for working with them, and what the best practices for managing Docker logs are.
To learn more Docker commands you will most certainly use while working with containers, check out our List of Docker Commands: Cheat Sheet.