・参考資料 https://tt-computing.com/cake4_0-log-404
CakePHP3.10 で作られたシステムを CakePHP4.4.14 への移行を行いました。実施する上で既に実施された方々の十分な資料が有ったので、比較的スムーズに行きました。
ただ一点 404エラーを別ログファイルを記録する方法だけは参考資料通りでも上手く行かないので、試行錯誤してやっと出来る様になったので、こちらで情報を共有させて下さい。CakePHP 4.4 でエラー処理の仕組みを上位互換無い形で変更した事が原因です。
普通マイナーバージョンアップ時にこういう上位互換性が無い様な変更はして欲しくは無いですね。CakePHP5 がリリース候補 RC1 が出ているので、そこで入れるのはかまわないと思うのですが。
config/app.php
・エラーログのクラス指定と404エラーログの指定
'Error' => [
'errorLevel' => E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED,
'skipLog' => [],
'log' => true,
'trace' => true,
'ignoredDeprecationPaths' => [],
'logger' => App\Error\CustomErrorLogger::class, // ← 追加
],
/*
* Configures logging options
*/
'Log' => [
・・・・・
// 以下を追加
'error404' => [
'className' => FileLog::class,
'path' => LOGS,
'file' => 'error_404',
'url' => env('LOG_ERROR_URL', null),
'scopes' => ['error404'],
],
src/Error/CustomErrorLogger.php
・エラーロガーの実装
<?php
declare(strict_types=1);
namespace App\Error;
use Cake\Core\Exception\CakeException;
use Cake\Log\Log;
use Psr\Http\Message\ServerRequestInterface;
use Throwable;
use Cake\Error\ErrorLoggerInterface;
use Cake\Error\ErrorLogger;
class CustomErrorLogger implements ErrorLoggerInterface
{
/**
* @inheritDoc
*/
public function logMessage($level, string $message, array $context = []): bool
{
$logMessage_instance = new ErrorLogger();
return $logMessage_instance->logMessage($level, $message, $context);
}
public function log(Throwable $exception, ?ServerRequestInterface $request = null): bool
{
// 404 扱いとする Exception
$targetExceptions = [
'Cake\Controller\Exception\MissingActionException',
'Cake\Http\Exception\NotFoundException',
'Cake\Http\Exception\MissingControllerException',
'Cake\Http\Exception\InvalidCsrfTokenException',
'Cake\Routing\Exception\MissingRouteException',
'Cake\Routing\Exception\MissingControllerException',
'Cake\View\Exception\MissingTemplateException',
];
// 404 の場合は別ファイルにログを記述
$get_class_string = get_class($exception);
if (in_array(get_class($exception), $targetExceptions)) {
// 独自のログ内容
$url = $_SERVER['REQUEST_URI'];
$ip = $_SERVER['REMOTE_ADDR'];
$ip2 = $_SERVER['HTTP_X_FORWARDED_FOR']??''; // プロキシサーバーを通すと真のクライアントIP が取れないので、こちらを取得
$ua = $_SERVER['HTTP_USER_AGENT'];
$message = "{$url}\t{$ip}\t{$ip2}\t{$ua}\n\n";
return Log::error($message, ['scope' => 'error404']);
}
$log_instance = new ErrorLogger();
return $log_instance->log($exception, $request);
}
}
ネットを検索しても CakePHP4 の情報は本当に少ないので驚きました。公式マニュアルの日本語版でも、カスタムエラーログの部分は英語のままになってました。
自分の様な苦労をしない様に情報共有出来て、これが参考になれば嬉しいです。また改善案とかございましたら教えて下さい。