Docker, eine beliebte Virtualisierungsplattform auf Betriebssystemebene, die es uns ermöglicht, Anwendungen in Paketen, so genannten Containern, bereitzustellen, bei denen es sich vereinfacht gesagt um isolierte Umgebungen mit eigener Software, Bibliotheken und Konfigurationsdateien handelt.

Wie jede andere moderne Software ist die Protokollierung von Ereignissen und Meldungen wie Warnungen und Fehlern ein fester Bestandteil der Docker-Plattform, mit der Sie Ihre Anwendungen und Produktionsprobleme debuggen können.

Wir werden Ihnen einige einfache Möglichkeiten vorstellen, wie Sie die Protokolle für Ihre Container verwalten und überwachen können. Fangen wir also an.

Docker Logs Befehl

Die grundlegende Syntax zum Abrufen von Protokollen eines Containers lautet:

$ docker logs [OPTIONEN] <CONTAINER-NAME ODER ID>

ODER

$ docker container logs [OPTIONEN] <CONTAINER-NAME ODER ID>

Beide Syntaxen sind im Wesentlichen gleich, daher konzentrieren wir uns in diesem Artikel auf den Rest der Befehle als docker logs.

Beachten Sie jedoch, dass der obige Befehl nur für Container funktioniert, die mit dem Protokollierungstreiber json-file oder journald gestartet werden.

OPTIONS bezieht sich hier auf die verfügbaren unterstützten Flags für den Befehl docker logs, die unten aufgeführt sind:

Name, Abkürzung Standard Beschreibung
--details Zeigt zusätzliche Details in den Protokollen an.
-follow, -f Protokollausgabe verfolgen
--since Zeigt Protokolle seit Zeitstempel (z.B. 2021-08-28T15:23:37Z) oder relativ (z.B. 56m für 56 Minuten)
--tail , -n alle Anzahl der Zeilen, die ab dem Ende der Protokolle angezeigt werden sollen
--Zeitstempel, -t Zeigt Zeitstempel an
--until API 1.35
Zeigt Protokolle vor einem Zeitstempel (z.B. 2021-08-28T15:23:37Z) oder relativ (z.B. 56m für 56 Minuten)

Beispiel:

$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
28913415ed22 nginx "/docker-entrypoint...." vor 2 Sekunden Up 1 Sekunde 80/tcp gifted_edison
$ docker logs 28913415ed22
/docker-entrypoint.sh: /docker-entrypoint.d/ ist nicht leer, wird versuchen, die Konfiguration durchzuführen
/docker-entrypoint.sh: Sucht nach Shell-Skripten in /docker-entrypoint.d/
/docker-entrypoint.sh: Startet /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Ermitteln der Prüfsumme von /etc/nginx/conf.d/default.conf
10-listen-auf-IPv6-by-default.sh: info: Aktivieren von listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Startet /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Starten von /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Konfiguration abgeschlossen; bereit zum Starten
2021/08/28 09:02:59 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice]</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> 1#1: Verwendung der "epoll" Ereignis-Methode
2021/08/28 09:02:59 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: nginx/1.21.1
2021/08/28 09:02:59 [ <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: gebaut mit gcc 8.3.0 (Debian 8.3.0-6)
2021/08/28 09:02:59 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: OS: Linux 5.8.0-1039-azure
2021/08/28 09:02:59 [ <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/08/28 09:02:59 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: Arbeitsprozesse starten
2021/08/28 09:02:59 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: Arbeitsprozess 31 starten
2021/08/28 09:02:59 [ <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: Arbeitsprozess 32 starten
$

Speicherort der Docker Logs

Docker erfasst standardmäßig die Standardausgabe (und Standardfehler) aller Ihrer Container und schreibt sie in Dateien im JSON-Format. Dies geschieht mit dem JSON File Logging-Treiber oder json-file. Diese Protokolle werden standardmäßig an container-spezifischen Orten unter dem Dateisystem /var/lib/docker gespeichert.

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

Als Beispiel kann ich für meinen unten aufgeführten redis-Container seine json-Logdatei überprüfen, wie im folgenden Ausschnitt gezeigt:

$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
551c9273bbea redis "docker-entrypoint.s..." vor 19 Minuten Up 19 Minuten 6379/tcp redis
6cc871763df1 nginx "/docker-entrypoint...." vor 7 Stunden Up 7 Stunden 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 wird gestartet oO0OoOoO0Oo\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 # Warnung: keine Konfigurationsdatei angegeben, Verwendung der Standardkonfiguration. Um eine Konfigurationsdatei anzugeben, verwenden Sie 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 * monotone Uhr: 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 initialisiert\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! Das Speichern im Hintergrund kann bei geringem Speicher fehlschlagen. Um dieses Problem zu beheben, fügen Sie 'vm.overcommit_memory = 1' zu /etc/sysctl.conf hinzu und starten Sie dann neu oder führen Sie den Befehl 'sysctl vm.overcommit_memory=1' aus, damit dies wirksam wird.\n", "stream": "stdout", "time": "2021-08-28T16:53:42.161186984Z"}
{"log": "1:M 28 Aug 2021 16:53:42.161 * Bereit, Verbindungen zu akzeptieren\n", "stream": "stdout", "time": "2021-08-28T16:53:42.161484389Z"}
$

Extra Details anzeigen

Um zusätzliche Details in den Protokollen anzuzeigen, verwenden Sie das Flag --details.

Beispiel:

$ docker logs 6cc871763df1 --details
 /docker-entrypoint.sh: /docker-entrypoint.d/ ist nicht leer, wird versuchen, die Konfiguration durchzuführen
 /docker-entrypoint.sh: Suche nach Shell-Skripten in /docker-entrypoint.d/
 /docker-entrypoint.sh: Startet /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
 10-listen-on-ipv6-by-default.sh: info: Ermitteln der Prüfsumme von /etc/nginx/conf.d/default.conf
 10-listen-auf-IPv6-by-default.sh: info: Aktivieren von listen on IPv6 in /etc/nginx/conf.d/default.conf
 /docker-entrypoint.sh: Startet /docker-entrypoint.d/20-envsubst-on-templates.sh
 /docker-entrypoint.sh: Starten von /docker-entrypoint.d/30-tune-worker-processes.sh
 /docker-entrypoint.sh: Konfiguration abgeschlossen; bereit zum Starten
 2021/08/28 10:29:05 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice]</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> 1#1: Verwendung der "epoll" Ereignis-Methode
 2021/08/28 10:29:05 [ <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: nginx/1.21.1
 2021/08/28 10:29:05 [ <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: gebaut mit gcc 8.3.0 (Debian 8.3.0-6)
 2021/08/28 10:29:05 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: OS: Linux 5.8.0-1039-azure
 2021/08/28 10:29:05 [ <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
 2021/08/28 10:29:05 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: Arbeitsprozesse starten
 2021/08/28 10:29:05 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: Arbeitsprozess 33 starten
 2021/08/28 10:29:05 [ <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: Arbeitsprozess 34 starten
 172.17.0.1 - - [28/Aug/2021:10:29:26 0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.68.0" "-"
$

Log-Ausgabe verfolgen

Sie können die Flagge --follow oder -f verwenden, um die Protokollausgabe zu verfolgen. So können Sie neue Aktualisierungen im Protokollstrom von STDOUT und STDERR kontinuierlich verfolgen.

Beispiel:

$ docker logs 6cc871763df1 -f
/docker-entrypoint.sh: /docker-entrypoint.d/ ist nicht leer, wird versuchen, die Konfiguration durchzuführen
/docker-entrypoint.sh: Suche nach Shell-Skripten in /docker-entrypoint.d/
/docker-entrypoint.sh: Startet /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Ermitteln der Prüfsumme von /etc/nginx/conf.d/default.conf
10-listen-auf-IPv6-by-default.sh: info: Aktivieren von listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Startet /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Starten von /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Konfiguration abgeschlossen; bereit zum Starten
2021/08/28 10:29:05 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice]</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> 1#1: Verwendung der "epoll" Ereignis-Methode
2021/08/28 10:29:05 [ <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: nginx/1.21.1
2021/08/28 10:29:05 [ <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: gebaut mit gcc 8.3.0 (Debian 8.3.0-6)
2021/08/28 10:29:05 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: OS: Linux 5.8.0-1039-azure
2021/08/28 10:29:05 [ <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/08/28 10:29:05 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: Arbeitsprozesse starten
2021/08/28 10:29:05 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: Arbeitsprozess 33 starten
2021/08/28 10:29:05 [ <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: Arbeitsprozess 34 starten
172.17.0.1 - - [28/Aug/2021:10:29:26 0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.68.0" "-"

Tail Logs

Containerprotokolle können mit dem Flag --tail oder -n in den Hintergrund gestellt werden, um die Anzahl der auf dem Bildschirm angezeigten Ausgaben zu begrenzen. In der Voreinstellung nimmt dieses Flag das Argument all an, das den gesamten Protokollstrom anzeigt. Um eine feste Anzahl von Zeilen ab dem Ende der Protokolle anzuzeigen, geben Sie nach dem Flag --tail oder -n eine positive ganze Zahl an.

Beispiel:

$ docker logs 6cc871763df1 -n 10
/docker-entrypoint.sh: Konfiguration abgeschlossen; bereit zum Starten
2021/08/28 10:29:05 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice]</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> 1#1: Verwendung der Ereignismethode "epoll
2021/08/28 10:29:05 [ <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: nginx/1.21.1
2021/08/28 10:29:05 [ <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: gebaut mit gcc 8.3.0 (Debian 8.3.0-6)
2021/08/28 10:29:05 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: OS: Linux 5.8.0-1039-azure
2021/08/28 10:29:05 [ <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/08/28 10:29:05 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: Arbeitsprozesse starten
2021/08/28 10:29:05 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: Arbeitsprozess 33 starten
2021/08/28 10:29:05 [ <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: Arbeitsprozess 34 starten
172.17.0.1 - - [28/Aug/2021:10:29:26 0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.68.0" "-"
$

Protokolle anzeigen seit

Wir können die Protokollausgabe einschränken, indem wir das Flag --since verwenden und einen Zeitstempel wie einen absoluten Wert mit der Syntax 2021-08-28T15:23:37Z oder einen relativen wie 56m für 56 Minuten angeben.

Die Option --since zeigt nur die Containerprotokolle an, die nach einem bestimmten Datum erstellt wurden. Sie können das Datum als RFC 3339-Datum, als UNIX-Zeitstempel oder als Go-Dauerstring (z.B. 1m30s, 3h) angeben. Die lokale Zeitzone auf dem Client wird verwendet, wenn Sie am Ende des Zeitstempels weder ein Z noch einen -00:00 Zeitzonenversatz angeben. Sie können die Option --since mit einer oder beiden der Optionen --follow oder --tail kombinieren.

Beispiel:

$ 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" "-"
$

Im obigen Beispiel werden Protokolle seit nur 2 Minuten angezeigt, wobei nostalgic_wescoff der automatisch generierte Name ist, der für den nginx-Container vergeben wurde.

Protokolle anzeigen bis

Wie das Flag --since unterstützt Docker Logs auch das Flag --until, das Protokolle vor dem angegebenen Zeitstempel anzeigt. Auch der Zeitstempel folgt einer ähnlichen Konvention wie zuvor und kann als absoluter Wert mit der Syntax 2021-08-28T15:23:37Z oder als relativer Wert wie 56m für 56 Minuten angegeben werden.

Beispiel:

$ docker logs --until=1h30m nostalgic_wescoff
/docker-entrypoint.sh: /docker-entrypoint.d/ ist nicht leer, wird versuchen, die Konfiguration durchzuführen
/docker-entrypoint.sh: Sucht nach Shell-Skripten in /docker-entrypoint.d/
/docker-entrypoint.sh: Startet /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Ermitteln der Prüfsumme von /etc/nginx/conf.d/default.conf
10-listen-auf-IPv6-by-default.sh: info: Aktivieren von listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Startet /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Starten von /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Konfiguration abgeschlossen; bereit zum Starten
2021/08/28 10:29:05 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice]</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> 1#1: Verwendung der "epoll" Ereignis-Methode
2021/08/28 10:29:05 [ <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: nginx/1.21.1
2021/08/28 10:29:05 [ <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: gebaut mit gcc 8.3.0 (Debian 8.3.0-6)
2021/08/28 10:29:05 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: OS: Linux 5.8.0-1039-azure
2021/08/28 10:29:05 [ <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/08/28 10:29:05 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: Arbeitsprozesse starten
2021/08/28 10:29:05 <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: Arbeitsprozess 33 starten
2021/08/28 10:29:05 [ <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>notice</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x></x> ] 1#1: Arbeitsprozess 34 starten
172.17.0.1 - - [28/Aug/2021:10:29:26 0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.68.0" "-"
$

Im obigen Beispiel werden alle Protokolle vor 1 Stunde 30 Minuten angezeigt.

Zeitstempel anzeigen

Viele Containeranwendungen bieten in ihrer Protokollausgabe integrierte Zeitstempel, so dass Docker diese auch mit dem Befehl docker logs anzeigt. Wenn Sie möchten, dass Docker seine Zeitstempel in der Ausgabe explizit voranstellt, verwenden Sie die Flagge --timestamps oder -t.

Beispiel:

$ docker logs -t redis
2021-08-28T16:53:42.160312570Z 1:C 28 Aug 2021 16:53:42.160 # oO0OoO0OoO0Oo Redis wird gestartet oO0OoOoO0Oo
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, gerade gestartet
2021-08-28T16:53:42.160342171Z 1:C 28 Aug 2021 16:53:42.160 # Warnung: keine Konfigurationsdatei angegeben, verwendet die Standardkonfiguration. Um eine Konfigurationsdatei anzugeben, verwenden Sie redis-server /path/to/redis.conf
2021-08-28T16:53:42.160792578Z 1:M 28 Aug 2021 16:53:42.160 * monotone Uhr: 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 initialisiert
2021-08-28T16:53:42.161186984Z 1:M 28 Aug 2021 16:53:42.161 # WARNUNG overcommit_memory ist auf 0 gesetzt! Das Speichern im Hintergrund kann bei geringem Speicher fehlschlagen. Um dieses Problem zu beheben, fügen Sie 'vm.overcommit_memory = 1' zu /etc/sysctl.conf hinzu und starten Sie dann neu oder führen Sie den Befehl 'sysctl vm.overcommit_memory=1' aus, damit dies wirksam wird.
2021-08-28T16:53:42.161484389Z 1:M 28 Aug 2021 16:53:42.161 * Bereit, Verbindungen zu akzeptieren
$

Merge-Flags

Docker bietet die Möglichkeit, bestimmte Flags zu kombinieren, um eine besser gefilterte Ausgabe zu erhalten, anstatt den gesamten Protokollinhalt auf dem Bildschirm auszugeben. Als einfaches Beispiel können wir das Flag --tail mit --since kombinieren, um eine eingeschränktere Ausgabe zu erhalten.

Beispiel:

$ 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" "-"

Dies kann auch mit anderen Flags funktionieren.

Mit Shell-Dienstprogrammen filtern

Linux-Shell-Utilities können auch für mehr Geschicklichkeit in der Protokollausgabe verwendet werden. Dienstprogramme wie grep, head, tail usw. können für fortgeschrittene Operationen in die Docker-Protokollausgabe eingefügt werden.

Beispiel:

$ 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" "-"
$

Beachten Sie hier, dass wir die Protokollströme umleiten müssen, um eine einzelne Eingabe für grep mit 2>&1 zu erhalten.

Zusammenfassung 👩‍💻

Docker ist eine vielseitige Plattform, die zahlreiche Funktionen zur Verwaltung ihrer Umgebung bietet. Die Verwaltung von Protokollen für ein System ist eine der wesentlichen Fähigkeiten, die jeder Systemadministrator beherrschen sollte. Die Verwaltung von Protokollen in Docker ist einfach, wenn Sie die verfügbaren Befehle und möglichen Flags entsprechend Ihren Anforderungen kennen.

Weitere Informationen über Docker und seine Funktionen finden Sie in der Dokumentation von Docker.