Compose: Fonctionnalité: possibilité d'effacer l'historique des journaux

Créé le 9 mars 2015  ·  145Commentaires  ·  Source: docker/compose

Une fonctionnalité que je pensais être utile depuis l'utilisation de Fig, et maintenant Compose serait la possibilité d'effacer l'historique des journaux pour les conteneurs gérés par Composed. Les conteneurs de longue durée ou "bavards" peuvent se retrouver avec beaucoup de bruit de journal qui peut ne pas être souhaité.

Je m'attendrais à ce qu'une commande comme la suivante résoudrait le problème:
$ docker-compose logs --clear [service]

arelogs kinenhancement

Commentaire le plus utile

docker logs -c (clear) <container> serait génial.

+1

Tous les 145 commentaires

Je ne pense pas que ce soit une fonctionnalité prise en charge par le démon docker. En regardant la documentation de l'API, la seule option serait de tronquer les journaux renvoyés à un nombre limité de lignes par conteneur:

https://docs.docker.com/reference/api/docker_remote_api_v1.17/#get -container-logs

: +1: pour ce numéro. J'utilise en fait compose pour développer un site web en Golang, Mongodb et nginx ... 5 jours après le début j'ai un long journal qui devient inquiétant. Chaque fois que je redémarre des conteneurs, j'ajoute de nombreuses lignes au journal.
@dnephin je ne comprends pas si vous donnez une solution (que je ne comprends pas :)) ou si vous proposez de vérifier si c'est possible avec api. Désolé pour mon mauvais anglais.

Docker 1.6 ajoutera la prise en charge des pilotes de journalisation, voir https://github.com/docker/docker/pull/10568 (actuellement; JSON, syslog et "aucun") le travail est en cours pour la rotation de base des journaux; https://github.com/docker/docker/pull/11485

C'est bon d'entendre ça, merci beaucoup :)

Merci pour l'arrière-plan et la mise à jour sur Docker 1.6 - dans l'attente!

docker logs -c (clear) <container> serait génial.

+1

+1 Vraiment important

Sainte vache, je me suis assis pendant plusieurs minutes de rondins pour arriver à la fin. J'apprécierais vraiment cela aussi pour ne pas avoir à reconstruire constamment les conteneurs.

+1

+1

+1

: +1:

+1

+2

+1

Pour mémoire, avec Docker 1.8 et docker-compose 1.4, il existe déjà une méthode pour limiter la taille du journal en utilisant https://docs.docker.com/compose/yml/#log -driver et log-opt max-size:

  log_driver: "json-file"
  log_opt:
    max-size: "100k"
    max-file: "20"

@dmage Merci, exactement ce dont j'ai besoin.

+1000

+1 aimerait ça

+1

La solution

@Rodeoclash - Je pense qu'un cas d'utilisation pour cela est la réutilisation d'un ensemble donné de conteneurs pour une nouvelle exécution, c'est-à-dire un test de CI. Les anciens journaux ne sont pas pertinents pour la nouvelle exécution, donc un clear avant la commande suivante dissiperait la confusion.

+1

+1, même besoin que @rosskevin

Ok, pour récapituler:

  • vous pouvez le faire à partir d'un fichier de composition (voir https://github.com/docker/compose/issues/1083#issuecomment-141936600)
  • # 265 couvre la possibilité de limiter la sortie de la commande logs
  • # 1756 couvre la caisse de conteneur réutilisée

Je vais fermer cela car il est déjà pris en charge ou suivi dans d'autres problèmes.

Je ne comprends pas très bien pourquoi cela a été fermé. Comment effacez-vous l'historique des journaux?

J'ajoute:

  log_opt:
    max-size: 50k

Pour limiter la longueur des logs.

Ils ont vraiment besoin d'ajouter ceci, c'est essentiel. Limiter les journaux est une bonne chose et il devrait y avoir une commande simple pour effacer les journaux.

docker logs -c <container>

Ce qui donne?

