CakePHP 4.4 で Not Found 系エラーを別ログに保存する方法
はじめに
以前 「CakePHP 4.0 で 404 Not Found エラーを別ログに保存する方法」 を投稿しましたが、CakePHP 4.4.0 から仕様が変わり、実装方法にも少し違いがあります。
- Error & Exception Configuration (Error & Exception Handling - 4.x)
- https://book.cakephp.org/4/en/development/errors.html#error-exception-configuration
- Custom Error Logging (Error & Exception Handling - 4.x)
- https://book.cakephp.org/4/en/development/errors.html#custom-error-logging
今日は CakePHP 4.4 で 404 系エラーログを別ファイルに保存する方法をご紹介します。
1. 実装方法
まず config/app.php に下記のように追記します。
config/app.php
<?php
use App\Error\AppErrorLogger; // ←追加
...
return [
...
'Error' => [
...
'logger' => AppErrorLogger::class, // ← 追加
],
...
'Log' => [
// 以下を追加
'error404' => [
'className' => FileLog::class,
'path' => LOGS,
'file' => 'error_404',
'url' => env('LOG_ERROR_URL', null),
'scopes' => ['notFound'],
],
...
そして src/Error/AppErrorLogger.php を作成します。
src/Error/AppErrorLogger.php
<?php
declare(strict_types=1);
namespace App\Error;
use Cake\Error\ErrorLogger;
use Cake\Log\Log;
use Psr\Http\Message\ServerRequestInterface;
use Throwable;
/**
* Application ErrorLogger
*/
class AppErrorLogger extends ErrorLogger
{
/**
* @inheritDoc
*/
public function logException(
Throwable $exception,
?ServerRequestInterface $request = null,
bool $includeTrace = false
): void {
// 404 扱いとする Exception
$targetExceptions = [
'Cake\Controller\Exception\MissingActionException',
'Cake\Datasource\Exception\RecordNotFoundException',
'Cake\Http\Exception\MissingControllerException',
'Cake\Http\Exception\NotFoundException',
'Cake\Routing\Exception\MissingRouteException',
];
// 404 エラーの場合は config/app.php に追加した error404 の設定を使用
$expClass = get_class($exception);
$is404 = in_array($expClass, $targetExceptions);
$context = $is404 ? ['scope' => 'notFound'] : [];
// ログに記載する内容を取得
$message = $this->getMessage($exception, false, $includeTrace);
if ($request !== null) {
$message .= $this->getRequestContext($request);
}
Log::error($message, $context);
}
}
以上で実装は終わりです。
あとは存在しない URL にアクセスしたりして、動作確認をしてみてください。
問題がなければ logs/error_404.log に出力されます。
2. ログ出力内容の変更
error_404.log に出力する内容を変更したい場合には、AppErrorLogger.php を下記のように変更すれば OK です。
src/Error/AppErrorLogger.php
// ログに記載する内容を取得 (以下を変更)
if ($is404) {
$url = $_SERVER['REQUEST_URI'];
$ip = $_SERVER['REMOTE_ADDR'];
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
$message = "{$url}\t{$expClass}\t{$ip}\t{$ua}";
} else {
$message = $this->getMessage($exception, false, $includeTrace);
if ($request !== null) {
$message .= $this->getRequestContext($request);
}
}
3. おわりに
執筆時点では、下記日本語ドキュメントには 4.4 の更新情報が反映されていません。
- エラーと例外の設定 (エラーと例外の処理 - 4.x)
- https://book.cakephp.org/4/ja/development/errors.html#error-configuration
- Custom Error Logging (エラーと例外の処理 - 4.x)
- https://book.cakephp.org/4/ja/development/errors.html#custom-error-logging
日本語ドキュメント通りにやってうまくいかないときは、英語版を参照することをお勧めします。
今回のように最新バージョンが反映されていない場合は 「prior to」 という英単語がキーワードの一つになるかと思います。
- 英語「prior to」の意味・使い方・読み方 | Weblio英和辞書
- https://ejje.weblio.jp/content/prior+to