はじめに
- YUZURIHAの松村です。
- 先日担当しているプロジェクトのLaravelのバージョンを、9から10にメジャーアップデートしました。
- Laravel 10は公式のアップグレードガイドがあるので、基本的にはこちらの内容を参照しながら進めました。
- その中ではまったポイントをご紹介します。
バリデーション関連のメソッドの引数名がattributes
に変更
- Laravel 10では、バリデーション関連の
make
メソッドやvalidate
メソッドなどの引数名が、customAttributes
からattributes
に変更になりました。 - 担当しているプロジェクトでは、
validate
メソッドを使ってる箇所が多いためエラーになりました。 - この変更は公式のアップグレードガイドには記載されていないため、少しはまってしまいました。
Monolog 3アップデートによるLog records
のデータ型変更
- 今回のアップデートで一番はまったのがこちらです。
- 画面上は500エラーが表示されるものの、Laravelのログが一切出力されなかったのではまりました。
- webサーバ(nginx)のログを確認すると以下のように出力されていたので、まずこれでMonologに関するエラーであることがわかりました。
| 2023/11/15 02:59:06 [error] 11#11: *186 FastCGI sent in stderr: "PHP message: PHP Fatal error: Uncaught TypeError: App\Logging\LogFormatter::App\Logging\{closure}(): Argument #1 ($record) must be of type array, Monolog\LogRecord given, called in /var/www/app/vendor/monolog/monolog/src/Monolog/Handler/ProcessableHandlerTrait.php on line 56 and defined in /var/www/app/app/Logging/LogFormatter.php:37 | Stack trace: | #0 /var/www/app/vendor/monolog/monolog/src/Monolog/Handler/ProcessableHandlerTrait.php(56): App\Logging\LogFormatter->App\Logging\{closure}(Object(Monolog\LogRecord)) | #1 /var/www/app/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php(39): Monolog\Handler\AbstractProcessingHandler->processRecord(Object(Monolog\LogRecord)) | #2 /var/www/app/vendor/monolog/monolog/src/Monolog/Logger.php(389): Monolog\Handler\AbstractProcessingHandler->handle(Object(Monolog\LogRecord)) | #3 /var/www/app/vendor/monolog/monolog/src/Monolog/Logger.php(644): Monolog\Logger->addRecord(Object(Monolog\Level), 'App\\Logging\\Log...', Array)
- Laravelのアップグレードガイドを確認すると、Monologが3にメジャーアップデートされたことが記載されています。
- そこで、次はMonolog 3のアップグレードガイドを確認します。
- これで、
Log records
のデータ型が配列からMonolog\LogRecord
オブジェクトに変更されたことがわかりました。Log records have been converted from an array to a Monolog\LogRecord object with public (and mostly readonly) properties. e.g. instead of doing $record['context'] use $record->context. In formatters or handlers if you rather need an array to work with you can use $record->toArray() to get back a Monolog 1/2 style record array. This will contain the enum values instead of enum cases in the level and level_name keys to be more backwards compatible and use simpler data types.
- 担当しているプロジェクトでは、ログフォーマットの設定をする際に
$record
を配列として扱っていたため、ここが原因でエラーになっていたわけですね。 - 配列から
Monolog\LogRecord
オブジェクトとして扱うように修正して、500エラーを解消しました。 - めでたしめでたし!
今回の学び
- 今回はまったポイントの学びとしては、以下の2点になると思います。
アップグレードガイドがあったとしても、自分でコミットログやPull Requestを見に行く
- Laravelは比較的メジャーなFrameworkということもあり、公式で親切にアップグレードガイドを用意してくれています。
- しかし、それでも全てを網羅しているとは限らないので、アップグレードガイドを見て解決できない場合は自分でコミットログやPull Requestを調べることが大切ですね。
アプリケーション側を調査してわからなかったら、インフラ側を調査する
- 今回は「ログ出力の依存ライブラリのアップデートによって500エラーが発生したため、Framework自体のログが全く出力されなくなる」という事象が発生しました。
- 今回はnginxのログを見に行くことで解決に繋がりましたが、この事象はFrameworkのアップデートで十分起こり得るあるあるのように思います。
- やはり「アプリケーション側を調査してわからなかったら、インフラ側を調査する」という意識を持つのは大切ですね。