Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tail stdout from multiple Docker containers

I have a script that starts 10 containers in background mode (fig up -d option). I want to aggregate the stdout or the log in /var/log from all of them. How can I do this?

The containers are started using different docker-compose files so I can not do docker-compose up target1 target2 target3

docker logs only accepts one container as a parameter.

I was considering creating a volume from the /var/log on all containers, mapping them to a directory outside of docker, making sure the logs do not have colliding name and than using the bash tail -f * . But I would appreciate a more elegant solution

like image 939
Ryan Avatar asked Jun 29 '16 08:06

Ryan


People also ask

Can two docker containers talk to each other?

If you are running more than one container, you can let your containers communicate with each other by attaching them to the same network. Docker creates virtual networks which let your containers talk to each other. In a network, a container has an IP address, and optionally a hostname.

Can I have two Dockerfiles?

Introduction. Docker is a handy tool for containerization. It's so useful that sometimes, we want to have more than one Dockerfile in the project. Unfortunately, this goes against the straightforward convention of naming all Dockerfiles just “Dockerfile”.

Can multiple docker containers use the same port?

So there is no conflict if multiple containers are using the same port ( :80 in this case). You can access one container from another using its container-name or service-name or ip-address, whereas ip-address is not a good idea because this might change every time you (re)start the container.

How do I merge Dockerfiles?

You can't combine dockerfiles as conflicts may occur. What you want to do is to create a new dockerfile or build a custom image.


2 Answers

This bash script will do what you want:

docker-logs

#!/bin/bash

if [ $# -eq 0 ]; then
   echo "Usage: $(basename "$0") containerid ..."
   exit 1
fi

pids=()
cleanup()
{
   kill "${pids[@]}"
}

trap cleanup EXIT

while [ $# -ne 0 ]
do
    (docker logs -f -t --tail=10 "$1"|sed -e "s/^/$1: /")&
    pids+=($!)
    shift
done
wait

Usage:

$ docker-logs containerid1 containerid2 ... containeridN

The output of this script has each line from the tracked logs prepended with the container id.

The script works in --follow mode and must be interrupted with Ctrl-C.

Note that the options of docker logs are hardcoded in the script. If you need to be able to control the options of docker logs from the command line then you will need to parse the command line arguments (for example with getopts).

like image 147
Leon Avatar answered Oct 07 '22 20:10

Leon


Docker does not support as 1.12 yet. But I have a workaround via bash;

docker ps | grep -w <filter-text> | for i in `awk '{ print $1 }'`; do docker logs -f --tail=30 $i & done

I am using docker swarm modes comes with 1.12 and deploying many replication. So all of my containers contain common text which is same as service name. To tail all of its logs in a docker node , I am using this on each docker node. filter-text will be filtering only my containers.

If you want to stop tailing, this works for me;

pkill -f 'docker logs'
like image 25
Ahmet DAL Avatar answered Oct 07 '22 21:10

Ahmet DAL