web-dev-qa-db-ja.com

SymfonyはDockerコンテナー内のstdoutにログを記録します

Symfonyアプリケーションのdockerイメージを作成しています。この画像では、Symfonyログをstdoutにストリーミングします。したがって、nginxログの構成方法と同様に、次の行をDockerfileに追加しました。

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

コンテナ内では、これを見ることができます:

$ 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

ただし、アプリは次のエラーをスローします。

PHP致命的エラー:「ストリームまたはファイル "/var/www/project/app/logs/prod.log"を開くことができませんでした:ストリームを開くことができません:そのようなファイルまたはディレクトリはありません」というメッセージを含むキャッチされない例外 'UnexpectedValueException' var/www/project/app/cache/prod/classes.php:5808
スタックトレース:
#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) 、配列)
#6 [内部関数]:5808行の/var/www/project/app/cache/prod/classes.phpのSymfony\Component\Debug\E

助言がありますか ?

21
Webberig

Monologの助けを借りて、ログをstdout/stderrに送信するのは非常に簡単です。私の例ではstderrを使用していますが、stdoutでも同じだと思います。

ログファイルを定義する代わりに、優先ストリームパスを入力するだけです

path:  "php://stderr"

しかし、まだ完了していません。また、PHPを適宜設定する必要があります。ワーカーはプロセスの出力をキャッチし、この出力をstderrに再度記録する必要があります。

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

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

Fat dockerコンテナでプロセス制御システムを使用している場合、このシステムがstdout(またはstderr)にもログを記録することを確認する必要があります。

スーパーバイザーとの例:

[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

全体として、次のことを確認してください。

  • アプリケーションはstdout/stderrにログを記録します
  • PHPはワーカー出力をキャッチし、stderrにログを記録します
  • オプション:プロセス制御システムは、管理対象プロセスの出力をstdout/stderrに転送する必要があります
35
frastel