@@ -568,15 +568,102 @@ ANSIエスケープのよくある課題は、ANSIエスケープシーケンス
568568}
569569` ` `
570570
571- ## 稼働中のログ出力
571+ ## Web APIのログ出力
572572
573- - バッチの進行中
574- - IF等での一括処理時は処理状況を一定タイミングでロギング(xx行目\~xx行目処理中 など)
575- - ハングしていないことの確認
573+ Web APIアクセスに対して適切にログ出力することで、不具合検知やセキュリティインシデントの調査、性能分析などに役立てることができる。
574+
575+ ### アクセスログ
576+
577+ アクセスログは、システムに対するリクエストとレスポンスの記録である。出力タイミングは 推奨順に3パターンがある。
578+
579+ 1. (推奨)リクエスト/レスポンスの両方で出力(リクエストとレスポンスの両方を出すことで、調査性を上げる。ログ量は倍になるが、保守運用性を高めることを優先するため)
580+ 1. レスポンス後に出力(処理時間やステータスコードを出力できるため)
581+ 1. リクエストが届いた瞬間に出力
582+
583+ ::: tip ヘルスチェックのアクセスログは出力させない
584+ ヘルスチェックに対するアクセスログは除外するような分岐を入れた方が良い。ヘルスチェックAPIはロードバランサーなどシステム内部側で利用されるため、ログを出力すると調査分析の妨げになるし、余計なキャッシュアウトにも繋がるためである。
585+ :::
586+
587+ ::: tip OPTIONSのログは出すべきか?
588+ Web API設計ガイドライン > [機能配置](/documents/forWebAPI/web_api_guidelines.html#機能配置aws)では、CORS対応のためのOPTIONSメソッドはAPIゲートウェイなどで対応させることが推奨である。もし、アプリケーション側でOPTIONSメソッドを実装する場合は、トラブルシューティングやセキュリティ上の監視に役立つため、特にHTTPメソッドで絞らずそのままログを出しておく方が良い。
589+ :::
590+
591+ ::: info 参考
592+ [OWASP/CheatSheetSeries](https://github.com/OWASP/CheatSheetSeries)の[cheatsheets/Logging_Cheat_Sheet.md](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Logging_Cheat_Sheet.md)
593+ :::
594+
595+ ### ログ項目
596+
597+ 「推奨するキー名称」で定義した共通スキーマに加え、以下の項目を出力する。
598+
599+ | 項目 | 項目 | 要求時 | 応答時 | 備考 |
600+ | :--------------- | :--------------------------- | :----- | :----- | :------------------------------------------------------------------------------------------------------------------- |
601+ | タイムスタンプ | timestamp | ✅️ | ✅️ | ISO 8601形式でミリ秒まで保持する。タイムゾーンはUTC 2024-10-12T11:23:01.123Z またはJST 2024-10-12T20:23:01.123+09:00 |
602+ | ログレベル | severity.tex | ✅️ | ✅️ | info固定または、要求時をdebug・応答時にinfoにしても良い |
603+ | リクエストID | request.id | ✅️ | ✅️ | トレース用のID。リクエストヘッダーに存在する場合はそれを、存在しなければサーバ側で採番した値を出力 |
604+ | URLパス | url.path | ✅️ | ✅️ | 相対パス。 ` /api/v1/users` |
605+ | HTTPメソッド | http.request.method | ✅️ | ✅️ | HEAD,GET,POST,PUT,PATCH,DELETE |
606+ | 送信元IPアドレス | client.address | ❓️ | ❓️ | パブリックAPIの場合、個人情報特定に繋がる可能性があるため、出力可否はプロジェクトのセキュリティ基準に従う |
607+ | ユーザーID | user_id | ❓️ | ❓️ | ログイン済みの場合、ユーザーIDを出力する |
608+ | ステータスコード | http.response.status_code | ー | ✅️ | HTTPステータスコード |
609+ | 処理時間 | http.server.request.duration | ー | ✅️ | ミリ秒を推奨 |
610+ | User Agent | user_agent.original | ✅️ | ✅️ | クライアントの特定に利用する。 |
611+
612+ ## バッチ実行時のログ出力
613+
614+ バッチ処理でも適切なログを出力することで、何か課題が生じた際に解析の手がかりとなり、保守運用時コストを低減させることができる。
615+
616+ 推奨は以下。
617+
618+ - 起動・終了はログ出力する
619+ - 機能ID、バージョン、実行時間、パラメータなど決められた項目を出力することでトレースしやすくする
620+ - 何かしらの共通機能側で設定できると良い
621+ - 処理件数をログ出力する
622+ - 特に。0件でスキップしたのであれば、その旨もINFOログに出す
623+ - 結合テスト時などで、出力先のDBテーブルに書き込みがゼロ件だった場合に、調査したいことは意外と多い
624+ - 進行中のログ
625+ - 大量件数をループで処理する場合は進行状況が分かるように、例えば1万件ごとにログが出すと良い(入力の処理件数と合わせると、大体の終了時間の見込みが立てられるため)
626+ - バッチ処理がロック待ちなど何かしらの理由でハングしてしまったのか、進んでいるか見極めたい場合がある
576627- SQL実行ログについて
577628 - twoway-sql の場合は、生成後のSQLにたいして フォーマットして出力することが望ましい
578- - ヘルスチェックのログは、アクセスログに出さないように制御する
579- - ログ検索で除外できるとはいえ、ノイズである。また、ヘルスチェックのログを見る用途は稼働してしまえば存在しないため、不要な費用発生である
629+ - ループ処理でのログ出力はセーブする
630+ - Amazon CloudWatch Logsなどは思いの外コストが高いため、例えば数千件オーダーから1行ずつログ出力すると、想定外の費用となる
631+ - ループ内ではなく外にするか、1万件ごとにログ出力するなど工夫をする
632+
633+ 出力例:
634+
635+ ` ` ` json
636+ // 開始時
637+ {
638+ " timestamp" : " ..." ,
639+ " severity.text" : " INFO" ,
640+ " message" : " 月次集計バッチを開始します" ,
641+ " batch.job_id" : " monthly-aggregate" ,
642+ " batch.params" : {" target_month" : " 2025-09" }
643+ }
644+
645+ // 進行中(サンプリング)
646+ {
647+ " timestamp" : " ..." ,
648+ " severity.text" : " INFO" ,
649+ " message" : " 集計処理進行中: 10000 / 50000 件完了 (20%)"
650+ }
651+
652+ // 終了時
653+ {
654+ " timestamp" : " ..." ,
655+ " severity.text" : " INFO" ,
656+ " message" : " 月次集計バッチを正常終了しました" ,
657+ " batch.result" : " success" ,
658+ " batch.stats" : {
659+ " total" : 50000,
660+ " success" : 49998,
661+ " failed" : 2,
662+ " skipped" : 0
663+ },
664+ " duration_ms" : 120500
665+ }
666+ ` ` `
580667
581668## 非正規化
582669
@@ -669,9 +756,9 @@ ANSIエスケープのよくある課題は、ANSIエスケープシーケンス
669756
670757推奨は以下の通り。
671758
672- - 機密情報をログ出力しない
673- - パスワード、APIキー、クレジットカード番号、個人情報(PII)などのログ出力は禁止する
674- - 誤って出力されないように、ログ出力のフレームワーク側でもマスキングやオミットするような作り込みを行っておく
759+ - 機密情報をログ出力しない。どうしても必要な場合はマスキングする
760+ - セッションID、アクセストークン、 パスワード、APIキー、クレジットカード番号、個人情報(PII)、ユーザーが収集に同意していない情報(GDPR)
761+ - 誤って出力されないように、ログ出力のフレームワーク側でもマスキングやオミットするような作り込みを行っておく
675762 - 機密フィールドを除外した、JavaでいうtoString()メソッドやDTO(構造体など)を作っておく
676763- アクセス制御
677764 - ログの不正な改ざんを防ぐため、一度書き込まれたら変更、削除できないようなIAMロール設定を行う
0 commit comments