I'm building a docker image for a Symfony application. In this image, I want to stream the Symfony logs to stdout. So, similar to how nginx logs are configured, I added this line to my Dockerfile:
ln -sf /dev/stdout /var/www/project/app/logs/prod.log
Inside the container, I can see this:
$ 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
However, the app throws following error:
PHP Fatal error: Uncaught exception 'UnexpectedValueException' with message 'The stream or file "/var/www/project/app/logs/prod.log" could not be opened: failed to open stream: No such file or directory' in /var/www/project/app/cache/prod/classes.php:5808
Stack trace:
#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('critical', '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 [internal function]: Symfony\\Component\\Debug\\E in /var/www/project/app/cache/prod/classes.php on line 5808
Any suggestions ?
With the help of Monolog, it is very easy to send logs to stdout/stderr. My examples are using stderr, but I think it's the same with stdout.
Instead of defining a log file you just enter the preferred stream path
path: "php://stderr"
BUT you are not done yet. You also have to configure PHP accordingly. The workers have to catch the output of their processes and log this output again to their stderr.
PHP Configuration
#/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
Symfony Configuration
# 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
If you are using any process control system in a fat docker container you have to make sure that this system also logs to stdout (or stderr).
Example with supervisor:
[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
All in all make sure that:
My config to get all php infos / warnings / errors to docker log (I am using php:7.1-apache image):
php.ini
log_errors = On
error_reporting = E_ALL | E_STRICT
error_log = /dev/stderr
Symfony config
# app/config/config_prod.yml
monolog:
handlers:
main:
type: group
members: [logfile, dockerlog]
logfile:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: ['!event', '!doctrine']
dockerlog:
type: stream
path: "php://stderr"
level: debug
channels: ['!event', '!doctrine']
troubleshooting:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.