0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

CakePHP4.4 で 404エラーを別のログファイルに記録する

Last updated at Posted at 2023-06-30

・参考資料 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 の情報は本当に少ないので驚きました。公式マニュアルの日本語版でも、カスタムエラーログの部分は英語のままになってました。

自分の様な苦労をしない様に情報共有出来て、これが参考になれば嬉しいです。また改善案とかございましたら教えて下さい。

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?