Suchen einer Zeichenfolge in Docker-Protokollen des Containers


72

Was ist der beste Weg, um eine bestimmte Zeichenfolge in den Protokollen eines Docker-Containers zu finden? Angenommen, ich möchte alle Anfragen sehen, die im Docker-Image "nginx" gestellt werden, das von einer IP stammt, die mit "127" beginnt.

grep funktioniert nicht wie erwartet mit dem Docker-Protokollbefehl:

docker logs nginx | grep "127."

Es druckt alle Protokolle, filtert aber nicht das Ergebnis!


Die Frage ist: Was ist der beste Weg, um eine bestimmte Zeichenfolge in den Protokollen eines Docker-Containers zu finden
Gering

Sendet docker logsdie Ausgabe an die Standardausgabe? Denn wenn ja, grepsollte es gut funktionieren. Wenn nicht, ist es etwas kaputt und Sie müssen den Standardfehler auf die Standardausgabe umleiten, bevor Sie mit filtern grep.
Etan Reisner

1
Überprüfen Sie stderr et atdout, Auszug aus github.com/docker/docker/issues/7440 $ docker run -d --name foo busybox ls abcd $ docker logs foo > stdout.log 2>stderr.log $ cat stdout.log $ cat stderr.log ls: abcd: No such file or directory
user2915097

1
@Robse Entschuldigung, Ihre Frage war schwer zu bekommen, bevor Sie dieses Beispiel hinzugefügt haben. Sieht so aus, als wäre docker logses schwer zu verstehen, da es Terminalsteuerungszeichen enthält. Ich würde die Nginx-Protokolldateien durchsuchen.
hek2mgl

Ich frage mich, ob Sie dies mit --follow tun könnten, damit der Grep während der Initialisierung der Container eine Schleife durchläuft
Mr-Programs

Antworten:


147

Dies kann passieren, wenn sich der Container bei stderr anmeldet. Piping funktioniert nur für stdout. Versuchen Sie also:

docker logs nginx 2>&1 | grep "127."

9

Als Vim-Fan benutze lessund suche ich lieber mit/

docker logs nginx 2>&1 | less

4

Um den Kommentaren nachzugehen und dies für alle anderen zu klären, die dieses Problem haben. Hier ist die einfachste Möglichkeit, ein Nginx-Containerprotokoll zu durchsuchen.

docker logs nginx > stdout.log 2>stderr.log
cat stdout.log | grep "127."

IMO ist etwas chaotisch, weil Sie diese möglicherweise sehr großen Dateien erstellen und löschen müssen. Hoffentlich bekommen wir ein paar Werkzeuge, um es ein bisschen bequemer zu machen.


Unwahrscheinlich - es sieht nicht so aus, als würde docker logses separate stdout und stderr unterstützen github.com/moby/moby/issues/25683
Martynas Jusevičius


3

Außerdem fand ich es nützlich, einige Begriffe hervorzuheben, nach denen ich in den Protokollen suche. Besonders bei produktiven Installationen, bei denen viel Protokollausgabe generiert wird. In meinem Fall möchte ich COUNT(*)Aussagen hervorheben . Aber mit einem einfachen grep kann ich nicht die gesamte SQL-Anweisung sehen, da es sich um eine mehrzeilige Anweisung handelt. Dies ist mit -Eswitch und etwas Regex möglich :

Zum Beispiel Schnipsel folgende für alle Fragen suchen , die enthalten COUNT(*)sowie count(*):

docker logs <containerName> -f | grep --line-buffered -i -E --color "select count\(\*\)|$"

Einige Erklärungen:

  • docker logs -fsagen Docker zu f ollow die Protokolle, so auch die Filter applys neue Einträge wie beim Betrachten sie mittail -f
  • greps --line-bufferedschalten spült die Ausgabe auf jeder Zeile, die in Echtzeit erforderlich ist , wenn grep docker logs -fverwendet wird
  • -Eeine ist e Xtended RegexMuster, benötigt unser Muster anzuwenden , die uns auch die nicht passenden Ergebnisse erlauben Rückkehr
  • --color hebt die übereinstimmenden Teile hervor (scheint das Standardverhalten auf meinem Ubuntu 16.04 LTS zu sein, aber möglicherweise nicht auf anderen Distributionen, daher habe ich es aus Sicherheitsgründen hier aufgenommen)
  • *entkam seine abzuschalten spezielle glob Funktionalität , wo (und )maskiert ihre regex zu vermeiden , als Gruppe bedeutet, die durch aktiviert -ESchalter

Wenn sich der Container bei stderr anmeldet, können Sie sie weiterleiten, wie Edoardo bereits für einen einfachen grep geschrieben hat :

docker logs <containerName> -f 2>&1 | grep --line-buffered -i -E --color "select count\(\*\)|$"

Der -fSchalter kann weggelassen werden, wenn kein Live-Grep gewünscht wird. In beiden Fällen wird das gesamte Protokoll mit einem hervorgehobenen Suchbegriff wie folgt angezeigt:

Geben Sie hier die Bildbeschreibung ein


2

Führen Sie den folgenden Befehl aus, um den Containernamen für das Image nginx zu extrahieren.

docker ps --filter ancestor=nginx

Kopieren Sie die Container-ID vom letzten Befehl und extrahieren Sie den Protokollpfad für Ihren Container über den folgenden Befehl

grep "127." `docker inspect --format={{.LogPath}} <ContainerName>`

0

Verwenden Sie zuerst diesen Befehl (b1e3c456f07f ist die Container-ID):

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

Das Ergebnis wird ungefähr so ​​aussehen:

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

Verwenden Sie zweitens diesen Befehl (Sie können vim verwenden, wenn Sie möchten):

nano /var/lib/docker/containers/b1e3c456f07f2cb3ae79381ada33a034041a10f65174f52bc1792110b36fb767/b1e3c456f07f2cb3ae79381ada33a034041a10f65174f52bc1792110b36fb767-json.log

0

Ich benutze es im Allgemeinen auch mit -fOption, wenn ich das Problem debugge

docker logs -f nginx 2>&1 | grep "127."

Es wird uns in Echtzeit zeigen, was wir erwarten.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.