Docker как посмотреть ошибки

Для разработчиков или инженеров DevOps/SecOps всегда важно просматривать логи приложения, чтобы отладить определенные проблемы или понять события, происходящие в вашем приложении.

В контексте Docker вы можете получить доступ к журналам Docker-контейнера с помощью docker CLI.

Эти логи содержат информацию, которая регистрируется контейнером, и могут помочь в устранении неполадок или мониторинге состояния приложения, когда это необходимо.

В этой статье мы рассмотрим, как просматривать журналы контейнеров docker.

Содержание

  1. Настройка лабораторной среды
  2. Использование команды docker logs
  3. Использование команды docker logs –follow
  4. Использование команды docker logs –tail
  5. Заключение

Настройка лабораторной среды

Давайте скачаем образ Nginx из публичного dockerhub с помощью следующей команды.


Далее запустим Docker с Nginx с помощью приведенной ниже команды.


Теперь давайте проверим, запущен ли контейнер docker, с помощью команды $ docker ps.

CONTAINER ID   IMAGE              COMMAND                  CREATED          STATUS                         PORTS                                     NAMES
dbc8526c6b7e   nginx:latest       "/docker-entrypoint.…"   19 seconds ago   Up 12 seconds                  80/tcp                                    modest_kowalevski

Использование команды docker logs

Команда docker logs позволяет получить логи контейнера docker без необходимости входить внутрь контейнера.

Эти логи собираются из потоков STDOUT и STDERR контейнеров docker.

Логи хранятся на хосте docker в формате JSON, и на каждый контейнер всегда приходится один файл лога.

Синтаксис команды docker logs показан ниже.

docker logs <container ID>

Давайте разберемся в этом на примере.

Использование команды docker logs –follow

Теперь, когда контейнер запущен и работает, давайте просмотрим логи контейнера docker


где мы указываем ID контейнера в команде и видим в терминале следующий вывод.

Эта команда покажет логи указанного контейнера docker.

Однако вы не сможете просматривать вывод непрерывно.

Чтобы просматривать логи непрерывно, мы можем создать непрерывный поток вывода на терминал с помощью опции –follow.

docker logs --follow <container ID>

Приведенная выше команда будет передавать последние выходные данные из контейнеров stdout и stderr, и вы сможете отслеживать логи в режиме реального времени до тех пор, пока не остановите процесс.

Этот механизм может быть очень полезен в ситуациях, когда вам нужно устранить неполадки в производственных системах, отслеживая логи контейнеров docker в режиме реального времени.

Использование команды docker logs –tail

Должна возникнуть ситуация, когда вы хотите ограничить количество строк лога контейнера, выводимых на экран.

Как же это сделать?

Команды logs у Docker предоставляют опцию –tail, которая может помочь достичь этой цели.

Давайте рассмотрим это на примере.

docker logs --tail <number> <container_id>

Давайте просмотрим 10 строк вывода нашего контейнера Nginx с помощью приведенной ниже команды.

docker logs --tail 10 dbc8526c6b7e

Заключение

В этой статье мы узнали о том, как просматривать логи контейнеров docker.

см. также:

  • 🐳 Как очистить логи запущенных контейнеров Docker
  • 🐳 Почему процессы в контейнерах Docker не должны запускаться от имени Root
  • 🐳 Как проверить изменения в файловой системе контейнера Docker
  • 🐳 Как просмотреть историю событий Docker
  • 🐳 Как автоматически обновлять контейнеры Docker из реджестри образов
  • 🐳 Как запустить несколько контейнеров Docker на разных IP-адресах
  • 🐳 Как использовать Docker с UFW параллельно
  • 🐳 Как запустить несколько служб в одном контейнере Docker
  • 🐳 Как установить Docker на Kali Linux

Knowledge on logging with Docker can be very helpful for day-to-day system administration activities, be it troubleshooting or basic monitoring. Without tracking logs on Docker, mitigating issues would be a lot more difficult when investigating anomalies.

This write-up explores some important information on that area to make it easier to understand how to manage Docker associated log files on your Linux system.

Let me start by exploring the most basic parts and gradually go deeper into some specifics.

You can use the docker logs command to fetch whatever is going on with the service inside a running container.

The syntax is simple:

docker logs container_name_or_ID

You probably already know that you can use the docker ps command to view the running containers’ name and ID.

Let’s take a real-world example. I have deployed Nextcloud with Docker. The container is named nextcloud, unsurprisingly.  

Now, to view the logs of the container named nextcloud, use:

docker logs nextcloud

Here’s a truncated version of the output of the above command:

172.18.0.2 - - [23/Jul/2021:19:36:09 +0000] "HEAD /.env HTTP/1.1" 302 1571 "-" "python-requests/2.26.0"
172.18.0.2 - - [23/Jul/2021:19:49:52 +0000] "HEAD /c99.php HTTP/1.1" 302 1565 "-" "python-requests/2.26.0"
172.18.0.2 - - [24/Jul/2021:16:25:23 +0000] "HEAD /backup.tar HTTP/1.1" 302 1571 "-" "python-requests/2.26.0"
172.18.0.2 - - [24/Jul/2021:16:25:24 +0000] "HEAD /backup.zip HTTP/1.1" 302 1569 "-" "python-requests/2.26.0"
172.18.0.2 - - [25/Jul/2021:20:36:01 +0000] "GET / HTTP/1.1" 302 1590 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko; compatible; BW/1.1; bit.ly/2W6Px8S) Chrome/84.0.4147.105 Safari/537.36"
172.18.0.2 - - [25/Jul/2021:20:36:07 +0000] "GET /custom_apps/richdocumentscode/proxy.php?req=/hosting/capabilities HTTP/1.1" 200 721 "-" "Nextcloud Server Crawler"
172.18.0.2 - - [25/Jul/2021:20:36:04 +0000] "GET /login HTTP/1.1" 200 7501 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko; compatible; BW/1.1; bit.ly/2W6Px8S) Chrome/84.0.4147.105 Safari/537.36"

