[logging] How to redirect docker container logs to a single file?

I want to redirect all the logs of my docker container to single log file to analyse them. I tried

docker logs container > /tmp/stdout.log 2>/tmp/stderr.log

but this gives log in two different file. I already tried

docker logs container > /tmp/stdout.log

but it did not work.

This question is related to logging docker

The answer is


The easiest way that I use is this command on terminal:

docker logs elk > /home/Desktop/output.log

structure is:

docker logs <Container Name> > path/filename.log

If you work on Windows and use PowerShell (like me), you could use the following line to capture the stdout and stderr:

 docker logs <containerId> | Out-File 'C:/dev/mylog.txt'

I hope it helps someone!


Bash script to copy all container logs to a specified directory:

#!/usr/bin/env bash

TARGET_DIR=~/logs/docker_logs
mkdir -p "$TARGET_DIR"
for name in `sudo docker ps --format '{{.Names}}'`;
do
    path=$(sudo docker inspect --format='{{.LogPath}}' $name)
    sudo cp -rf "$path" "$TARGET_DIR"/$name.log
done

docker logs -f <yourContainer> &> your.log &

Explanation:

  • -f (i.e.--follow): writes all existing logs and continues (follows) logging everything that comes next.
  • &> redirects both the standard output and standard error.
  • Likely you want to run that method in the background, thus the &.
  • You can separate output and stderr by: > output.log 2> error.log (instead of using &>).

docker logs -f docker_container_name >> YOUR_LOG_PATH 2>&1 &


How about this option:

docker logs containername >& logs/myFile.log

It will not redirect logs which was asked for in the question, but copy them once to a specific file.


Assuming that you have multiple containers and you want to aggregate the logs into a single file, you need to use some log aggregator like fluentd. fluentd is supported as logging driver for docker containers.

So in docker-compose, you need to define the logging driver

  service1:
    image: webapp:0.0.1
    logging:
      driver: "fluentd"
      options:
        tag: service1 

  service2:
        image: myapp:0.0.1
        logging:
          driver: "fluentd"
          options:
            tag: service2

The second step would be update the fluentd conf to cater the logs for both service 1 and service 2

 <match service1>
   @type copy
   <store>
    @type file
    path /fluentd/log/service/service.*.log
    time_slice_format %Y%m%d
    time_slice_wait 10m
    time_format %Y%m%dT%H%M%S%z
  </store>
 </match> 
 <match service2>
    @type copy
   <store>
    @type file
    path /fluentd/log/service/service.*.log
    time_slice_format %Y%m%d
    time_slice_wait 10m
    time_format %Y%m%dT%H%M%S%
  </store>
 </match> 

In this config, we are asking logs to be written to a single file to this path
/fluentd/log/service/service.*.log

and the third step would be to run the customized fluentd which will start writing the logs to file.

Here is the link for step by step instructions

Bit Long, but correct way since you get more control over log files path etc and it works well in Docker Swarm too .


Since Docker merges stdout and stderr for us, we can treat the log output like any other shell stream. To redirect the current logs to a file, use a redirection operator

$ docker logs test_container > output.log
docker logs -f test_container > output.log

Instead of sending output to stderr and stdout, redirect your application’s output to a file and map the file to permanent storage outside of the container.

$ docker logs test_container> /tmp/output.log

Docker will not accept relative paths on the command line, so if you want to use a different directory, you’ll need to use the complete path.


First check your container id

docker ps -a

You can see first row in CONTAINER ID columns. Probably it looks like this "3fd0bfce2806" then type it in shell

docker inspect --format='{{.LogPath}}' 3fd0bfce2806

You will see something like this

/var/lib/docker/containers/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1-json.log

then you can see it as

cat /var/lib/docker/containers/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1-json.log

It would be in JSON format, you can use the timestamp to trace errors


To capture both stdout & stderr from your docker container to a single log file run the following:

docker logs container > container.log 2>&1