LoginSignup
5
5

More than 3 years have passed since last update.

PHP のエラーログを root が作成してしまってアプリから書けなくなる問題

Last updated at Posted at 2019-08-21

php のエラーログ、php.ini で次のように設定していると・・

error_log = /var/log/php/php.log
log_errors = On

なにかの拍子で root で php を実行してエラーが出力されると /var/log/php/php.log が root 所有の 0644 とかで作成されてしまい、アプリケーションの実行ユーザーからエラーログが書けなくなってしまいます。

この問題を解決するためのいくつかの案。

案:logrotate で 0666 でファイルを作成する

logrotate で次のように create 0666 root root を指定します。

/var/log/php/*.log {
  missingok
  notifempty
  create 0666 root root
}

こうしておけばローテーション時に 0666 でログファイルができるので、root でログに書き込んでしまっても Web アプリからのエラーログが書き込めなくなったりはしません。

と思ったら次のような問題があるらしいです。

logrotateがrenameして新しいファイルを作るよりはやくPHPのloggerがファイルを作ってしまい、logrotateがfile existsで死んでしまう。どうしてPHPはファイルを開きっぱなしにできないのかしら
https://twitter.com/kazeburo/status/960717004494684161

うーん・・・

案:php.ini ではエラーログを設定しない

php.ini ではエラーログのファイル名を空にして SAPI のデフォの出力先に出るようにします(CLI なら標準出力?か標準エラー?、mod_php なら Apache の error_log、php-fpm なら??)。

php.ini

error_reporting = -1
display_errors = off
display_startup_errors = off
error_log =
log_errors = On

その上で httpd.conf とか php-fpm.conf とかの SAPI に固有の設定ファイルでエラーログの出力先を指定します。

httpd.conf

php_value error_log /var/log/php/apache.log

php-fpm.conf

php_value[error_log] = /var/log/php/apache.log

もしくは php-<sapi>.ini のような特定の SAPI でだけ読まれる php.ini でも良いかもしれません。

cron とかから CLI を実行するときはコマンドラインオプションで指定します。

cron.d/app

SHELL=/bin/bash
MAILTO=root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
* * * * * apache php -d error_log=/var/log/php/batch.log -d display_errors=stderr /path/to/batch.php | logger -i -t app

logrotate では nocreate を指定します。

/var/log/php/*.log {
  missingok
  notifempty
  nocreate
}

これで不意に root で php -r xxx とかしてしまってもログファイルは作成されません。

さいごに

PHP を使い始めた最初のころから php.ini で↓みたいにするのは鉄板だと思ってたのですが、

error_log = /var/log/php/php.log
log_errors = On

実はそうでもなくて世間一般では SAPI 固有の設定ファイルで指定してたりする? のだろうか。いや、syslog という手もあるか。。。

追記

Web アプリケーションを root で動かすことは一般的にはありえないですが、サーバのオペレーション用のスクリプトやちょっとしたワンライナーを PHP で作って root で実行とかすると、サーバグローバルな php.ini でログを吐く設定していると問題になることがあるということですね。ログ以外でも php.ini で出力先が設定できるものは同様です(なにかあったっけ?思いつかない)。アプリケーションのキャッシュとかは PHP のコアが吐くわけではないので問題ありません(それはアプリケションが吐くものなので)。

もっとも、PHP で Web アプリケーション以外を作ることはまあまずないですけど・・実際のところシステムの運用中にこの問題が起こったことはないと思います。

ただ、たまに PHP が一番得意だという理由で PHP でなんでも書く人はいますしそれをあまり止めたりもしないです。もちろん、Web アプリケーションと同じ言語で書いてしまうと Web アプリケーションの都合で言語のバージョンアップをするときに影響範囲がわかりにくくなるので、サーバオペレーション系のスクリプトはディストリから提供されているものをそのまま使うのが良いだろうと思います(Bash とか Python とか)。Web アプリケーション用の PHP とサーバオペレーション用の PHP を別々に入れる? それはやめておいたほうが良いと思いますね、、、どっちの PHP で実行されるかわからなくて新規の人がとてつもなく混乱しそうです(勝手なイメージですが Ruby だと Web アプリケーションとサーバオペレーションをを同じ Ruby で実行してることが多そう?)。

5
5
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5