Too much of logs? The good thing is that there are various options that make viewing docker logs a lot easier, just like logs in Linux.

Tail Docker logs to view only certain number of lines

Docker logs command has --tail attribute that can be used in a fashion similar to the tail command.

Which means, you can use it to display only a certain number of lines of Docker logs from the end.

For example, to view the last 50 lines of a container, you can use:

docker logs --tail 50 container_name_or_ID

You may use the above command in this fashion as well

docker logs -n=50 container_name_or_ID

Viewing Docker logs in real-time on a live container

You can totally view the container logs in real time. To “follow” the logs, use the --follow or the -f attribute.

docker logs -f container_name_or_ID

When you run docker logs with follow option, you’ll notice that the new log lines will be reported from the container as time progresses.

To exit, you can simply use the Ctrl+C key combination and drop back to the terminal prompt.

Most of the options in the docker logs sub-command can be combined to produce a desired result.

For example, docker logs -f will flood the screen with all the logs from the beginning. You wouldn’t want that. What you can do is to combine both tail and follow options like this:

docker logs -f --tail 20 container_name_or_ID

The above command will show the last 20 lines of the logs and then follow the logs in real time.

When updating your app containers with scaling, the above command can be very helpful before you remove an older container.

View timestamp in Docker logs

If you also want to see the timestamp of the log entries, you can use the -t option.

docker logs -t container_name_or_ID

This can easily be combined with other options like --follow and --tail.

The command below will show the last 10 lines of the log file of a given container with timestamps attached to each of them

docker logs -n=10 -t container_name_or_ID

Viewing Docker logs in a specified time period

When you are investigating an issue, time can be a critical factor, in which case the --since and --until flags could prove very helpful.

For example, if you are investigating an issue that occurred in the past 24 hours, the following command will show the logged contents of whatever happened only during that time:

docker logs --since 1440m -t container_name_or_ID

1440m in the above command denotes 24×60 minutes. Adding the -t or the --timestamps flag ensures the reported lines get labeled with a timestamp for you to comprehend incidents or errors even more easily. I’d suggest adding it when inquiring any container.

Similarly, if you require the log details after the first 24 hours of initiating deployment, the equivalent command would be:

docker logs --until 1440m -t nextcloud

Other than specifying time in minutes, the above two flags can also be used with a specific timestamp that -t generates. The format is like 2021-07-28T06:20:00.

docker logs --since 2021-07-28 -t container_name_or_ID

The above command will show the logs from 28th July 2021.

For a complete overview of docker logs, you can also check its man page with man docker-logs.

Accessing Docker logs from within the container

In some interesting use-cases, you may want to go for a hybrid approach, where you access the application specific logs from within the containers.

To do that, you enter the Docker container:

docker exec -it container_name_or_ID sh

And then you can use the regular Linux tools to get application related logs. One approach would be to get the process ID of the desired service using the ps command:

ps aux

Get the details on this process:

cat /proc/PID_of_process/fd/1

Docker system service logs

If you wish to see the logs of the Docker service itself on the host, you can use journalctl if you are on Ubuntu 16.04 or later:

sudo journalctl -u docker

How to Use journalctl Command to Analyze Logs in Linux

Beginner’s guide to using journalctl commands for viewing, filtering and analyzing journal logs in Linux.

Abhishek Prakash

Where are Docker logs stored?

You should find the docker logs in the /var/lib/docker/containers directory on the host system. This directory contains the log files related to all containers in their individual directories. You can identify the directories with the container ID.

I used the docker ps to find that 70f19fde9076 is the container ID of the Nextcloud container.

If I look into the directory where docker logs are stored:

avimanyu@localhost:~$ sudo ls -lh /var/lib/docker/containers

total 16K
drwx------ 4 root root 4.0K Jul 27 18:48 0efe12b28562c42619e533ad5f524d56740a7a3739d9e082c758bac95ae2a46f
drwx------ 4 root root 4.0K Jul 27 18:57 12c55f365f93ecb7f91e40bc130ddc2409216a61bbb244cd045a22b4513416d3
drwx------ 4 root root 4.0K Jul 27 18:58 70f19fde907672b9a6e5ff3b7db0c9ecbcb68d419712cb04d03d77694cd2ca4e
drwx------ 4 root root 4.0K Jul 27 18:57 a436399ef16a3efc0a909b9c3f725938e595e0b8fd34644b13f28b2c9bcb4ed7

There are currently four containers running, and you can see that the third one matches the one we need to look into (it begins with 70f19fde9076).

If you check the contents of this directory, you can see that our log file sits right there!

avimanyu@localhost:~$ sudo ls -lh /var/lib/docker/containers/70f19fde907672b9a6e5ff3b7db0c9ecbcb68d419712cb04d03d77694cd2ca4e

total 192K
-rw-r----- 1 root root 150K Jul 27 18:58 70f19fde907672b9a6e5ff3b7db0c9ecbcb68d419712cb04d03d77694cd2ca4e-json.log
drwx------ 2 root root 4.0K Jul 19 17:10 checkpoints
-rw------- 1 root root 5.5K Jul 27 18:58 config.v2.json
-rw-r--r-- 1 root root 1.5K Jul 27 18:58 hostconfig.json
-rw-r--r-- 1 root root   13 Jul 27 18:58 hostname
-rw-r--r-- 1 root root  198 Jul 27 18:58 hosts
drwx------ 3 root root 4.0K Jul 19 17:10 mounts
-rw-r--r-- 1 root root   79 Jul 27 18:58 resolv.conf
-rw-r--r-- 1 root root   71 Jul 27 18:58 resolv.conf.hash

