Wie lösche ich die Protokolle für einen Docker-Container ordnungsgemäß?

208

Ich benutze docker logs [container-name], um die Protokolle eines bestimmten Containers zu sehen.

Gibt es eine elegante Möglichkeit, diese Protokolle zu löschen?

Youssouf Maiga
quelle
14
Nebenbei können Sie die Größe der Protokolle übersudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log"
Daniel F

Antworten:

250

Aus dieser Frage ergibt sich ein Einzeiler, den Sie ausführen können:

echo "" > $(docker inspect --format='{{.LogPath}}' <container_name_or_id>)

oder es gibt den ähnlichen Befehl zum Abschneiden:

truncate -s 0 $(docker inspect --format='{{.LogPath}}' <container_name_or_id>)

Ich bin kein großer Fan von beidem, da sie Dockers Dateien direkt ändern. Das Löschen externer Protokolle kann auftreten, während Docker JSON-formatierte Daten in die Datei schreibt, was zu einer Teilzeile führt und die Fähigkeit zum Lesen von Protokollen aus der docker logsCLI beeinträchtigt .

Stattdessen kann Docker die Protokolle automatisch für Sie drehen lassen. Dies erfolgt mit zusätzlichen Flags für dockerd, wenn Sie den Standard- JSON-Protokollierungstreiber verwenden :

dockerd ... --log-opt max-size=10m --log-opt max-file=3

Sie können dies auch als Teil Ihrer daemon.json- Datei festlegen , anstatt Ihre Startskripte zu ändern :

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

Diese Optionen müssen mit Root-Zugriff konfiguriert werden. Stellen Sie sicher, dass Sie a ausführen, systemctl reload dockernachdem Sie diese Datei geändert haben, damit die Einstellungen angewendet werden. Diese Einstellung ist dann die Standardeinstellung für alle neu erstellten Container. Beachten Sie, dass vorhandene Container gelöscht und neu erstellt werden müssen, um die neuen Protokolllimits zu erhalten.


Ähnliche Protokolloptionen können an einzelne Container übergeben werden, um diese Standardeinstellungen zu überschreiben. Auf diese Weise können Sie mehr oder weniger Protokolle für einzelne Container speichern. So docker runsieht es aus:

docker run --log-driver json-file --log-opt max-size=10m --log-opt max-file=3 ...

oder in einer Erstellungsdatei:

version: '3.7'
services:
  app:
    image: ...
    logging:
      options:
        max-size: "10m"
        max-file: "3"

Für zusätzliche Platzersparnis können Sie vom json-Protokolltreiber zum "lokalen" Protokolltreiber wechseln. Es werden die gleichen Optionen für maximale Größe und maximale Datei verwendet, aber anstatt in json zu speichern, wird eine binäre Syntax verwendet, die schneller und kleiner ist. Auf diese Weise können Sie mehr Protokolle in einer Datei gleicher Größe speichern. Der Eintrag daemon.json dafür sieht folgendermaßen aus:

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

Der Nachteil des lokalen Treibers ist, dass externe Protokollparser / -weiterleitungen, die vom direkten Zugriff auf die JSON-Protokolle abhängig sind, nicht mehr funktionieren. Wenn Sie also ein Tool wie Filebeat zum Senden an Elastic oder Splunks Universal Forwarder verwenden, würde ich den "lokalen" Treiber vermeiden.

Ich habe in meiner Präsentation mit Tipps und Tricks etwas mehr dazu .

BMitch
quelle
6
Ich habe eine gemacht, service docker restart die alleine nicht funktioniert hat. Außerdem mussten brandneue Container erstellt werden, bevor sie in Kraft traten. Das heißt, nur die alten Container
aufzurufen
Ich verwende Docker 1.13.1 und das 'docker inspect --format =' {{. LogPath}} '<Container-ID>' gibt eine Nullzeichenfolge ("") zurück .... aber ich erhalte immer noch eine Ausgabe von ' Docker-Protokolle <Container-ID> '?!? Woher kommt das und wie lösche ich es?
JD Allen
@JDAllen 1.13.1 ist lange nicht mehr unterstützt. Ich habe kein so altes System, um die Inspektionsausgabe anzuzeigen.
BMitch
Besser noch wäre echo -n > .... Auf jeden Fall möchte ich mehr Kontrolle über meine Protokolle haben. Zum Beispiel würde ich nach dem Neustart von Docker-Compose gerne den Mechanismus haben, um etwas mit den erhaltenen Protokollen zu tun.
NarūnasK
2
@AlexisWilke Wenn Sie Docker stoppen können, können Sie wahrscheinlich Ihren Container stoppen. Wenn Sie Letzteres tun können, wäre es mein Rat, den Container mit den Protokollierungsoptionen neu zu erstellen. Der neue Container enthält keine alten Protokolle, und neue Protokolle werden automatisch gerollt, wodurch sowohl das kurzfristige als auch das langfristige Problem gleichzeitig gelöst werden.
BMitch
226