Je comprends comment limiter la taille du journal, mais comment effacer le journal?

Je ne pense pas que l'effacement d'un journal soit pris en charge par le moteur docker, qui gère les journaux.

Peut-être qu'avec un pilote de journal personnalisé, vous pourriez le faire, mais ce serait externe à composer.

+1 pour pouvoir vider les journaux ...

+1

+1

+1

+1

+1 pour la commande d'effacement du journal.

+1 pour la commande d'effacement du journal

+1

+1

+1

: +1:

+1

+1

docker-logs-clean.sh

#!/bin/bash

rm $(docker inspect $1 | grep -G '"LogPath": "*"' | sed -e 's/.*"LogPath": "//g' | sed -e 's/",//g');

Invocation:

sudo ./docker-logs-clean.sh <container-name>;

@sgarbesi merci!
+1

+1 pour la commande d'effacement du journal

Fermé en faveur de?

Pour réitérer mon commentaire de https://github.com/docker/compose/issues/1083#issuecomment -149357280:

Ok, pour récapituler:

  • vous pouvez le faire à partir d'un fichier de composition (voir https://github.com/docker/compose/issues/1083#issuecomment-141936600)
  • # 265 couvre la possibilité de limiter la sortie de la commande logs
  • # 1756 couvre la caisse de conteneur réutilisée

Si vous recherchez une commande comme docker logs --clear , qui n'est pas prise en charge par le moteur docker, vous devrez donc la demander sur docker / docker. Cependant, je pense que les options ci-dessus devraient déjà être suffisantes dans la plupart des cas. Ce que la plupart des gens veulent, c'est simplement afficher un sous-ensemble des journaux, et non les supprimer.

Merci @dnephin et tous les autres pour leurs contributions. J'ai soulevé ce problème il y a presque un an maintenant, et à en juger par les commentaires depuis lors, il me semble assez clair que la gestion des journaux est un problème pour de nombreux utilisateurs de composer.

Il y a eu quelques solutions de contournement mentionnées, moi-même j'utilise principalement max-size pour garder les journaux à une longueur raisonnable. Cela aide beaucoup, et je suis reconnaissant pour ces solutions de contournement, mais il est important de garder à l'esprit qu'il s'agit d'une _ solution de contournement_, pas d'une solution.

Il est également clair pour moi maintenant qu'une partie de la responsabilité de résoudre ce problème réside dans le système de journalisation Docker et qu'il lui faudrait fournir une commande clear pour que Compose puisse l'utiliser - c'est juste.

Cela dit cependant, il y a quelques fonctionnalités qui en ont fait les versions de Docker depuis la création de ce ticket - à savoir --since=<timestamp> et --tail=<num-lines> qui pourraient être pris en charge par Compose pour se rapprocher de donner un vrai solution à ce problème.

Par exemple, prendre en charge --since pourrait rendre quelque chose comme ça possible:

$ docker-compose logs --since=now my_container

ou

$ docker-compose logs --since=5m my_container

Le support pour --tail serait également utile, par exemple

$ docker-compose logs --tail=100 my_container

et bien sûr, leurs combinaisons. Il peut également être judicieux de les soutenir dans docker-compose.yml dans le cadre du bloc logging , mais même sans cela, simplement en prenant en charge ces deux options, je suppose que vous pourriez satisfaire la majorité des personnes qui ont + J'avais ce billet.

En résumé, merci encore pour tous les commentaires et solutions de contournement, et pour Docker et Compose eux-mêmes - ce sont tous deux d'excellents produits - j'espère que vous tiendrez compte des idées avancées dans ce fil de discussion et que vous continuerez à rendre ces produits encore plus performants.

Voir # 2227 pour un résumé

: +1: merci @dnephin ,

Ce que j'ai fait a été de supprimer manuellement les fichiers <container-id>-json.log placés dans /var/lib/docker/containers/<container-id>/ (utilisez sudo ). Une fois que j'ai exécuté docker-compose logs , le journal était vide. Ce n'est pas une solution mais avec un fichier .bash approprié, vous pouvez automatiser le nettoyage avant chaque build.

Edit: Quelque chose comme ça fait l'affaire (à utiliser sous vos propres risques !!):

sudo find /var/lib/docker/containers/ -type f -name '*-json.log' -delete

+1

+1

+1

+1

+2

+2

+1

+20

+1

+1

+1

+1

@sgarbesi Après avoir exécuté cette commande de nettoyage, la fonction de journalisation fonctionnera normalement?

+1

docker-logs-clean.sh

#!/bin/bash

for container_id in $(docker ps -a --filter="name=$name" -q);

    do file=$(docker inspect $container_id | grep -G '"LogPath": "*"' | sed -e 's/.*"LogPath": "//g' | sed -e 's/",//g');

    if [ -f $file ]
      then
          rm $file;
    fi

done

Invocation:


chmod +x docker-logs-clean.sh

sudo ./docker-logs-clean.sh

+1 pour l'option de ligne de commande pour effacer les journaux manuellement

@kassanmoor fait pour moi.

+1

Merci pour les autres moyens de nettoyer les journaux de conteneurs

👍

+1 👍

+1!

+1

+1

+1

Ce serait une excellente fonctionnalité à avoir, j'ai quelques conteneurs basés sur Java et après même un jour ou deux de dépannage, cela peut prendre 30 secondes ou plus pour faire un docker logs -f <container> parce que Java aime ces multi-lignes journaux.

Une autre chose qui pourrait être plus facile à implémenter est un autre indicateur sur les journaux pour démarrer une queue sans faire écho à tous les journaux existants docker logs -f -n <container> par exemple (ce qui signifie suivre uniquement les nouveaux journaux). Cela ne ferait écho qu'aux messages de journal reçus après l'exécution de la commande.

Le contraire fonctionnerait également (et serait plus proche de la façon dont fonctionne gnu tail): faire un -f fait écho aux 5 à 10 dernières lignes, puis aux nouvelles lignes par défaut et ajouter un drapeau pour tout faire écho comme il le fait maintenant (peut-être docker logs -f -a <container> ou quelque chose).

Sur cette note, j'aimerais avoir la fonctionnalité de gnu tail qui permet de spécifier le nombre de lignes à queue comme docker logs -100 <container> me donne les 100 dernières lignes.

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

Existe-t-il une astuce pour Docker pour Mac? Merci et +1 pour une option de ligne de commande pour cela :)

+1

+1

+1

MISE À JOUR: 2016/10/08 - Suppression de l'exigence pour "jq" car "docker logs" prend en charge les modèles Go! (https://docs.docker.com/engine/admin/formatting/)

Salut à tous,

Parce que la suppression de fichiers qui pourraient être ouverts est généralement une mauvaise idée - surtout si vous essayez d'économiser de l'espace disque! - J'ai développé les efforts initiaux de @sgarbesi , @lvitals & @wazoo (merci pour les idées les gars) pour produire le script légèrement plus fonctionnel ci-dessous.

Copiez le code ci-dessous dans un fichier
vi ./docker-container-log-trim.sh
Rendre le fichier exécutable
chmod +x ./docker-container-log-trim.sh
Puis exécutez avec
sudo ./docker-container-log-trim.sh

Décommentez la ligne avec > lorsque vous faites confiance au script ... c'est là que la magie opère. :-)

Vos commentaires sont les bienvenus.
Merci.

PS. Testé, mais pas endurci au combat. Utiliser à vos risques et périls.

#!/bin/bash

# NOTES:
#  Does NOT delete logfile (BAD IDEA) - simply trims file with redirect.
#  Handles single/all-running/all-existing containers - see end of script for usage.
#  Enjoy :-)


