web-dev-qa-db-fra.com

Symfony se connecte à stdout à l'intérieur du conteneur Docker

Je crée une image docker pour une application Symfony. Dans cette image, je souhaite diffuser les journaux Symfony sur stdout. Donc, comme pour la configuration des journaux nginx, j'ai ajouté cette ligne à mon Dockerfile:

ln -sf /dev/stdout /var/www/project/app/logs/prod.log

À l'intérieur du conteneur, je peux voir ceci:

$ ls /var/www/project/app/logs/ -l
total 12
-rw-r--r-- 1 501 games 4473 Jul 21 08:36 dev.log
lrwxrwxrwx 1 501 games   11 Jul 21 08:35 prod.log -> /dev/stdout

Cependant, l'application génère l'erreur suivante:

Erreur fatale PHP: exception non interceptée 'UnexpectedValueException' avec le message 'Le flux ou le fichier "/var/www/project/app/logs/prod.log" n'a pas pu être ouvert: échec de l'ouverture du flux: aucun fichier ou répertoire de ce type' dans/var/www/project/app/cache/prod/classes.php: 5808
Trace de la pile:
# 0 /var/www/project/app/cache/prod/classes.php(5746): Monolog\Handler\StreamHandler-> write (Array)
# 1 /var/www/project/app/cache/prod/classes.php(5917): Monolog\Handler\AbstractProcessingHandler-> handle (Array)
# 2 /var/www/project/app/cache/prod/classes.php(6207): Monolog\Handler\FingersCrossedHandler-> handle (Array)
# 3 /var/www/project/app/cache/prod/classes.php(6276): Monolog\Logger-> addRecord (500, 'Fatal Error: Un ...', Array)
# 4 /var/www/project/app/cache/prod/classes.php(1978): Monolog\Logger-> log ('critique', 'Fatal Error: Un ...', Array)
# 5 /var/www/project/app/cache/prod/classes.php(2034): Symfony\Component\Debug\ErrorHandler-> handleException (Object (Symfony\Component\Debug\Exception\FatalErrorException) , Array)
# 6 [fonction interne]: Symfony\Component\Debug\E dans /var/www/project/app/cache/prod/classes.php sur la ligne 5808

Aucune suggestion ?

21
Webberig

Avec l'aide de Monolog, il est très facile d'envoyer des journaux à stdout/stderr. Mes exemples utilisent stderr, mais je pense que c'est la même chose avec stdout.

Au lieu de définir un fichier journal, vous entrez simplement le chemin de flux préféré

path:  "php://stderr"

MAIS vous n'avez pas encore fini. Vous devez également configurer PHP en conséquence. Les travailleurs doivent capturer la sortie de leurs processus et enregistrer à nouveau cette sortie dans leur stderr.

Configuration PHP

#/etc/php/7.0/fpm/php-fpm.conf
error_log = /proc/self/fd/2

#/etc/php/7.0/fpm/pool.d/www.conf
catch_workers_output = yes

Configuration de Symfony

# app/config/config_prod.yml
monolog:
    handlers:
        main:
            type:         fingers_crossed
            action_level: error
            handler:      nested
        nested:
            type:  stream
            path:  "php://stderr"
            level: debug
        console:
            type:  console

Si vous utilisez un système de contrôle de processus dans un conteneur Fat Docker, vous devez vous assurer que ce système se connecte également à stdout (ou stderr).

Exemple avec superviseur:

[supervisord]
nodaemon=true
;@see http://blog.turret.io/basic-supervisor-logging-with-docker/
;we need the output from the controlled processes
;but this is only possible with lowered loglevel
loglevel=debug

Dans l'ensemble, assurez-vous que:

  • L'application se connecte à stdout/stderr
  • PHP attrape la sortie des travailleurs et les journaux sur stderr
  • facultatif: tout système de contrôle de processus doit transmettre la sortie des processus gérés à stdout/stderr
35
frastel