Verwenden:

truncate -s 0 /var/lib/docker/containers/*/*-json.log

Möglicherweise benötigen Sie Sudo

sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"

ref. Jeff S. Wie lösche ich die Protokolle für einen Docker-Container richtig?

Referenz: Abschneiden einer Datei während der Verwendung (Linux)

duketwo
quelle
4
abschneiden: '/var/lib/docker/containers/*/*-json.log' kann nicht zum Schreiben geöffnet werden: Keine solche Datei oder kein solches Verzeichnis
BTR Naidu
2
@BTRNaidu Sie müssen es als root / sudo ausführen, der Inhalt von containersist sonst nicht verfügbar.
Spydon
25
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"- arbeitete für mich
Jeff S.
7
Ignorieren Sie die beiden oben genannten Profis. Wenn Sie sich nicht sicher sind, können Sie einfach unter "ls /var/lib/docker/containers/*/*-json.log" überprüfen, was abgeschnitten wird.
Duketwo
1
Nach dem Leeren der error from daemon in stream: Error grabbing logs: invalid character '\x00' looking for beginning of value
Protokolldatei erhalte
42

Unter Docker für Windows und Mac und wahrscheinlich auch unter anderen ist es möglich, die Option tail zu verwenden. Beispielsweise:

docker logs -f --tail 100

Auf diese Weise werden nur die letzten 100 Zeilen angezeigt, und Sie müssen nicht zuerst durch 1 Million Zeilen scrollen ...

(Daher ist das Löschen des Protokolls wahrscheinlich nicht erforderlich.)

Egbert Nierop
quelle
12
Die Idee ist, Protokolldateien zu bereinigen und nicht die letzten n Zeilen von Protokolldateien zu drucken
Youssouf Maiga
41
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"
Richard
quelle
4
Um die Größe der Protokolle zu erhalten sudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log", um nur die Gesamtgröße der Protokolle zu erhaltensudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log | grep total"
Daniel F
Gibt es Probleme damit, dass dockerd / aufs die gedrehten Protokolldateien nicht kennt und nicht entfernen kann?
ThorSummoner
Dieser Befehl hat bei mir funktioniert, während die anderen Befehle in diesem SO dies nicht getan haben. Wenn es darauf ankommt,
Tundra Fizz
27

Sie können logrotate einrichten, um die Protokolle regelmäßig zu löschen.

Beispieldatei in /etc/logrotate.d/docker-logs

/var/lib/docker/containers/*/*.log {
 rotate 7
 daily
 compress
 size=50M
 missingok
 delaycompress
 copytruncate
}
AlexPnt
quelle
und wie benutze ich das? wird standardmäßig mit docker run? Datei /etc/logrotate.d/docker-logsexistiert nicht, ich muss es erstellen?
Carlos.V
Sie müssen das Dienstprogramm logrotate (logrotate <Konfigurationsdatei>) aufrufen, damit es Ihre Konfiguration liest und die Bereinigung ausführt. Sie können es beispielsweise auch als Cron-Job festlegen.
AlexPnt
Das Problem bei diesem ist, dass es möglicherweise nicht richtig mit dem synchronisiert ist, was Docker tut. Die Verwendung der Docker-Funktion ist wahrscheinlich viel klüger. ( "log-opts"wie von BMitch gezeigt)
Alexis Wilke
12

Docker4Mac, eine Lösung für 2018:

LOGPATH=$(docker inspect --format='{{.LogPath}}' <container_name_or_id>)
docker run -it --rm --privileged --pid=host alpine:latest nsenter -t 1 -m -u -n -i -- truncate -s0 $LOGPATH

In der ersten Zeile wird der Pfad der Protokolldatei angezeigt, ähnlich der akzeptierten Antwort.

In der zweiten Zeile nsenterkönnen Sie Befehle in der xhyveVM ausführen, die als Host für alle Docker-Container unter Docker4Mac fungiert. Der Befehl, den wir ausführen, ist der truncate -s0 $LOGPATHaus Nicht-Mac-Antworten bekannte.

Wenn Sie verwenden docker-compose, wird die erste Zeile:

local LOGPATH=$(docker inspect --format='{{.LogPath}}' $(docker-compose ps -q <service>))

und <service>ist der Dienstname aus Ihrer docker-compose.ymlDatei.

Vielen Dank an https://github.com/justincormack/nsenter1 für den nsenterTrick.

Elifiner
quelle
4
Und um die Protokolle aller Container docker run -it --rm --privileged --pid=host alpine:latest nsenter -t 1 -m -u -n -i -- sh -c 'truncate -s0 /var/lib/docker/containers/*/*-json.log'
abzuschneiden,
10

Sie können dies nicht direkt über einen Docker-Befehl tun.

Sie können entweder die Größe des Protokolls begrenzen oder mithilfe eines Skripts Protokolle löschen, die sich auf einen Container beziehen. Beispiele für Skripte finden Sie hier (von unten lesen): Funktion: Möglichkeit zum Löschen des Protokollverlaufs # 1083

