ログ設計とは - アプリ開発で最初に決めるログレベルと出力項目
ログ設計とは、何をどの形式 / どのレベルで記録するかを実装前に決める設計活動。ログレベルの使い分け、含めるべき項目と禁止項目、保持期間とコストの目安を解説
ログ設計とは
ログ設計は、アプリケーションのログを構造化・分類し、効果的なデバッグと監視を実現する設計手法である。「何をログに出すか」「どの形式で出すか」「どの重要度で出すか」を実装前に決めておく活動で、障害が起きてから後悔する典型部位でもある。実行時の記録行為そのものはロギング、出力形式の話は構造化ログとして個別に解説しており、本項はその設計判断の全体を扱う。
ログレベルの使い分け
最初に決めるのはログレベルの規約だ。チームで基準を揃えないと、同じ事象が人によって ERROR にも INFO にもなり、アラートの信頼性が壊れる。
| レベル | 使いどころ | 例 |
|---|---|---|
| ERROR | 処理が失敗し、対応が必要 | 決済 API の呼び出し失敗 |
| WARN | 処理は継続できたが正常でない | リトライで回復した一時エラー |
| INFO | 正常系の重要イベント | 注文の受付完了、バッチの開始・終了 |
| DEBUG | 開発時の詳細な変数・分岐情報 | リクエストペイロードの中身 |
「ERROR は人が動く必要があるものだけ」と決めるのが要点で、放置してよい ERROR を許すと、監視は狼少年化して本物の障害を見逃す。
もう一つ決めておくのがレベル名の表記である。上の表は ERROR / WARN / INFO と大文字で示しているが、後述の構造化ログの例では level: 'error' と小文字で出している。CloudWatch Logs Insights の filter は文字列比較で大文字と小文字を区別するため、出力側で ERROR と error が混在すると filter level = 'error' は片方を取りこぼす。どちらに寄せるかを規約に書き、出力する直前で小文字化するなど機械的に揃えておく。
構造化ログ vs 非構造化ログ
非構造化ログは人間が読みやすいが、ツールでの検索・集計が困難である。構造化ログ (JSON) はフィールドごとにクエリできるため、CloudWatch Logs Insights で orderId や error を条件にした検索が即座に行える。
// ❌ 非構造化: 検索・分析が困難
console.log(`[ERROR] Order 123 failed: timeout after 5000ms`);
// ✅ 構造化 (JSON): CloudWatch Logs Insights で検索可能
console.log(JSON.stringify({
level: 'error',
message: 'Order processing failed',
orderId: '123',
error: 'timeout',
duration: 5000,
requestId: context.awsRequestId,
}));
ログに含めるべき情報
ログには、タイムスタンプ (いつ発生したか)、ログレベル (重要度の判断)、リクエスト ID (リクエストの追跡)、ユーザー ID (誰の操作か、PII に注意)、処理時間 (パフォーマンスの分析)、エラー情報 (スタックトレース、エラーコード) を含める。
ログに含めてはいけない情報
パスワード (セキュリティリスク)、アクセストークン (漏洩すると不正アクセス)、クレジットカード番号 (PCI DSS 違反)、個人情報 (GDPR / 個人情報保護法) はログに出力してはならない。
表で DEBUG の例に挙げたリクエストペイロードも、丸ごと出せばこの禁止項目を巻き込む。DEBUG なら許されるわけではなく、開発環境のログにも同じ基準を当て、ペイロードを出すならフィールドを選ぶかマスクしてから出す。
CloudWatch Logs Insights
CloudWatch Logs Insights の例を示す。
-- エラーの集計
filter level = 'error'
| stats count() as errorCount by error
| sort errorCount desc
-- 遅いリクエストの特定
filter duration > 3000
| fields @timestamp, orderId, duration
| sort duration desc
相関 ID (Correlation ID)
相関 ID (Correlation ID) のコード例を示す。
// API Gateway → Lambda A → Lambda B の呼び出しチェーンを追跡
// ヘッダー名は小文字化してから引く (下の注記を参照)
const headers = Object.fromEntries(
Object.entries(event.headers ?? {}).map(([k, v]) => [k.toLowerCase(), v]),
);
const correlationId = headers['x-correlation-id'] ?? crypto.randomUUID();
console.log(JSON.stringify({
correlationId,
message: 'Processing order',
}));
// 下流の Lambda にも correlationId を渡す
await invokeDownstream({ ...payload, correlationId });
ヘッダー名を決め打ちで引く実装は、X-Correlation-Id のように大文字混じりで送られた瞬間に undefined になり、下流で新しい ID が振られて追跡が切れる。例外は出ないため、障害調査でログを繋ごうとした時に初めて気付く。API Gateway の HTTP API (ペイロード形式 2.0) はヘッダー名を小文字化して Lambda へ渡すが、この正規化に頼らず受け取り側で小文字化してから引くほうが安全である。
ログの保持とコスト
dev 環境は 7 日 (コスト削減)、prod 環境は 90 日 (障害調査に十分)、監査ログは 1 年以上 (コンプライアンス) を目安に保持期間を設定する。
ログのアンチパターン
全てを DEBUG で出力するとコスト増とノイズの原因になる。エラーを握りつぶすと障害の検知が遅れる。非構造化ログは検索・分析が困難になる。機密情報の出力はセキュリティリスクを生む。
理論と実装の両面から学ぶなら関連書籍が参考になる。
この記事は役に立ちましたか?
関連用語
構造化ログとは - JSON ログの設計と検索性
構造化ログとは、ログを JSON など機械可読な形式で出力し、フィールド単位の検索 / 集計を可能にするロギング手法。非構造化ログとの違い、含めるべきフィールド、失敗パターンを解説
ロギング
アプリケーションの動作を記録し、デバッグ / 監視 / 監査に活用する仕組み
CloudWatch
AWS のモニタリング / ログ管理サービスで、メトリクス収集、ログ分析、アラートを提供する
オブザーバビリティ
システムの内部状態を外部から観測可能にし、問題の原因を迅速に特定するための仕組み
ログ集約
分散システムの複数サービスから出力されるログを一元的に収集 / 検索 / 分析する仕組み
相関 ID
分散システムで 1 つのリクエストに紐づく全ログを追跡するための一意な識別子
関連する記事
セキュリティ本ガイド - Web 開発者が読むべき技術書の選び方
Web セキュリティの基礎から実践まで学べる技術書の選び方マトリクスと、読了後にやるべき 3 つのアクションを紹介します。
エラーが出たときこそ本の出番
プログラミング中にエラーが出ると焦りますが、そんなときこそ本が役に立ちます。エラーと本の付き合い方を、初心者向けにやさしく解説します。
AWS 本の選び方 - 全体像 / 構築 / 設計 / 運用 / セキュリティの 5 視点
AWS を学ぶ技術書の選び方を「全体像 / 構築 / 設計 / 運用 / セキュリティ」の 5 視点で整理。公式ドキュメントと本の役割分担、資格対策書の位置づけまで、2026 年 8 月時点の定番書で AWS 独学のルートを解説します。