CS-Cart: エラーをログに出したり、Slackに通知したりする
CS-Cartはアーキテクチャがしっかりしていないというか、10年くらい前のアーキテクチャというか、とにかくフレームワークの作りがゆるいので、改修していると今時当たり前の仕組みが無かったりする。
その1つが、エラーの通知。CS-CartでFatalエラーやExceptionが発生しても、開発者は知るすべがない。致命的なエラーになると、ユーザには下のような画面が表示され、HTMLのソースコードにコメントでエラー情報が出力されるが、顧客から連絡がないと発見することができず、後手後手になってしまう。
CS-Cartはエラーをどうハンドリングしているか
CS-Cartがエラーをどう処理しているかだが、DEVELOPMENT環境かどうかで挙動が違う。まず、DEVELOPMENT環境ではない いわゆる本番環境では、次の処理をしている
-
register_shutdown_function
で、Fatalエラーになっても最悪画面が真っ白にならないようにエラー処理をしている - ログは取っていない
DEVELOPMENT環境では、これに加えて、
-
set_error_handler
で開発者用エラー画面を出すのと、error_logを実行する
くらいはやっている。
ソースコードをgrepしてみたが、exception handlerは使っていないので、Exceptionが発生してcatchされないと画面が真っ白になる。
CS-Cartでエラーをログに出す方法
CS-Cartならhookを使ってエラーハンドリングしたいところだが、エラー処理部分には残念ながらフックがない。したがって、エラーを捉える処理を実装しないとならない。
と言っても難しいことはなく、set_error_handler
, set_exception_handler
,
register_shutdown_function
でエラーハンドラをバインドしておけばいい。どこに、エラーログの処理を書くか悩ましいが、とりあえずlocal_conf.phpに書いておけばよいかと思う。
$reportError = function (Exception $exception) {
// ここでログをとる
};
set_error_handler(function ($severity, $message, $file, $line) use ($reportError) {
if (error_reporting() & $severity) {
$reportError(new ErrorException($message, 0, $severity, $file, $line));
}
});
set_exception_handler(function (Exception $exception) use ($reportError) {
$reportError($exception);
});
register_shutdown_function(function () use ($reportError) {
$error = error_get_last();
if (isset($error['type']) and in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING])) {
$reportError(new ErrorException($error['message'], 0, $error['type'], $error['file'], $error['line']));
}
});
set_error_handler
は1プロセスに1個しか登録できないのがPHPの仕様だが、CS-CartはDEVELOPMENT環境でないと、set_exception_handler
を使わないので気にせず登録してしまってOK。
register_shutdown_function
はPHPの仕様上、複数登録できるので問題ない。set_exception_handler
はそもそも使われていないので、登録してしまって構わない。
Slackにエラーを通知する方法
PHP: Slackにメッセージを投稿するクラス - Qiitaを使って、Slackにエラーを投げるようにする。
エラーをログにとるなら、エラーの文脈もあるとデバッグしやすいので、つけておく。
require_once __DIR__ . '/app/SlackNotifier.php';
$webhookUrl = 'https://hooks.slack.com/services/...';
$slackNotifier = new SlackNotifier($webhookUrl);
$reportError = function (Exception $exception) use ($slackNotifier) {
$user = \Tygh\Registry::get('user_info');
$slackNotifier->exception($exception, [
'HTTP_HOST' => @$_SERVER['HTTP_HOST'],
'REMOTE_ADDR' => @$_SERVER['REMOTE_ADDR'],
'REQUEST_METHOD' => @$_SERVER['REQUEST_METHOD'],
'url' => @"http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]",
'user_id' => @$user['user_id'],
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
'ajax?' => defined('AJAX_REQUEST') ? 'yes' : 'no',
]);
};
Author And Source
この問題について(CS-Cart: エラーをログに出したり、Slackに通知したりする), 我々は、より多くの情報をここで見つけました https://qiita.com/suin/items/cf348b08b6023b7638b2著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .