web-dev-qa-db-fra.com

Faire écrire une application Docker sur stdout

Je déploie une application tierce conformément à la 12 factor Advisory , et l'un des points indique que les journaux d'application doivent être imprimés sur stdout/stderr: le logiciel de clustering peut alors le collecter.

Cependant, l'application ne peut écrire que dans des fichiers ou syslog. Comment imprimer ces journaux à la place?

53
kolypto

Une recette étonnante est donnée dans le nginx Dockerfile :

# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /var/log/nginx/access.log \
    && ln -sf /dev/stderr /var/log/nginx/error.log

Simplement, l'application peut continuer à y écrire sous forme de fichier, mais en conséquence, les lignes iront à stdout & stderr!

118
kolypto

Dans une autre question, Tuer le processus enfant lorsque le parent quitte , j'ai obtenu la réponse qui a aidé à trier cela.

De cette façon, nous configurons l'application pour qu'elle se connecte à un fichier et en continu tail -f il. Heureusement, tail peut accepter --pid PID: il se fermera à la fin du processus spécifié. Nous mettons $$ there: PID du shell actuel.

Comme dernière étape, l'application lancée est exec 'ed, ce qui signifie que le shell actuel est complètement remplacé par cette application.

Script du coureur, run.sh, ressemblera à ceci:

#! /usr/bin/env bash
set -eu

rm -rf /var/log/my-application.log
tail --pid $$ -F /var/log/my-application.log &

exec /path/to/my-application --logfile /var/log/my-application.log

REMARQUE: en utilisant tail -F nous listons les noms de fichiers, et il les lira même s'ils apparaissent plus tard!

Enfin, le Dockerfile minimaliste:

FROM ubuntu
ADD run.sh /root/run.sh
CMD ['/root/run.sh']

Remarque: pour travailler quelques-uns extrêmement étranges tail -f comportement (qui dit "a été remplacé par un fichier distant. abandonner ce nom") j'ai essayé une autre approche: tous les fichiers journaux connus sont créés et tronqués au démarrage: de cette façon, je m'assure qu'ils existent, et alors seulement - - les queue:

#! /usr/bin/env bash
set -eu

LOGS=/var/log/myapp/

( umask 0 && truncate -s0 $LOGS/http.{access,error}.log )
tail --pid $$ -n0 -F $LOGS/* &

exec /usr/sbin/Apache2 -DFOREGROUND
16
kolypto

Pour un processus d'arrière-plan dans un conteneur Docker, par ex. connexion avec exec à/bin/bash que j'ai pu utiliser.

echo "test log1" >> /proc/1/fd/1

Cela envoie la sortie à la sortie standard du pid 1, qui est le seul pick-up Docker.

15
Pieter

pour nginx, vous pouvez avoir nginx.conf pointant vers /dev/stderr et /dev/stdout comme ça

user  nginx;
worker_processes  4;
error_log  /dev/stderr;
http {
    access_log  /dev/stdout  main;
...

et votre Dockerfile entrée doit être

/usr/sbin/nginx -g 'daemon off;'
6
Muayyad Alsadi