Therefore, the corresponding log file is 70f19fde907672b9a6e5ff3b7db0c9ecbcb68d419712cb04d03d77694cd2ca4e-json.log which is the same file that you were reading when I ran the docker logs command in the beginning.

Let me quickly verify that:

avimanyu@localhost:~$ sudo cat /var/lib/docker/containers/70f19fde907672b9a6e5ff3b7db0c9ecbcb68d419712cb04d03d77694cd2ca4e/70f19fde907672b9a6e5ff3b7db0c9ecbcb68d419712cb04d03d77694cd2ca4e-json.log

{"log":"172.18.0.2 - - [23/Jul/2021:19:36:09 +0000] \"HEAD /.env HTTP/1.1\" 302 1571 \"-\" \"python-requests/2.26.0\"\n","stream":"stdout","time":"2021-07-23T19:36:09.837857567Z"}
{"log":"172.18.0.2 - - [23/Jul/2021:19:49:52 +0000] \"HEAD /c99.php HTTP/1.1\" 302 1565 \"-\" \"python-requests/2.26.0\"\n","stream":"stdout","time":"2021-07-23T19:49:52.996108799Z"}
{"log":"172.18.0.2 - - [24/Jul/2021:16:25:23 +0000] \"HEAD /backup.tar HTTP/1.1\" 302 1571 \"-\" \"python-requests/2.26.0\"\n","stream":"stdout","time":"2021-07-24T16:25:23.445225166Z"}
{"log":"172.18.0.2 - - [24/Jul/2021:16:25:24 +0000] \"HEAD /backup.zip HTTP/1.1\" 302 1569 \"-\" \"python-requests/2.26.0\"\n","stream":"stdout","time":"2021-07-24T16:25:24.772881041Z"}
{"log":"172.18.0.2 - - [25/Jul/2021:20:36:01 +0000] \"GET / HTTP/1.1\" 302 1590 \"-\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko; compatible; BW/1.1; bit.ly/2W6Px8S) Chrome/84.0.4147.105 Safari/537.36\"\n","stream":"stdout","time":"2021-07-25T20:36:03.678967877Z"}
{"log":"172.18.0.2 - - [25/Jul/2021:20:36:07 +0000] \"GET /custom_apps/richdocumentscode/proxy.php?req=/hosting/capabilities HTTP/1.1\" 200 721 \"-\" \"Nextcloud Server Crawler\"\n","stream":"stdout","time":"2021-07-25T20:36:07.404618408Z"}
{"log":"172.18.0.2 - - [25/Jul/2021:20:36:04 +0000] \"GET /login HTTP/1.1\" 200 7501 \"-\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko; compatible; BW/1.1; bit.ly/2W6Px8S) Chrome/84.0.4147.105 Safari/537.36\"\n","stream":"stdout","time":"2021-07-25T20:36:07.619020402Z"}

The log contents are the same, but since I’m reading the log file directly from the host, this has a lot of jargon compared to the docker logs command used earlier.

Enabling Log Rotation for Docker (JSON)

By default, for JSON file based logging, log rotation on Docker is disabled.

This may pose a problem with the disk space if the log files grows bigger in size. Our Docker based Ghost instance saw its log files going up to 20 GB in size. You would want to avoid such situation by enabling log rotation.

To enable log rotation for Docker, edit the /etc/docker/daemon.json file:

sudo nano /etc/docker/daemon.json

Append the following lines and save the file:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3" 
  }
}

Restart Docker daemon:

sudo systemctl restart docker

The above setup is of course relevant to a generic Docker installation, which has JSON logging set as default. So do note that every other logging mechanism (listed below) has its own way of implementing rotation.

A quick word about logging drivers

Did you notice “json” in the log filename from earlier? That’s because JSON File is the default logging driver on Docker.

Apart from JSON, there are many other logging mechanisms to choose from as well:

  • Local file
  • Logentries
  • Graylog Extended Format(GELF)
  • Syslog
  • Amazon Cloudwatch Logs(AWS)
  • Event Tracing in Windows(ETW)
  • Fluentd
  • Google Cloud Project Logs(GCP)
  • Journald
  • Splunk
  • Logstash

For large-scale deployments, GELF, AWS, GCP and Fluentd are recommended as they implement a centralized approach. But for small scale, JSON does the job just fine, while Local, Syslog and Journald are also quite suitable. Syslog and Logstash are particularly very helpful if complex log analysis becomes a requirement. ETW is Windows specific, whereas Splunk is focused on remote logging.

Starting from Docker Engine 20.10, a new feature called “dual-logging” has been introduced that ensures executing the docker logs command as well as performing log rotation irrespective of the logging driver in effect.

Summary

In this article, I’ve begun with the basics of how to view the logs for any Docker container, both at the container and host-system level. I’ve also showed you how to locate the physical location of container-specific log files residing on your host-system. I briefly showed you how to check the logs for the Docker service on the host itself.

Later, I’ve discussed logging drivers with focus on the default mechanism and also highlighted the new dual logging feature.

I hope these pointers help you in your daily monitoring or learning activities. Any more thoughts and suggestions are more than welcome! Please share them in the comment section below.

docker logs

Docker, a popular OS-level virtualization platform that allows us to deliver applications in packages known as containers which in simple terms are isolated environments with their own software, libraries, and configuration files.

Like any other modern software, logging events and messages like warnings and errors is an inherent part of the Docker platform, which allows you to debug your applications and production issues.

