2015-08-18 9 views
5

Derzeit leiten wir alle Anwendungsprotokolle von mehreren Containern auf stdout um und sammeln/var/log/message über rsyslog im Host zum ELK-Stack.Protokollierungslösung für mehrere Container, die auf demselben Host laufen

Alle Docker-Container-Logs werden als docker/xxxxxxxx angezeigt, wir können nicht feststellen, für welche Anwendung dieses Logbuch erstellt wurde, trotzdem können wir problemlos Anwendungen von mehreren Container-Logs von Docker Stdout unterscheiden.

+1

Ein 'docker-compose logs -f' könnte ausreichen, wenn das ist, wie Sie sie gestartet –

Antwort

1

Haben Sie sich fluentd angesehen? Es kann sein, was du brauchst.

+0

Die gleiche Frage hier, wie können wir jeden Anwendungstyp anders als Container-ID sagen? – Tom

+0

um ehrlich zu sein, ich habe es nie benutzt, aber gute Dinge darüber gehört. Ich fürchte, Sie müssten tiefer in die Dokumentation einsteigen. –

0

Warum verlassen Sie sich auf/var/log/messages Protokolle für Ihre Anwendungsprotokolle? Meiner Meinung nach sollten Ihre Anwendungsprotokolle unabhängig sein.

Angenommen, Sie haben eine Java, Ruby, Python, Knoten, Golang App (Was auch immer), dann können Sie die Protokolle in den Container in etwas wie /var/log/myapp/myapp.log pumpen. Das führen Sie Ihre Log-forwarder in Ihrem Container zu ELK allem unter /var/log/myapp/myapp.log Schiff

Allgemeines der Versender die Hostnamen als container_id basierend auf dem HOSTNAME env Variable zeigen. Zum Beispiel:

[[email protected] ~]# env | grep HOSTNAME 
HOSTNAME=1dfab5ea15cd 
[[email protected] ~]# 

Sie können auch so etwas wie Beaver oder log-courier verwenden, um Ihre Protokolle zu versenden.

Sie können Ihre Protokolle rotieren und alte Protokolle löschen, wenn es um Speicherplatz geht.

Wenn Sie also den Befehl docker logs verwenden möchten, um zu STDOUT und STDERR umzuleiten, wird Ihre Anwendung etwas in das Protokoll schreiben, das den Container/die Anwendung identifiziert. (Container könnte wieder der Hostname sein) Aber Sie können auf dem Host-Rechner zu /var/log/app/application.log umleiten. Etwas wie:

containerid/<hostname>-application: INFO: <message> 

Denkt nicht, dass es eine andere Art und Weise ...

Sie können auch anstelle von Logstash als eine weitere Option zu Fluentd wechseln.

+0

Das Speichern von physischen Protokollen in Containern ist keine bewährte Methode. Mit Docker 1.6 können wir alle Anwendungsprotokolle in stdout ausgeben und dann vom Host zur weiteren Verarbeitung abholen. – Tom

+0

Ich sehe es noch nicht so, ich denke, dass Docker Container-IDs identifiziert, wenn es in zukünftigen Versionen auf STDOUT/STDERR umleitet. Sieht so aus, als wäre es noch nicht da. – Rico

8

(Anleitung für OS X, soll aber in Linux arbeiten)

Es scheint keinen Weg, dies mit einem Docker Befehl zu tun, aber in der Bash können Sie mehrere Befehle gleichzeitig ausführen, und Mit sed können Sie Ihren Containernamen voranstellen.

docker logs -f --tail=30 container1 | sed -e 's/^/[-- container1 --]/' & 
docker logs -f --tail=30 container2 | sed -e 's/^/[-- container2 --]/' & 

Und Sie sehen Ausgabe von beiden Containern gleichzeitig.

container1 :: logging line 
container1 :: logging line 
container2 :: logging line 
container2 :: logging line 
container1 :: logging line 
container1 :: logging line 
container2 :: logging line 
container2 :: logging line 

Um Schwanz alle Container auf einmal:

#!/bin/bash 

names=$(docker ps --format "{{.Names}}") 
echo "tailing $names" 

while read -r name 
do 
    # eval to show container name in jobs list 
    eval "docker logs -f --tail=5 \"$name\" | sed -e \"s/^/[-- $name --] /\" &" 
    # For Ubuntu 16.04 
    #eval "docker logs -f --tail=5 \"$name\" |& sed -e \"s/^/[-- $name --] /\" &" 
done <<< "$names" 

function _exit { 
    echo 
    echo "Stopping tails $(jobs -p | tr '\n' ' ')" 
    echo "..." 

    # Using `sh -c` so that if some have exited, that error will 
    # not prevent further tails from being killed. 
    jobs -p | tr '\n' ' ' | xargs -I % sh -c "kill % || true" 

    echo "Done" 
} 

# On ctrl+c, kill all tails started by this script. 
trap _exit EXIT 

# For Ubuntu 16.04 
#trap _exit INT 

# Don't exit this script until ctrl+c or all tails exit. 
wait 

Und sie fg laufen zu stoppen und dann ctrl+c für jeden Behälter drücken.

Update: Danke an @ Flo-Woo für Ubuntu 16.04 Unterstützung

+1

für meinen Ubuntu 16.04 Server musste ich diese Änderungen vornehmen und funktionierte gut danke. "eval" docker logs -f --tail = 5 \ "$ name \" | & sed -e \ s/^/[- $ name -]/\ "&" 'und' trap _exit INT ' –

+1

Ich habe auch die Definition der Shell am Anfang des Skripts hinzugefügt, ansonsten habe ich" Umleitung unerwartet "erhalten. '#!/Bin/bash' – Jleuleu

+0

Guter Anruf @Jleuleu – Nate

Verwandte Themen