Lesen Sie den Protokollierungsabschnitt der Docker-Compose-Dateireferenz, in dem Sie Optionen (z. B. Protokollrotation und Protokollgrößenbeschränkung) für einige Protokollierungstreiber angeben können.

Tristan
quelle
7

Versuchen Sie als Root- Benutzer Folgendes auszuführen:

>  /var/lib/docker/containers/*/*-json.log

oder

cat /dev/null > /var/lib/docker/containers/*/*-json.log

oder

echo "" > /var/lib/docker/containers/*/*-json.log
Watson Kepson
quelle
6

Auf meinen Ubuntu-Servern würde ich sogar als Sudo bekommen Cannot open ‘/var/lib/docker/containers/*/*-json.log’ for writing: No such file or directory

Aber das Kämmen des Dockers inspizierte und schnitt die Antworten ab:

sudo truncate -s 0 `docker inspect --format='{{.LogPath}}' <container>`
Aqwan
quelle
2

Ich bevorzuge dieses (aus den obigen Lösungen):

truncate -s 0 /var/lib/docker/containers/*/*-json.log

Ich verwende jedoch mehrere Systeme (z. B. Ubuntu 18.x Bionic), auf denen dieser Pfad nicht wie erwartet funktioniert. Docker wird über Snap installiert, sodass der Pfad zu Containern eher wie folgt lautet:

truncate -s 0 /var/snap/docker/common/var-lib-docker/containers/*/*-json.log
igraczech
quelle
1

Sie können die Log-Opts-Parameter auch docker runwie folgt in der Befehlszeile angeben :

docker run --log-opt max-size=10m --log-opt max-file=5 my-app:latest

oder in einer docker-compose.yml wie dieser

my-app:
image: my-app:latest
logging:
    driver: "json-file"
    options:
        max-file: "5"
        max-size: 10m

Credits: https://medium.com/@Quigley_Ja/rotating-docker-logs-keeping-your-overlay-folder-small-40cfa2155412 (James Quigley)

Dag Baardsen
quelle
Die Parameterwerte sollten (dh zitiert werden "5"und "10m"jeweils), wie gezeigt , hier für die globale daemon.json Datei, aber es ist das gleiche für ein Docker-compose.yml. In beiden Fällen sind nur neu erstellte Container betroffen.
Adrian W
@AdrianW: docker-compose.yml benötigt keine Anführungszeichen. Dies sind völlig unterschiedliche Dateiformate. Und ja, Sie haben Recht: "Docker Run" -Befehle und Docker-Compose-Parameter wirken sich nur auf neu erstellte Container aus - im Gegensatz zu der Antwort hier mit den meisten Stimmen, die nur neu gestartete Dockerd-Daemons betrifft und nur über den Root-Zugriff verfügbar ist. Meine Antwort soll einen viel einfacheren und aktualisierten Pfad als das Bearbeiten anzeigen, als den gesamten Dockerd-Prozess neu zu starten.
Dag Baardsen
Ohne Anführungszeichen erhalte ich: FEHLER: für App Container für Service-App kann nicht erstellt werden: json: Nummer kann nicht in das Go-Strukturfeld LogConfig.Config vom Typ string aufgelöst werden Wenn ich so zitiere: "5"es funktioniert. Die 10mArbeit ohne zu zitieren.
Adrian W
Anscheinend gibt es einen Unterschied zwischen Docker für Windows und Docker für Linux. Bei letzterem muss ich die Werte in Anführungszeichen setzen. Nicht auf dem ersteren. Die Beschreibung wurde auf beide aktualisiert. Danke, @AdrianW
Dag Baardsen
0

Docker für Mac-Benutzer, hier ist die Lösung:

    1. Suchen Sie den Pfad der Protokolldatei nach:

      $ docker inspect | grep log

    1. SSH in den Docker-Computer (nehmen wir an, der Name lautet default, falls nicht, wird ausgeführt docker-machine ls, um dies herauszufinden):

      $ docker-machine ssh default

    1. Wechsel zum Root-Benutzer ( Referenz ):

      $ sudo -i

    1. Löschen Sie den Inhalt der Protokolldatei:

      $ echo "" > log_file_path_from_step1

Jinsong Li
quelle
2
Docker-Maschine funktioniert nicht mit Docker für Mac. Sie können stattdessen laufen "Docker Lauf -ti -v / var / lib / Docker / Container: / var / Anfang centos bash" , dann "truncate --size 0 /var/inception/08d29a7d469232cfef4456dc6eebcbf313bf01ba73e479520a036150c5ab84de/08d29a7d469232cfef4456dc6eebcbf313bf01ba73e479520a036150c5ab84de-json.log"
Jamshid
Sie können docker exec -it default sheine sh-Shell in einen Container eingeben. Viele Container stellen den sudoBefehl jedoch nicht implizit zur Verfügung.
Dag Baardsen