We’ll be covering some simple ways in which you can manage and monitor logs for your containers. So let’s get started.

Docker Logs Command

The basic syntax to fetch logs of a container is:

$ docker logs [OPTIONS] <CONTAINER-NAME OR ID>

OR

$ docker container logs [OPTIONS] <CONTAINER-NAME OR ID>

Both of the syntaxes are essentially the same, so we’ll focus on the rest of the commands in this article as docker logs.

Though do note here that the above command is only functional for containers that are started with the json-file  or journald logging driver.

Here OPTIONS refers to the available supported flags with docker logs command, which are listed below:

Name, Shorthand Default Description
--details Show extra details provided to logs.
--follow-f Follow log output
--since Show logs since timestamp (e.g. 2021-08-28T15:23:37Z) or relative (e.g. 56m for 56 minutes)
--tail , -n all Number of lines to show from the end of the logs
--timestamps, -t Show timestamps
--until API 1.35+
Show logs before a timestamp (e.g. 2021-08-28T15:23:37Z) or relative (e.g. 56m for 56 minutes)

Example:

$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS        PORTS     NAMES
28913415ed22   nginx     "/docker-entrypoint.…"   2 seconds ago   Up 1 second   80/tcp    gifted_edison
$ docker logs 28913415ed22
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/08/28 09:02:59 [notice] 1#1: using the "epoll" event method
2021/08/28 09:02:59 [notice] 1#1: nginx/1.21.1
2021/08/28 09:02:59 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2021/08/28 09:02:59 [notice] 1#1: OS: Linux 5.8.0-1039-azure
2021/08/28 09:02:59 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/08/28 09:02:59 [notice] 1#1: start worker processes
2021/08/28 09:02:59 [notice] 1#1: start worker process 31
2021/08/28 09:02:59 [notice] 1#1: start worker process 32
$

Docker Logs Location

Docker, by default, captures the standard output (and standard error) of all your containers and writes them in files using the JSON format. This is achieved using JSON File logging driver or json-file. These logs are by default stored at container-specific locations under /var/lib/docker filesystem.

/var/lib/docker/containers/<container_id>/<container_id>-json.log

As an example, for my redis container listed below, I can check its json logfile as shown in the snippet below:

$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                   NAMES
551c9273bbea   redis     "docker-entrypoint.s…"   19 minutes ago   Up 19 minutes   6379/tcp                                redis
6cc871763df1   nginx     "/docker-entrypoint.…"   7 hours ago      Up 7 hours      0.0.0.0:8080->80/tcp, :::8080->80/tcp   nostalgic_wescoff
$ sudo ls -l /var/lib/docker/containers/551c9273bbea6eaf66523ed735866b9ebe6924c3b504dfeb44bef90e69d59c73/551c9273bbea6eaf66523ed735866b9ebe6924c3b504dfeb44bef90e69d59c73-json.log
-rw-r----- 1 root root 1437 Aug 28 16:53 /var/lib/docker/containers/551c9273bbea6eaf66523ed735866b9ebe6924c3b504dfeb44bef90e69d59c73/551c9273bbea6eaf66523ed735866b9ebe6924c3b504dfeb44bef90e69d59c73-json.log
$ sudo tail -10 /var/lib/docker/containers/551c9273bbea6eaf66523ed735866b9ebe6924c3b504dfeb44bef90e69d59c73/551c9273bbea6eaf66523ed735866b9ebe6924c3b504dfeb44bef90e69d59c73-json.log
{"log":"1:C 28 Aug 2021 16:53:42.160 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo\n","stream":"stdout","time":"2021-08-28T16:53:42.16031257Z"}
{"log":"1:C 28 Aug 2021 16:53:42.160 # Redis version=6.2.5, bits=64, commit=00000000, modified=0, pid=1, just started\n","stream":"stdout","time":"2021-08-28T16:53:42.160337871Z"}
{"log":"1:C 28 Aug 2021 16:53:42.160 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf\n","stream":"stdout","time":"2021-08-28T16:53:42.160342171Z"}
{"log":"1:M 28 Aug 2021 16:53:42.160 * monotonic clock: POSIX clock_gettime\n","stream":"stdout","time":"2021-08-28T16:53:42.160792578Z"}
{"log":"1:M 28 Aug 2021 16:53:42.161 * Running mode=standalone, port=6379.\n","stream":"stdout","time":"2021-08-28T16:53:42.161148683Z"}
{"log":"1:M 28 Aug 2021 16:53:42.161 # Server initialized\n","stream":"stdout","time":"2021-08-28T16:53:42.161170984Z"}
{"log":"1:M 28 Aug 2021 16:53:42.161 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.\n","stream":"stdout","time":"2021-08-28T16:53:42.161186984Z"}
{"log":"1:M 28 Aug 2021 16:53:42.161 * Ready to accept connections\n","stream":"stdout","time":"2021-08-28T16:53:42.161484389Z"}
$

Show Extra Details

To show extra details provided to logs, use --details flag.

Example:

$ docker logs 6cc871763df1 --details
 /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
 /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
 /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
 /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
 /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
 /docker-entrypoint.sh: Configuration complete; ready for start up
 2021/08/28 10:29:05 [notice] 1#1: using the "epoll" event method
 2021/08/28 10:29:05 [notice] 1#1: nginx/1.21.1
 2021/08/28 10:29:05 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
 2021/08/28 10:29:05 [notice] 1#1: OS: Linux 5.8.0-1039-azure
 2021/08/28 10:29:05 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
 2021/08/28 10:29:05 [notice] 1#1: start worker processes
 2021/08/28 10:29:05 [notice] 1#1: start worker process 33
 2021/08/28 10:29:05 [notice] 1#1: start worker process 34
 172.17.0.1 - - [28/Aug/2021:10:29:26 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.68.0" "-"
$

Follow Log Output

You can use --follow or -f flag to follow the log output. This allows you to monitor new updates in the log stream from continuously STDOUT and STDERR.

Example:

$ docker logs 6cc871763df1 -f
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/08/28 10:29:05 [notice] 1#1: using the "epoll" event method
2021/08/28 10:29:05 [notice] 1#1: nginx/1.21.1
2021/08/28 10:29:05 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2021/08/28 10:29:05 [notice] 1#1: OS: Linux 5.8.0-1039-azure
2021/08/28 10:29:05 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/08/28 10:29:05 [notice] 1#1: start worker processes
2021/08/28 10:29:05 [notice] 1#1: start worker process 33
2021/08/28 10:29:05 [notice] 1#1: start worker process 34
172.17.0.1 - - [28/Aug/2021:10:29:26 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.68.0" "-"

Tail Logs

Container logs can be tailed to limit the number of output shown on the screen with --tail or -n flag. By default, this flag assumes all as an argument that shows the complete log stream. To show a fixed number of lines from the end of the logs, specify a positive integer number following --tail or -n flag.

Example:

$ docker logs 6cc871763df1 -n 10
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/08/28 10:29:05 [notice] 1#1: using the "epoll" event method
2021/08/28 10:29:05 [notice] 1#1: nginx/1.21.1
2021/08/28 10:29:05 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2021/08/28 10:29:05 [notice] 1#1: OS: Linux 5.8.0-1039-azure
2021/08/28 10:29:05 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/08/28 10:29:05 [notice] 1#1: start worker processes
2021/08/28 10:29:05 [notice] 1#1: start worker process 33
2021/08/28 10:29:05 [notice] 1#1: start worker process 34
172.17.0.1 - - [28/Aug/2021:10:29:26 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.68.0" "-"
$

Show Logs Since

We can limit log output by using --since flag and giving a timestamp like an absolute value with syntax 2021-08-28T15:23:37Z or a relative one like 56m for 56 minutes.

The --since option shows only the container logs generated after a given date. You can specify the date as an RFC 3339 date, a UNIX timestamp, or a Go duration string (e.g. 1m30s3h). The local time zone on the client will be used if you do not provide either a Z or a +-00:00 time zone offset at the end of the timestamp. You can combine the --since option with either or both of the --follow or --tail options.

Example:

$ docker logs --since=1m nostalgic_wescoff
172.17.0.1 - - [28/Aug/2021:15:19:24 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.68.0" "-"
172.17.0.1 - - [28/Aug/2021:15:19:25 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.68.0" "-"
$

In the above example, logs since only 2 minutes are shown where nostalgic_wescoff is the auto-generated name assigned for the nginx container.

Show Logs Until

Like --since flag, docker logs also support --until flag, which shows logs before the given timestamp. Similarly, the timestamp follows a similar convention as earlier and can be specified as an absolute value with syntax 2021-08-28T15:23:37Z or a relative one like 56m for 56 minutes.

Example:

$ docker logs --until=1h30m nostalgic_wescoff
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/08/28 10:29:05 [notice] 1#1: using the "epoll" event method
2021/08/28 10:29:05 [notice] 1#1: nginx/1.21.1
2021/08/28 10:29:05 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2021/08/28 10:29:05 [notice] 1#1: OS: Linux 5.8.0-1039-azure
2021/08/28 10:29:05 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/08/28 10:29:05 [notice] 1#1: start worker processes
2021/08/28 10:29:05 [notice] 1#1: start worker process 33
2021/08/28 10:29:05 [notice] 1#1: start worker process 34
172.17.0.1 - - [28/Aug/2021:10:29:26 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.68.0" "-"
$

In the above example, all logs before 1 hour 30 minutes are shown.

Show Timestamps

Many container applications offer timestamps built in their log output, so Docker also shows them with docker logs command. If you need Docker to explicitly prefix its timestamps in the output, use --timestamps or -t flag.

Example:

$ docker logs -t redis
2021-08-28T16:53:42.160312570Z 1:C 28 Aug 2021 16:53:42.160 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2021-08-28T16:53:42.160337871Z 1:C 28 Aug 2021 16:53:42.160 # Redis version=6.2.5, bits=64, commit=00000000, modified=0, pid=1, just started
2021-08-28T16:53:42.160342171Z 1:C 28 Aug 2021 16:53:42.160 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
2021-08-28T16:53:42.160792578Z 1:M 28 Aug 2021 16:53:42.160 * monotonic clock: POSIX clock_gettime
2021-08-28T16:53:42.161148683Z 1:M 28 Aug 2021 16:53:42.161 * Running mode=standalone, port=6379.
2021-08-28T16:53:42.161170984Z 1:M 28 Aug 2021 16:53:42.161 # Server initialized
2021-08-28T16:53:42.161186984Z 1:M 28 Aug 2021 16:53:42.161 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
2021-08-28T16:53:42.161484389Z 1:M 28 Aug 2021 16:53:42.161 * Ready to accept connections
$

Merge Flags

Docker offers to combine certain flags to get more filtered output rather than print all of the log contents on the screen. As a simple example, we can combine --tail flag with --since to get more restricted output.

Example:

$ docker logs --since=2h -f nostalgic_wescoff
172.17.0.1 - - [28/Aug/2021:15:19:24 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.68.0" "-"
172.17.0.1 - - [28/Aug/2021:15:19:25 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.68.0" "-"

This can work with other flags as well.

Filter With Shell Utilities

Linux shell utilities can also be used for more dexterity in the log output. Utilities like grep, head, tail etc. can be piped to docker logs output for more advanced operations.

Example:

$ docker logs --since=7h nostalgic_wescoff 2>&1 | grep GET
172.17.0.1 - - [28/Aug/2021:10:29:26 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.68.0" "-"
172.17.0.1 - - [28/Aug/2021:15:19:24 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.68.0" "-"
172.17.0.1 - - [28/Aug/2021:15:19:25 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.68.0" "-"
$

Do note here that we need to redirect log streams to provide single piped input for grep using 2>&1.

Summary 👩‍💻

Docker is a versatile platform that offers numerous features to administer its environment. Managing logs for a system is one of the essential skills which every system administrator should know. Managing logs in Docker is easy once you know the available command and possible flags as per your requirements.

For further read on Docker and its functionalities, refer to Docker’s documentation.

If you deploy containers with Docker, at some point you’ll need to troubleshoot. Jack Wallen shows you how to do so with the logs command.

Containers can be a tricky solution to deploy and manage. Given there are so many moving pieces to this puzzle, it’s often very challenging to even know where to begin when trouble strikes. Is it the host? What about the network? Maybe it’s the provider? Or maybe it’s just a container that’s gone awry.

After you’ve found nothing wrong with your host, network, or provider, it’s time to look at what is probably most often the root cause of the problem…the container itself.

Although containers have become the darling of the IT ball, they are far from perfect. Things go wrong. And given how complicated containers are, they often go wrong at the very heart of your deployments.

SEE: Checklist: Server inventory (TechRepublic Premium)

So what do you do? How do you troubleshoot a single container? Fortunately, the developers thought about that and added a command that allows you to check the logs of a container. Let’s find out how to use this handy tool.

What you’ll need

The only thing you’ll need to view Docker container logs is Docker deployed to a machine. It doesn’t matter what the platform is, so long as it supports Docker. I’ll be demonstrating on Ubuntu Server 20.04.

With that single requisite out of the way, let’s view those logs.

How to use the Docker log command

I’m going to deploy an NGINX container to demonstrate how container logs are viewed. So log into your Docker host and deploy the NGINX container with the command:

docker run --name docker-nginx -p 8080:80 -d nginx

Give it a second and you should have a new NGINX container running, named docker-nginx. Open a web browser and point it to http://SERVER:8080 (Where SERVER is the IP address of the hosting server) and you should see the NGINX welcome page.

But let’s say that page doesn’t appear? What gives? Why is my container not running? To find out, we’d issue the command:

docker logs docker-nginx

Docker will immediately print out all of the log file information it has (Figure A).

Figure A

The Docker logs of our newly deployed NGINX container.

Of course, our container doesn’t have any errors, because it’s running just fine. Even so, that’s a lot of output to comb through. Let’s say you only want to view the last five lines from the log file. For that you could issue the command:

docker logs docker-nginx --tail 5

Or maybe you want to view the logs as they are written (so you can more easily troubleshoot a container as it sends and receives data). For that you will use the follow option like so:

docker logs docker-nginx --follow

This will continue outputting information, so you can watch the logs being written in real time (Figure B).

Figure B

Following the Docker log file for our running docker-nginx container.

Let’s say you know something went wrong within the last hour and you want to only view the logs that have been written within that timeframe. For that, issue the command:

docker logs docker-nginx --since=60m

Or maybe you know something went wrong prior to an hour ago. You can use the until option to display every log file written prior with the command:

docker logs docker-nginx --until=60m

Finally, you might want to add a few extra details to your log output, which is done with the –details option:

docker logs docker-nginx --details

Between these commands, you should have everything you need to troubleshoot a specific Docker container. One thing to note is that you can substitute the Container ID for the Name (as I’ve used above). To find the associated Container ID, issue the command:

docker ps -a

When you run the docker logs command using the Container ID, you only need to use the first four characters of the ID, as in:

docker logs 118b --details

And that’s all there is to viewing the logs of your Docker containers.

Illustration: Lisa Hornung/TechRepublic

As we are all aware the future of application deployment is containerization, and more and more application deployment is moving to docker. It is always good to have a complete understanding of the docker logs. In this blog, I will take you through the docker logs. So let’s get started.

What is docker logs?

Docker provides a command called logs, using which we can analyze the docker container logs. When a docker container starts, it will add all the activity in the logs file, and using the log command; we can fetch all the logs.

There are different ways users can access the docker logs, and the docker logs command is one of them.

docker logs example

With the docker logs command, we can access the entire container logs. The general syntax of the docker logs command is:

docker logs [OPTIONS] CONTAINER

You can fetch the docker logs documentation by typing:

docker logs --help

Usage:  docker logs [OPTIONS] CONTAINER

Fetch the logs of a container

Options:
      --details        Show extra details provided to logs
  -f, --follow         Follow log output
      --since string   Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)
  -n, --tail string    Number of lines to show from the end of the logs (default "all")
  -t, --timestamps     Show timestamps
      --until string   Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)

docker logs example

This session will understand how docker logs help us debug the issues while deploying an image.

Example 1: Nginx container logs

In this example, we will be deploying an Nginx docker container and trying to fetch the logs generated by the Nginx container.

Run an Nginx container using the below command:

docker run -d --name my-nginx -p 8080:80 nginx:latest
af8512b74be6f19171ed93822d82f06183670bd44a8e689d1f0157c71976cc88
➜  ~

Verify if the container is running:

docker ps
CONTAINER ID   IMAGE            COMMAND                  CREATED         STATUS         PORTS                                   NAMES
af8512b74be6   nginx:latest     "/docker-entrypoint.…"   8 seconds ago   Up 4 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp   my-nginx

The Nginx container logs can be found by typing the below command:

docker logs my-nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/07/09 16:05:17 [notice] 1#1: using the "epoll" event method
2021/07/09 16:05:17 [notice] 1#1: nginx/1.21.0
2021/07/09 16:05:17 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2021/07/09 16:05:17 [notice] 1#1: OS: Linux 5.10.25-linuxkit
2021/07/09 16:05:17 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/07/09 16:05:17 [notice] 1#1: start worker processes
2021/07/09 16:05:17 [notice] 1#1: start worker process 31
2021/07/09 16:05:17 [notice] 1#1: start worker process 32

From the above logs, we can see that the Nginx container starts without any error.

Now go to localhost:8080 to fetch the docker container UI.

docker logs

let’s rerun the docker logs command and see if the Nginx container has logged any more activity:

docker logs my-nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/07/09 16:05:17 [notice] 1#1: using the "epoll" event method
2021/07/09 16:05:17 [notice] 1#1: nginx/1.21.0
2021/07/09 16:05:17 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2021/07/09 16:05:17 [notice] 1#1: OS: Linux 5.10.25-linuxkit
2021/07/09 16:05:17 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/07/09 16:05:17 [notice] 1#1: start worker processes
2021/07/09 16:05:17 [notice] 1#1: start worker process 31
2021/07/09 16:05:17 [notice] 1#1: start worker process 32
172.17.0.1 - - [09/Jul/2021:16:10:00 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
2021/07/09 16:10:00 [error] 32#32: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:8080/"
172.17.0.1 - - [09/Jul/2021:16:10:00 +0000] "GET /favicon.ico HTTP/1.1" 404 153 "http://localhost:8080/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"

The Nginx container has logged logs for any get request via UI. This log comes in very handy if you wish to troubleshoot any error in container deployment.

docker logs command

In this session, we will go through all the docker logs commands that the data ops engineer should know.

docker logs -f command

The Docker logs -f command is used to get the logs in real-time as they are generated. For the above Nginx, container let’s run the logs command and pass the -f flag.

docker logs -f my-nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/07/09 16:05:17 [notice] 1#1: using the "epoll" event method
2021/07/09 16:05:17 [notice] 1#1: nginx/1.21.0
2021/07/09 16:05:17 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2021/07/09 16:05:17 [notice] 1#1: OS: Linux 5.10.25-linuxkit
2021/07/09 16:05:17 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/07/09 16:05:17 [notice] 1#1: start worker processes
2021/07/09 16:05:17 [notice] 1#1: start worker process 31
2021/07/09 16:05:17 [notice] 1#1: start worker process 32
172.17.0.1 - - [09/Jul/2021:16:10:00 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
2021/07/09 16:10:00 [error] 32#32: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:8080/"
172.17.0.1 - - [09/Jul/2021:16:10:00 +0000] "GET /favicon.ico HTTP/1.1" 404 153 "http://localhost:8080/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"

Goto localhost:8080 and try to access the Nginx URL and refresh the page multiple times. You will observe that for each gets request; new logs will be displayed in the docker logs -f command:

docker logs -f my-nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/07/09 16:05:17 [notice] 1#1: using the "epoll" event method
2021/07/09 16:05:17 [notice] 1#1: nginx/1.21.0
2021/07/09 16:05:17 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2021/07/09 16:05:17 [notice] 1#1: OS: Linux 5.10.25-linuxkit
2021/07/09 16:05:17 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/07/09 16:05:17 [notice] 1#1: start worker processes
2021/07/09 16:05:17 [notice] 1#1: start worker process 31
2021/07/09 16:05:17 [notice] 1#1: start worker process 32
172.17.0.1 - - [09/Jul/2021:16:10:00 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
2021/07/09 16:10:00 [error] 32#32: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:8080/"
172.17.0.1 - - [09/Jul/2021:16:10:00 +0000] "GET /favicon.ico HTTP/1.1" 404 153 "http://localhost:8080/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:17 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:18 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:19 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:20 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:24 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"

These logs will be very beneficial if you wish to know who visited your website and using which browser search engine.

docker logs | grep

Docker logs followed by grepping are another way to grep only the logs we are interested in.

Suppose, in the above example, you wish to get only the GET request to Nginx web UI. You can achieve this using the below command:

docker logs my-nginx 2>&1 | grep "Apple"
172.17.0.1 - - [09/Jul/2021:16:10:00 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [09/Jul/2021:16:10:00 +0000] "GET /favicon.ico HTTP/1.1" 404 153 "http://localhost:8080/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:17 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:18 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:19 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:20 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:24 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"

you have to use 2>&1 because the docker container is logging to stderr, and piping the grep command will only work for stdout.

docker logs head

With docker logs followed by the head command, you can fetch only the top logs generated by the docker container.

docker logs my-nginx | head
2021/07/09 16:05:17 [notice] 1#1: using the "epoll" event method
2021/07/09 16:05:17 [notice] 1#1: nginx/1.21.0
2021/07/09 16:05:17 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2021/07/09 16:05:17 [notice] 1#1: OS: Linux 5.10.25-linuxkit
2021/07/09 16:05:17 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/07/09 16:05:17 [notice] 1#1: start worker processes
2021/07/09 16:05:17 [notice] 1#1: start worker process 31
2021/07/09 16:05:17 [notice] 1#1: start worker process 32
2021/07/09 16:10:00 [error] 32#32: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:8080/"
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
172.17.0.1 - - [09/Jul/2021:16:10:00 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [09/Jul/2021:16:10:00 +0000] "GET /favicon.ico HTTP/1.1" 404 153 "http://localhost:8080/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"

By default, the head command will give you the top 10 rows.

the Above logs contain stderr as well, and if you wish to get rid of them, you have to use the below command:

docker logs my-nginx 2>&1 | head
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/07/09 16:05:17 [notice] 1#1: using the "epoll" event method
2021/07/09 16:05:17 [notice] 1#1: nginx/1.21.0

Similarly, you can get the specific number of rows by passing -n after the head command.

n= number of rows to be fetched.

docker logs my-nginx 2>&1| head -5
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf

docker logs tail

Like the docker logs head command, we can use the docker logs tail command to get the bottom n rows.

docker logs my-nginx 2>&1| tail
2021/07/09 16:05:17 [notice] 1#1: start worker process 31
2021/07/09 16:05:17 [notice] 1#1: start worker process 32
172.17.0.1 - - [09/Jul/2021:16:10:00 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
2021/07/09 16:10:00 [error] 32#32: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:8080/"
172.17.0.1 - - [09/Jul/2021:16:10:00 +0000] "GET /favicon.ico HTTP/1.1" 404 153 "http://localhost:8080/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:17 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:18 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:19 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:20 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:24 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
➜  ~

Suppose you wish to get only 2 button rows. Run the below command to do so.

docker logs my-nginx 2>&1| tail -2
172.17.0.1 - - [10/Jul/2021:06:32:20 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:24 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
➜  ~

docker logs since

The docker logs since is another excellent command to fetch the logs from a specific time until now. Let’s run this command in the my-Nginx container and verify the output.

docker logs --since 2021-07-10 my-nginx
172.17.0.1 - - [10/Jul/2021:06:32:17 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:18 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:19 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:20 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:24 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"

In the above command, we have fetched the logs from 07 July 2021

docker logs until

docker until command is opposite of the since command. Using the docker until command, we can get logs before a timestamp.

docker logs --until 2021-07-10 my-nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/07/09 16:05:17 [notice] 1#1: using the "epoll" event method
2021/07/09 16:05:17 [notice] 1#1: nginx/1.21.0
2021/07/09 16:05:17 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2021/07/09 16:05:17 [notice] 1#1: OS: Linux 5.10.25-linuxkit
2021/07/09 16:05:17 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/07/09 16:05:17 [notice] 1#1: start worker processes
2021/07/09 16:05:17 [notice] 1#1: start worker process 31
2021/07/09 16:05:17 [notice] 1#1: start worker process 32
172.17.0.1 - - [09/Jul/2021:16:10:00 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
2021/07/09 16:10:00 [error] 32#32: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:8080/"
172.17.0.1 - - [09/Jul/2021:16:10:00 +0000] "GET /favicon.ico HTTP/1.1" 404 153 "http://localhost:8080/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"

docker logs location

The Docker logs command is an excellent command to get information about the docker containers logs. But in case you are curious, how you can get information about the location of the log?

We can use the docker inspect command to get all information about the docker container, and you can –format command to get the logPath location.

docker inspect --format={{.LogPath}} my-nginx
/var/lib/docker/containers/af8512b74be6f19171ed93822d82f06183670bd44a8e689d1f0157c71976cc88/af8512b74be6f19171ed93822d82f06183670bd44a8e689d1f0157c71976cc88-json.log

docker logs of an exited container

So far, we have seen how we can get the logs into a running container, but how can you retrieve the logs of an exited container?

The answer to this question is quite simple. In the same way you get the logs of a running container, you can get logs of a stopped container.

Let’s stop the above my-nginx container which we ran.

docker kill my-nginx
my-nginx

Let’s verify if the container is exited.

docker ps -a
CONTAINER ID   IMAGE             COMMAND                  CREATED        STATUS                       PORTS                                   NAMES
af8512b74be6   nginx:latest      "/docker-entrypoint.…"   16 hours ago   Exited (137) 8 seconds ago                                           my-nginx

Now let’s try to fetch this exited nginx container log.

docker logs af8512b74be6
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/07/09 16:05:17 [notice] 1#1: using the "epoll" event method
2021/07/09 16:05:17 [notice] 1#1: nginx/1.21.0
2021/07/09 16:05:17 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2021/07/09 16:05:17 [notice] 1#1: OS: Linux 5.10.25-linuxkit
2021/07/09 16:05:17 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/07/09 16:05:17 [notice] 1#1: start worker processes
2021/07/09 16:05:17 [notice] 1#1: start worker process 31
2021/07/09 16:05:17 [notice] 1#1: start worker process 32
172.17.0.1 - - [09/Jul/2021:16:10:00 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
2021/07/09 16:10:00 [error] 32#32: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:8080/"
172.17.0.1 - - [09/Jul/2021:16:10:00 +0000] "GET /favicon.ico HTTP/1.1" 404 153 "http://localhost:8080/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:17 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:18 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:19 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:20 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"
172.17.0.1 - - [10/Jul/2021:06:32:24 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" "-"

NOTE: You can fetch the container logs by container name or by container id.

docker logs clear

In case you wish to clear all the logs generated by the docker container. There are many ways to achieve that, but one of the easiest ways is to use the below command.

$(docker inspect --format='{{.LogPath}}' my-nginx_lst)

We get the docker logs file name in the above command and use the> arrow to put black data in that file.

Conclusion

Finally, we have come to the end of this fantastic tutorial. Here we have learned all about the docker logs. We started with the basic docker logs command, and later we have seen how we can filter out the specific logs.I hope you enjoy this tutorial. Please do let me know in the comment box.

More to read?

Hello-world docker image

Docker httpd image

Dockerfile tutorial for begineer

Понравилась статья? Поделить с друзьями:
  • Docash golf ошибка е40
  • Dhcp сервер ошибка 20013
  • Docash golf ошибка e11
  • Dm1spn3 ошибка камаз
  • Dhcp ошибка 1056