Comment rediriger les journaux du conteneur Docker vers un seul fichier?

111

Je souhaite rediriger tous les journaux de mon conteneur Docker vers un fichier journal unique pour les analyser. j'ai essayé

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

mais cela donne journal dans deux fichiers différents. J'ai déjà essayé

docker logs container > /tmp/stdout.log

Mais cela n'a pas fonctionné.

KETAN PATIL
la source

Réponses:

137

Pas besoin de rediriger les journaux.

Docker stocke par défaut les journaux dans un fichier journal. Pour vérifier le chemin du fichier journal, exécutez la commande:

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

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

Ouvrez ce fichier journal et analysez.

si vous redirigez les journaux, vous n'obtiendrez que les journaux avant la redirection. vous ne pourrez pas voir les journaux en direct.

ÉDITER:

Pour voir les journaux en direct, vous pouvez exécuter la commande ci-dessous

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

Remarque:

Ce fichier journal /var/lib/docker/containers/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334-json.logne sera créé que si le docker génère des journaux s'il n'y a pas de journaux, ce fichier ne sera pas là. c'est similaire comme parfois si nous exécutons la commande docker logs containernameet qu'elle ne renvoie rien. Dans ce scénario, ce fichier ne sera pas disponible.

pl_rock
la source
tail -f `docker inspect --format='{{.LogPath}}' myapp`- c'est vraiment JSON
Adam
il échouera si ce fichier n'est pas là. signifie que si le docker ne génère aucun journal, ce fichier ne sera pas créé. mais si docker génère des journaux, cette commande est bonne pour voir les journaux en direct. merci Adam. l'ajoutant à ma réponse pour aider les autres.
pl_rock
"Docker par défaut enregistre les journaux dans un fichier journal." - dans quel contexte? Tous les conteneurs exécutés sur un hôte docker obtiennent la sortie dans un seul fichier? Un seul conteneur?
Chris Stryczynski
@ChrisStryczynski Docker crée un fichier journal par conteneur
Eddy Hernandez
127

Que diriez-vous de cette option:

docker logs containername >& logs/myFile.log

Il ne redirigera pas les journaux demandés dans la question, mais les copiera une fois dans un fichier spécifique.

Eddy Hernandez
la source
Si je ne me trompe pas, cette commande copiera essentiellement tous les journaux à partir du moment où le conteneur a commencé à se présenter dans myFile.logs. Droite.?
S Andrew
@SAndrew fondamentalement oui! mais les nouvelles versions de Docker peuvent changer. mieux voir docker logs --helppour être sûr
Eddy Hernandez
39

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

Explication:

  • -f(ie --follow): écrit tous les journaux existants et continue ( suit ) la journalisation de tout ce qui vient ensuite.
  • &> redirige à la fois la sortie standard et l'erreur standard.
  • Vous souhaitez probablement exécuter cette méthode en arrière-plan, donc le fichier &.
  • Vous pouvez séparer la sortie et stderr par: > output.log 2> error.log(au lieu d'utiliser &>).
juanmirocks
la source
9

Pour capturer à la fois stdout et stderr de votre conteneur Docker dans un seul fichier journal, exécutez ce qui suit:

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

En supposant que vous disposez de plusieurs conteneurs et que vous souhaitez regrouper les journaux dans un seul fichier, vous devez utiliser un agrégateur de journaux tel que fluentd. fluentd est pris en charge comme pilote de journalisation pour les conteneurs Docker.

Donc, dans docker-compose, vous devez définir le pilote de journalisation

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

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

La deuxième étape serait de mettre à jour la conf fluentd pour gérer les journaux pour le service 1 et le service 2

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

Dans cette configuration, nous demandons que les journaux soient écrits dans un seul fichier sur ce chemin
/fluentd/log/service/service.*.log

et la troisième étape serait d'exécuter le fluentd personnalisé qui commencera à écrire les journaux dans le fichier.

Voici le lien pour des instructions étape par étape

Bit Long, mais de manière correcte car vous obtenez plus de contrôle sur le chemin des fichiers journaux, etc. et cela fonctionne bien dans Docker Swarm aussi.

Abhishek Galoda
la source
1

Puisque Docker fusionne stdout et stderr pour nous, nous pouvons traiter la sortie du journal comme n'importe quel autre flux shell. Pour rediriger les journaux actuels vers un fichier, utilisez un opérateur de redirection

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

Au lieu d'envoyer la sortie vers stderr et stdout, redirigez la sortie de votre application vers un fichier et mappez le fichier vers un stockage permanent en dehors du conteneur.

$ docker logs test_container> /tmp/output.log

Docker n'acceptera pas les chemins relatifs sur la ligne de commande, donc si vous souhaitez utiliser un répertoire différent, vous devrez utiliser le chemin complet.

Anish Varghese
la source
1

Si vous travaillez sous Windows et utilisez PowerShell (comme moi), vous pouvez utiliser la ligne suivante pour capturer le stdoutet stderr:

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

J'espère que ça aide quelqu'un!

mirind4
la source
1
Pour enregistrer tous les journaux de conteneur dans un fichier, en fonction du nom du conteneur ...foreach ($element in $(docker ps -a --format "{{.Names}}")) {docker logs $element | Out-File "C:/dockerlogs/$element.log"}
xisket
1

Le moyen le plus simple que j'utilise est cette commande sur le terminal:

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

la structure est:

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

Vérifiez d'abord votre identifiant de conteneur

docker ps -a

Vous pouvez voir la première ligne dans les colonnes CONTAINER ID. Cela ressemble probablement à ceci "3fd0bfce2806" puis tapez-le dans le shell

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

Vous verrez quelque chose comme ça

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

alors vous pouvez le voir comme

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

Ce serait au format JSON, vous pouvez utiliser l'horodatage pour tracer les erreurs

Kiran Beethoju
la source
0

Script Bash pour copier tous les journaux de conteneur dans un répertoire spécifié:

#!/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
la source