SlideShare a Scribd company logo
Norikraで作る
PHPの例外検知システム
YAPC::Asia Tokyo 2015 LT
Masahiro Nagano @kazeburo
PHPはじめました
長年Perlをやってきましたが
PHPの例外を検出し
通知するシステム
Catch PHP Exception and send it to Slack
STEP 1
例外をログに記録する
Log the PHP Exception
Try-Catch
try {
throw new MyAppException('Boofy');
} catch (Exception $e ) {
$msg = json_encode(array(
'message' => $e->getMessage(),
'_exception' => array(
'class' => get_class($e),
'message' => $e->getMessage(),
'trace' => ..
),
)). "n";
error_log($msg, 3, '/path/to/app_error_log');
}
set_exception_handler
set_exception_handler(function($e) {
$msg = decorate_exception($e);
error_log($msg, 3, '/path/to/app_error_log');
});
throw new MyAppException('Boofy');
try-catch外で発生した例外を補足
Catch the PHP Exception outside Try-Catch
set_error_handler
set_error_handler(
function($severity, $msg, $file, $line){
throw new ErrorException(
$msg, 0, $$severity, $file, $line
);
}
);
PHPではエラーと例外は別物
エラーを例外に変換
Convert Error to Exeption
これらの機能を使っても
補足できない例外がある
(例)
syntax error、存在しないメソッドの呼び出し
Can’t all Exception with these functions
error_reporting & error_log
error_reporting(E_ALL | E_STRICT);
ini_set('error_log', '/path/to/php_log');
致命的エラーをログに記録
php.ini でも書ける
Log Fatal Errors to the log file
Apache vhost ErrorLog
<VirtualHost *:80>
ServerName api.example.com
ErrorLog /path/to/error_log
</VirtualHost>
php.ini にerror_logの設定がなく
ini_set 前にエラーが発生した場合
Apache ErrorLog
ErrorLog /var/log/httpd/error_log
Segmentation fault など
Apacheのworkerプロセスの不正終了
ここまでまとめ
PHP(mod_php)のエラーログは全部で
4つのファイルに記録される
ここまでが長かった
弊社の環境では
STEP 2
例外の集約から通知
構成
App
App
App SQLを投入
エラーログをfluentdでNorikraに送り
リアルタイムに集計してSlackに通知
fluentd
<source>
type tail
format json
path /path/to/app_error_log
tag nohostname.error_app_log
</source>
<source>
type tail
format /^[(?<time>[^]]*)] (?<message>.*)$/
time_format %d-%b-%Y %H:%M:%S
path /path/to/php_log
tag nohostname.apache_error
</source>
<source>
type tail
format /^[[^ ]* (?<time>[^]]*)] [(?<level>[^]]*)](?: [pid (?<pid>[^]]*)])? [client (?<client>[^]]*)] (?<message>.*?)(?:, referer: (?
<referer>.*))?$/
path /path/to/error_log
tag nohostname.apache_error
</source>
<source>
type tail
format /^[[^ ]* (?<time>[^]]*)] [(?<level>[^]]*)](?: [pid (?<pid>[^]]*)])? [client (?<client>[^]]*)] (?<message>.*?)(?:, referer: (?
<referer>.*))?$/
path /var/log/httpd/error_log
tag nohostname.apache_error
</source>
<match nohostname.**>
type record_reformer
tag ${tag_suffix[1]}
hostname ${hostname}
</match>
<match {error_app_log,apache_error}>
type forward
<server>
name cep
host cep
</server>
</match>
in_tail x 4
hostname追加
集約サーバへの送信
Norikra
•Norikra とはリアルタイムイベントスト
リームに対して SQL ラ��クな言語で処
理できる super cool なプロダクト
Norikra Query
SELECT
"alert-channel" as channel,
"[..][" || hostname || "] Detect *"
|| CAST(COUNT(*), string)
|| "* PDOException in this 1min: ```" || message
|| "``` action: `"
|| COALESCE(NULLABLE(action),"-") || "`" AS msg
FROM error_app_log.win:time_batch(1 min)
WHERE exception.class = "PDOException"
OR ( _exception.class = "ErrorException"
AND _exception.message LIKE "PDOStatement%" )
GROUP BY hostname, message, action
HAVING COUNT(*) > 0
表示例
まとめ
• Norikra便利
• PHPのエラーログはつらい
• 扱いづらいPHPのエラー処理を適当にいなす
- uzullaがブログ
• http://uzulla.hateblo.jp/entry/
2013/12/20/041619
He is an awesome
PHP guy!!!
おわり

More Related Content

Norikraで作るPHPの例外検知システム YAPC::Asia Tokyo 2015 LT