_get_container_logfile() {

  case $1 in

    running) _trim_container_logfile "$(docker ps -q)" $2
             ;;

        all) _trim_container_logfile "$(docker ps -aq)" $2
             ;;

          *) _trim_container_logfile "$(docker ps -a | awk -v ID=$1 '$1 ~ ID || $NF ~ ID {print $1}')" $2
             ;;

  esac

}


_trim_container_logfile() {

  TEMP=$(mktemp)

  case $2 in
    *[!0-9]*) echo "[lines] must be a number - \"$2\" is not a number."
              exit 1
              ;;
        ''|*) MAX=${2:-1000}
              ;;
  esac


  if [ -z $1 ]
  then
    echo "Container name/id unknown!"
    exit 1
  else
    for container in $1
    do
      logfile="$logfile $(docker inspect --format '{{ .LogPath }}' $container)"
      echo "Keeping $MAX lines: $logfile"

      tail -n ${MAX} $logfile > $TEMP
      # Uncomment the next line when you trust the script!
      # cat $TEMP > $logfile
    done
  fi

  rm $TEMP
}


if [ -a "$(which docker)" ]
then
  case $1 in
    --trim) if [ -z $2 ]
            then
              echo "Container name/id missing!"
              exit 1
            else
              _get_container_logfile $2 $3
            fi
            ;;

    --trim-running) _get_container_logfile running $2
                    ;;

    --trim-all) _get_container_logfile all $2
                ;;

    *) echo "Usage:"
       echo "  --trim {container} [lines]   Keep [lines] of logfile for a single container"
       echo "  --trim-running     [lines]   Keep [lines] of logfile for all running containers"
       echo "  --trim-all         [lines]   Keep [lines] of logfile for all containers"
       echo "Default: lines=1000"
       exit 1
       ;;
  esac
else
  echo "Requires \"docker\""
  exit 1
fi

+1

+1

Donc, comme il a été exprimé plusieurs fois qu'il y a un souhait pour une commande claire et explicite et comme il n'y en a jamais eu ajouté, aucune chance que cela soit rouvert?

Cela dépend d'un changement de moteur de docker bien sûr, mais c'est toujours quelque chose qui devra éventuellement être traité dans docker-compose également - et ce n'est certainement pas corrigé en ce qui concerne une commande explicite.

@DavidPesticcio J'obtiens cette erreur lors de l'exécution de votre script: line 53: $logfile: ambiguous redirect (après avoir supprimé le commentaire)

Salut @gingerlime , On dirait que $ TEMP n'est pas renseigné ... peut-être que "mktemp" n'est pas installé, ou ce n'est peut-être pas sur votre chemin? : - /

"Ça marche bien pour moi" - oui je sais, ça ne t'aide pas beaucoup, mais c'est vrai ... :-)

J'ai mis à jour le script, donc vous n'avez plus besoin de "jq" - peut-être que je devrais ajouter un renflouement si mktemp manque aussi ... Je pensais que c'était un outil standard - mais peut-être que vous n'utilisez pas le script dans une installation "standard" - comme à partir d'un conteneur minimal peut-être? :-)

J'espère que ça t'as aidé!

J'ai mktemp , et je l'utilise fréquemment ... Je n'ai pas vraiment passé beaucoup de temps à le déboguer. Nous avons fini avec le script plus simple ci-dessus qui ne fait que détruire ces journaux. Dans notre environnement de développement, ils ne sont pas importants.

sur ma configuration (c'est-à-dire en cours d'exécution en tant que pas d'utilisateur root), ce script bash n'aide pas si je me fais refuser la prémission en essayant d'ouvrir le fichier journal.

c'est un peu bizarre, qu'en tant qu'utilisateur je peux démarrer docker, mais je peux tocuh c'est des fichiers journaux ...
plus une raison pour avoir quelque chose à dépenser pour les commandes docker / docker-compose

J'ai dû modifier le script de @DavidPesticcio à cause des erreurs mentionnées précédemment ... ça va:

#!/bin/bash

# NOTES:
#  Does NOT delete logfile (BAD IDEA) - simply trims file with redirect.
#  Handles single/all-running/all-existing containers - see end of script for usage.
#  Enjoy :-)


_get_container_logfile() {

  case $1 in

    running) _trim_container_logfile "$(docker ps -q)" $2
             ;;

        all) _trim_container_logfile "$(docker ps -aq)" $2
             ;;

          *) _trim_container_logfile "$(docker ps -a | awk -v ID=$1 '$1 ~ ID || $NF ~ ID {print $1}')" $2
             ;;

  esac

}


_trim_container_logfile() {

  TEMP=$(mktemp)

  case $2 in
    *[!0-9]*) echo "[lines] must be a number - \"$2\" is not a number."
              exit 1
              ;;
        ''|*) MAX=${2:-1000}
              ;;
  esac


  if [ -z "$1" ]
  then
    echo "Container name/id unknown!"
    exit 1
  else
    for container in $1
    do
      logfile="$(docker inspect --format '{{.LogPath}}' $container)"
      if [ ! -f "$logfile" ]; then continue; fi
      echo "Keeping $MAX lines: $logfile"

      tail -n ${MAX} "$logfile" > "$TEMP"
      # Uncomment the next line when you trust the script!
      # cat "$TEMP" > "$logfile"
    done
  fi

  rm "$TEMP"
}


if [ -a "$(which docker)" ]
then
  case $1 in
    --trim) if [ -z $2 ]
            then
              echo "Container name/id missing!"
              exit 1
            else
              _get_container_logfile $2 $3
            fi
            ;;

    --trim-running) _get_container_logfile running $2
                    ;;

    --trim-all) _get_container_logfile all $2
                ;;

    *) echo "Usage:"
       echo "  --trim {container} [lines]   Keep [lines] of logfile for a single container"
       echo "  --trim-running     [lines]   Keep [lines] of logfile for all running containers"
       echo "  --trim-all         [lines]   Keep [lines] of logfile for all containers"
       echo "Default: lines=1000"
       exit 1
       ;;
  esac
else
  echo "Requires \"docker\""
  exit 1
fi

@dnephin a-t-il une chance que cela soit rouvert, car il existe une demande évidente d'avoir une commande d'effacement unique explicite pour les journaux?

Tronquez les journaux pour un conteneur donné (doit être root):

cp /dev/null $(docker inspect -f '{{.LogPath}}' container_name)

Vous voulez une troncature, pas une suppression. (La suppression du fichier référencé par un descripteur de fichier ouvert ne récupère pas d'espace jusqu'à ce que le processus, dans ce cas, le démon Docker, se termine complètement)

@oogali assez juste. Ce serait toujours bien d'avoir une commande appropriée pour le faire à la demande.

+1

serait bien d'avoir une commande appropriée pour cela

+1
serait bien d'avoir une commande appropriée pour qu'il le fasse à la demande.

C'est une évidence, fixer une date de début en tant que filtre est plus de travail que de simplement l'effacer pour regarder la sortie actuelle. Veuillez ajouter cette fonctionnalité.

+1

+1

+1

+1

+1

Suggestion liée tangentiellement:

Lorsque vous faites docker-compose logs -f , automatiquement par défaut à --tail=30 (ou tout autre nombre raisonnable)

docker-compose logs -f n'est pas suffisant car avec un grand nombre de journaux, cela prend beaucoup de temps

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

Ou il existe également cette solution de contournement

logpath=`docker inspect --format='{{.LogPath}}' reveelium_metricsextraction_1` && mv $logpath $logpath".bckup"

S'il vous plaît, arrêtez de commenter +1. Cela rend ce fil vraiment difficile à lire et à extraire des informations précieuses. Il y a un bouton de pouce vers le haut sur le post OP pour cela.

Rien ici ne fonctionne pour moi avec Docker pour mac. J'ai cependant piraté quelque chose qui fonctionne en lisant ce fil et les forums docker.

