Wie leite ich Docker-Container-Protokolle in eine einzelne Datei um?

108

Ich möchte alle Protokolle meines Docker-Containers in eine einzelne Protokolldatei umleiten, um sie zu analysieren. Ich habe es versucht

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

Dies gibt jedoch die Anmeldung in zwei verschiedenen Dateien. Ich habe es schon versucht

docker logs container > /tmp/stdout.log

aber es hat nicht funktioniert.

KETAN PATIL
quelle

Antworten:

135

Protokolle müssen nicht umgeleitet werden.

Docker speichert standardmäßig Protokolle in einer Protokolldatei. So überprüfen Sie den Befehl zum Ausführen des Protokolldateipfads:

docker inspect --format='{{.LogPath}}' containername

/var/lib/docker/containers/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334-json.log

Öffnen Sie diese Protokolldatei und analysieren Sie sie.

Wenn Sie Protokolle umleiten, erhalten Sie Protokolle nur vor der Umleitung. Sie können keine Live-Protokolle sehen.

BEARBEITEN:

Um Live-Protokolle anzuzeigen, können Sie den folgenden Befehl ausführen

tail -f `docker inspect --format='{{.LogPath}}' containername`

Hinweis:

Diese Protokolldatei /var/lib/docker/containers/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334-json.logwird nur erstellt, wenn Docker Protokolle generiert, wenn keine Protokolle vorhanden sind. Diese Datei ist dann nicht vorhanden. Es ist ähnlich wie manchmal, wenn wir einen Befehl ausführen docker logs containernameund nichts zurückgibt. In diesem Szenario ist diese Datei nicht verfügbar.

pl_rock
quelle
tail -f `docker inspect --format='{{.LogPath}}' myapp`- Es ist wirklich JSON
Adam
Es wird fehlschlagen, wenn diese Datei nicht vorhanden ist. Wenn Docker kein Protokoll generiert, wird diese Datei nicht erstellt. Wenn Docker jedoch Protokolle generiert, ist dieser Befehl gut geeignet, um Live-Protokolle anzuzeigen. danke Adam. Füge es meiner Antwort hinzu, um anderen zu helfen.
pl_rock
"Docker speichert standardmäßig Protokolle in einer Protokolldatei." - In welchem ​​Kontext? Alle Container, die auf einem Docker-Host ausgeführt werden, werden in eine einzelne Datei ausgegeben? Ein einziger Container?
Chris Stryczynski
@ChrisStryczynski Docker erstellt eine Protokolldatei pro Container
Eddy Hernandez
125

Wie wäre es mit dieser Option:

docker logs containername >& logs/myFile.log

Protokolle, nach denen in der Frage gefragt wurde, werden nicht umgeleitet, sondern einmal in eine bestimmte Datei kopiert.

Eddy Hernandez
quelle
Wenn ich mich nicht irre, kopiert dieser Befehl im Grunde alle Protokolle von dem Zeitpunkt an, an dem der Container gestartet wurde, um myFile.logs zu präsentieren. Richtig.?
S Andrew
@ Andrew im Grunde ja! Neue Versionen von Docker können sich jedoch ändern. besser zu sehen docker logs --help, um sicher zu sein
Eddy Hernandez
36

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

Erläuterung:

  • -f(dh --follow): schreibt alle vorhandenen Protokolle und fährt fort ( folgt ) Protokollierung alles, was als nächstes kommt.
  • &> Leitet sowohl die Standardausgabe als auch den Standardfehler um.
  • Wahrscheinlich möchten Sie diese Methode im Hintergrund ausführen, also die &.
  • Sie können Ausgabe und stderr trennen durch: > output.log 2> error.log (anstatt zu verwenden &>).
Juanmirocks
quelle
9

Führen Sie Folgendes aus, um sowohl stdout als auch stderr aus Ihrem Docker-Container in einer einzelnen Protokolldatei zu erfassen:

docker logs container > container.log 2>&1
Jean Velloen
quelle
8

Angenommen, Sie haben mehrere Container und möchten die Protokolle in einer einzigen Datei zusammenfassen, müssen Sie einen Protokollaggregator wie fluentd verwenden. fluentd wird als Protokollierungstreiber für Docker-Container unterstützt.

In Docker-Compose müssen Sie also den Protokollierungstreiber definieren

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

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

Der zweite Schritt wäre die Aktualisierung der fließenden Konfiguration, um die Protokolle sowohl für Dienst 1 als auch für Dienst 2 bereitzustellen

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

In dieser Konfiguration bitten wir Sie, Protokolle in eine einzelne Datei in diesen Pfad zu schreiben
/fluentd/log/service/service.*.log

und der dritte Schritt wäre, das angepasste Fluentd auszuführen, das mit dem Schreiben der Protokolle in die Datei beginnt.

Hier ist der Link für Schritt-für-Schritt-Anleitungen

Etwas lang, aber korrekt, da Sie mehr Kontrolle über den Pfad der Protokolldateien usw. haben und dies auch in Docker Swarm gut funktioniert.

Abhishek Galoda
quelle
1

Da Docker für uns stdout und stderr zusammenführt, können wir die Protokollausgabe wie jeden anderen Shell-Stream behandeln. Verwenden Sie einen Umleitungsoperator, um die aktuellen Protokolle in eine Datei umzuleiten

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

Anstatt die Ausgabe an stderr und stdout zu senden, leiten Sie die Ausgabe Ihrer Anwendung in eine Datei um und ordnen Sie die Datei einem permanenten Speicher außerhalb des Containers zu.

$ docker logs test_container> /tmp/output.log

Docker akzeptiert keine relativen Pfade in der Befehlszeile. Wenn Sie also ein anderes Verzeichnis verwenden möchten, müssen Sie den vollständigen Pfad verwenden.

Anish Varghese
quelle
1

Wenn Sie unter Windows arbeiten und PowerShell verwenden (wie ich), können Sie die folgende Zeile verwenden, um das stdoutund zu erfassen stderr:

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

Ich hoffe es hilft jemandem!

mirind4
quelle
1
So speichern Sie alle Containerprotokolle in einer Datei, basierend auf dem Containernamen ...foreach ($element in $(docker ps -a --format "{{.Names}}")) {docker logs $element | Out-File "C:/dockerlogs/$element.log"}
xisket
1

Der einfachste Weg, den ich benutze, ist dieser Befehl auf dem Terminal:

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

Struktur ist:

docker logs <Container Name> > path/filename.log
itssaifurrehman
quelle
1

Überprüfen Sie zuerst Ihre Container-ID

docker ps -a

Sie können die erste Zeile in den Spalten CONTAINER ID sehen. Wahrscheinlich sieht es so aus: "3fd0bfce2806", dann tippe es in die Shell

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

Sie werden so etwas sehen

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

dann können Sie es als sehen

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

Es wäre im JSON-Format, Sie können den Zeitstempel verwenden, um Fehler zu verfolgen

kiran beethoju
quelle
0

Bash-Skript zum Kopieren aller Containerprotokolle in ein angegebenes Verzeichnis:

#!/usr/bin/env bash

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