Le problème avec D4M, c'est que sur mac, vous devez réellement exécuter les commandes sur la vm xhyve. Alors, voici ce que j'ai trouvé. Ajoutez ces deux fonctions à votre .bash_profile .

Important : n'oubliez pas de démarrer un nouveau shell ou de recharger votre profil avant de continuer.


Maintenant, docker-logs-clean ressemble à ceci:

#!/bin/bash -e

if [[ -z $1 ]]; then
    echo "No container specified"
    exit 1
fi

logFile=$(docker inspect -f '{{.LogPath}}' $1 2> /dev/null)

echo -n "Cleaning ${logFile}... "
d4mexec << EOF
> $logFile
EOF
echo "done"

Notez que je ne suis pas rm ing le fichier journal, mais juste faire > , ce qui tronquera complètement le fichier.

FWIW dans la version 2 de docker-compose la fonctionnalité permettant de limiter la taille des fichiers journaux:

version: '2'
services:
  my-service:
    image: nginx:alpine
    restart: always
    logging:
      # limit logs retained on host to 25MB
      driver: "json-file"
      options:
        max-size: "500k"
        max-file: "50"

Il n'est pas très bien documenté sur le site Web de docker, et cela peut être utile à d'autres.

+1

+1

+1

+1

+1

J'ai fait un simple script docker_clear_log.sh :
sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' $1)
Utilisation: ./docker_clear_log.sh [Nom-ou-ID]
Cela devrait fonctionner si vous avez les droits sudo et le paramètre log_driver: "json-file" pour votre docker (par défaut).

+1

J'ai également essayé une solution temporaire et cela semble fonctionner

Le problème d'origine n'a jamais été résolu et le problème a été résolu de toute façon. Intéressant. @djessup , comment aimez-vous ces pommes?

serait toujours bien d'avoir un docker-compose les journaux --clean

Pourquoi ce problème a-t-il été clos sans même un commentaire alors que le problème en lui-même n'a pas été résolu?

@linvi

Quand je suis arrivé à ce fil, le commentaire de clôture avait été intégré à d'autres commentaires. C'est ici:

https://github.com/docker/compose/issues/1083#issuecomment -149357280

Je pense qu'ils espèrent couvrir ce cas d'utilisation particulier par des moyens indirects. Mentionnez votre cas d'utilisation particulier et comment il n'est pas couvert, et cela pourrait aider le ticket à être rouvert. Dans le pire des cas, quelqu'un pourrait vous indiquer un moyen facile d'obtenir ce que vous voulez: D

Les mises à jour?

quand il y a un journal, nous devrions pouvoir l'effacer de manière simple.

ce serait vraiment bien, si vous pouviez y intégrer la commande. cela ne semble pas difficile.
des milliers de personnes seraient très heureuses de ne pas avoir à tout faire défiler.

Si vous utilisez docker-compose, utilisez lazydocker pour afficher les journaux. Il n'est alors plus nécessaire de supprimer les journaux. Vous obtenez des journaux en direct et commencez avec les derniers journaux. Cela aide beaucoup au débogage.

grafik

https://github.com/jesseduffield/lazydocker
Vous pouvez l'installer avec une seule ligne et c'est un bon outil de surveillance. C'est dommage que les gens ne soient pas aussi raisonnables pour comprendre qu'une fonction "supprimer le journal" est une bonne chose.

Mais la solution de contournement avec le docker paresseux le fait pour moi. Merci jesseduffield de nous avoir donné la possibilité d'être paresseux avec votre outil de surveillance :-)
Envisagez peut-être de faire un don à lazydocker si cela vous facilite également le débogage / la surveillance.
Et pour vous les développeurs / mainteneurs de docker: pourquoi l'interface de docker n'est-elle pas comme ça?
Docker est assez génial, mais jetez un œil à lazydocker; il y a place à amélioration.

+2147483647

+49324893

Cette page vous a été utile?
0 / 5 - 0 notes