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?

【コツコツAWS】CloudWatch Logs -仕組みと代表的なログ-

0
Posted at

Amazon CloudWatch Logsに関して、勉強したことを残します。
AWSでは多くのログをCloudWatch Logsでまとめて見ることができますが、何がどんなログなのかを全く理解していませんでした。
今回はCloudWatch Logsの仕組みと、代表的なログの形式、CloudWatch Logsに集めて何ができるのかを整理します。

CloudWatch Logsの基本

CloudWatch Logsはログを集めて、保存・検索・監視するためのサービスです。まず用語としてよく出るのが以下の3つ。

用語 内容
ログイベント 1件のログ
ログストリーム 同じ出どころから出たログイベントの並び
ロググループ ログストリームをまとめる単位

用語の説明だけだとイメージしづらいですが、1つのLambda関数を例にすると↓のような階層関係になります。
コンソールでもロググループ → ログストリーム → ログイベントと選んでいけば、最終的にログの生データにたどり着きます。

用語の関係
/aws/lambda/<関数名>                          ← ロググループ (この関数専用の置き場)
├── YYYY/MM/DD/[$LATEST]<実行環境AのID>       ← ログストリーム (実行環境Aが出した分)
│     ├── INIT_START Runtime Version: ...    ← ログイベント
│     ├── START RequestId: ...
│     ├── <コードの出力>
│     ├── END RequestId: ...
│     └── REPORT RequestId: ... Duration: ... ms ...
├── YYYY/MM/DD/[$LATEST]<実行環境BのID>       ← ログストリーム (実行環境Bが出した分)
└── YYYY/MM/DD/[$LATEST]<実行環境CのID>       ← ログストリーム (実行環境Cが出した分)

ログの中身は「時刻」と「文字列」だけ

ログイベントに入るのは、タイムスタンプとテキスト(UTF-8の文字列)の2つだけです。そして、**ログの形式はCloudWatch Logsではなく、ログを出すサービス側が決めます。**よってログの分析を行うには、「サービスごとのログの読み方」を知る必要があります。

Lambdaのログ

ログ形式がサービスごとに違うということで、Lambdaのログがどんなものか確認します。
Lambda関数のログは、何も設定しなければ/aws/lambda/<関数名>というロググループに出力されます。

Lambdaのログイベント (テキスト形式)
INIT_START Runtime Version: python:***	Runtime Version ARN: arn:aws:lambda:***
START RequestId: *** Version: $LATEST
<コードの出力 (printやloggingの内容)>
END RequestId: ***
REPORT RequestId: *** Duration: *** ms Billed Duration: *** ms Memory Size: *** MB Max Memory Used: *** MB Init Duration: *** ms

ログの中身は大きく分けて以下の2種類。

  • システムログ: Lambdaが出すログ。 (INIT_START / START / END / REPORTの行)
  • アプリケーションログ: 関数のコードが出すログ。 (printやloggingの出力で、STARTとENDの間に入る)

コードが何も出力しなくても、1回の実行につき最低3行(START, END, REPORT)は出力されます。(初回実行だけ、INIT関係のログもあり)
RequestIdが1回の実行ごとのIDなので、これを目印にすればどこからどこまでが同じ実行ログかが分かります。

前述の通りログストリームは実行環境ごとなので、同じ実行環境が使い回されている間は、何回実行しても同じストリームに追記されていきます。

Lambdaのログ形式はテキストの他にJSONも選べます。
出力先のロググループも指定できるので、複数の関数のログを1つのロググループにまとめることも可能です。(その場合、ログストリーム名に関数名が入るようです)

CloudWatch Logsに出せる主なログ

Lambda以外にも、多くのサービスがCloudWatch Logsにログを送れます。
自分が使いそうなものを中心に、公式ドキュメントを確認してまとめたのが以下の表です。(サービスによってはCloudWatch Logsの他に、Amazon S3やAmazon Data Firehoseも送信先に選べます)

ログ ログから分かること CloudWatch Logs S3 / Firehose
AWS Lambda ログ 実行時間・消費メモリ・コードの出力 ○ ○
Amazon API Gateway アクセスログ 誰がどうAPIを呼んだか ○
Amazon CloudFront アクセスログ リクエストの時刻・応答関係 ○ ○
Amazon Cognito ログ メール/SMSの送信失敗など ○
AWS Step Functions ワークフローログ ワークフローの実行履歴 ○
VPC フローログ 通信の送信元・宛先・許可/拒否 ○ ○
Amazon S3 サーバーアクセスログ バケットへのリクエストの記録 ○ ○
AWS CloudTrail ログ 誰がどのAPIを実行したか ○
AWS CodeBuild ログ ビルドの各フェーズとコマンド出力 ○
Amazon SNS ログ メッセージ配信の成否と応答 ○
Amazon Bedrock AgentCore Runtime ランタイムの標準出力など ○ ○
Amazon EventBridge (パイプ/イベントバス) イベントの受信・配信の経過 ○ ○
AWS WAF ログ リクエストと一致したルール ○ ○

各サービスのログ形式

上記表にある、Lambda以外のサービスのログについて、全てではありませんが中身を確認したものを残します。
多くのサービスがデフォルトで無効となっており、必要に応じて形式やログに出力するフィールドを設定する必要があるようです。

API Gateway

上述したアクセスログの他に実行ログもあり、別々に有効化できます。

実行ログ アクセスログ
内容 リクエストを処理する過程 (エラーや実行トレース等) 誰がどうAPIにアクセスしたか
ロググループ API-Gateway-Execution-Logs_{rest-api-id}/{stage_name} 自分で作成して指定
形式 API Gatewayが決める。(1イベント1KBで切り捨て) 自分でCLF, JSON等の形式を決める。 ($context.requestIdまたは$context.extendedRequestIdは必須)
有効化 loggingLevelをERROR/INFOにして有効化 ステージに出力先と形式を設定して有効化

CloudFront アクセスログ

CloudFrontが受けたリクエストの詳細 (受信時刻、処理時間、サーバーの応答等)が分かります。用途としては応答時間やトラブルシューティングの分析。
デフォルトは無効で、ディストリビューションの設定で送信先や形式を指定して有効化します。

jsonでのログ例 (ドキュメントから引用)
{
"date": "2024-11-14",
"time": "21:34:06",
"x-edge-location": "SOF50-P2",
"asn": "16509",
"timestamp(ms)": "1731620046814",
"origin-fbl": "0.251",
"origin-lbl": "0.251",
"x-host-header": "d111111abcdef8.cloudfront.net",
"cs(Cookie)": "examplecookie=value"
}

上記の例以外にもフィールドには様々なものを設定できるようです。

Cognito ログ

配信に対してと、ユーザーアクティビティに対しての2種類のログがあり。
デフォルトでは無効で、ロググループを指定する必要があります。(形式はjson)

通知の配信エラー (userNotification) ユーザーアクティビティ (userAuthEvents)
何が分かるか ユーザープールがSES / SNS経由で送るメール・SMSの配信エラー サインイン・サインアウトなど認証操作の詳細とセキュリティ評価
ログレベル ERROR INFO
送信先 CloudWatch Logs CloudWatch Logs/Firehose/S3のいずれか
条件 Plusプラン不要 Plusプラン + 脅威保護が有効
設定方法 APIかSDKのみ (SetLogDeliveryConfiguration) APIまたはコンソール

VPCフローログ

こちらもデフォルトでは無効。フローログを作成して、ロググループを指定すれば有効になります。(ログストリーム名は<ENIのID>-all)

ログ例
2 123456789012 eni-0123456789abcdef0 203.0.113.12 10.0.0.10 49152 443 6 10 840 1700000000 1700000060 ACCEPT OK
2 123456789012 eni-0123456789abcdef0 198.51.100.7 10.0.0.10 51000 23 6 1 44 1700000000 1700000060 REJECT OK
2 123456789012 eni-0123456789abcdef0 - - - - - - - 1700000000 1700000060 - NODATA

出力されるログはスペース区切りのテキスト。デフォルト形式 (version 2)では以下の並びのようです。
version account-id interface-id srcaddr dstaddr srcport dstport protocol packets bytes start end action log-status

id以降のフィールドの内容は以下の通り。

フィールド 内容
srcaddr / dstaddr 送信元 / 宛先IP
srcport / dstport 送信元 / 宛先ポート
protocol プロトコル番号
packets / bytes 集約期間中のパケット数 / バイト数
start / end 集約期間内の最初 / 最後のパケットの時刻 (Unix秒)
action ACCEPT / REJECT
log-status OK / NODATA など

S3 サーバーアクセスログ

バケットに対するリクエストが記録されます。 (バケット名、時刻、リクエスト元のIP、リクエストした主体、操作、オブジェクトのキーなど)
セキュリティやアクセスの監査、S3の請求の理解に使用。

CloudWatch Logs S3の汎用バケット
形式 構造化されたJSON スペース区切りのテキスト
検索 Logs Insights Athena
料金 ログの取り込み料金 保管料金のみ
制約 クロスアカウント / クロスリージョンに対応 同じアカウント・リージョンのバケットのみ
textでのログ例
79a59df9... amzn-s3-demo-bucket1 [06/Feb/2019:00:01:57 +0000] 192.0.2.3 79a59df9... DD6CC733AEXAMPLE REST.PUT.OBJECT s3-dg.pdf "PUT /amzn-s3-demo-bucket1/s3-dg.pdf HTTP/1.1" 200 - - 4406583 41754 28 "-" "S3Console/0.4" - ...

CodeBuild ログ

記事作成時点では、Buildプロジェクト作成時にログ有効化のオプションがONになっているので、チェックを外さない限りはログが出力されます。(ログストリーム名はビルドID)

ログ例
[Container] YYYY/MM/DD hh:mm:ss.ssssss Running on CodeBuild On-demand
[Container] YYYY/MM/DD hh:mm:ss.ssssss Phase is DOWNLOAD_SOURCE
[Container] YYYY/MM/DD hh:mm:ss.ssssss Running command <buildspecに書いたコマンド>
<コマンドの出力>

[Container] で始まる行がCodeBuildのログ、それ以外がbuildspecのコマンドの出力になります。

AWS WAF

WAFが検査したリクエストの詳細と、そのリクエストがどう処理されたかが分かります。
形式はjsonで、主なフィールドは以下の通り。

フィールド 内容
action WAFがリクエストに適用した最終的なアクション (allow / block / CAPTCHA / challenge)
httpRequest リクエストのメタデータ
clientIp / country リクエスト元のIPアドレス / 国
httpMethod / headers / args HTTPメソッド / ヘッダー / クエリ文字列
httpSourceName リクエストの経路 (CF = CloudFront、APIGW = API Gateway、ALB、COGNITOIDP など)
nonTerminatingMatchingRules マッチしたが処理を終了しなかったルール (countなど)
rateBasedRuleList 評価されたレートベースルール
labels ルールがリクエストに付けたラベル

デフォルトでは無効で、有効化にはロググループの指定が必要。Web ACLと同じリージョンであることや、ロググループ名を指定の形にする必要があるようです。

CloudWatch Logsでできること

ログをCloudWatch Logsに集めると、以下のようなことができます。Logs Insightsとメトリクスフィルターの2つはよく目にするイメージです。

機能 できること
CloudWatch Logs Insights クエリ言語でログを検索・集計
メトリクスフィルター ログのパターンを数えたり値を抜き出したりしてメトリクス化 (グラフやアラームに使える)
サブスクリプションフィルター ログをリアルタイムで他のサービス(Lambda、Firehoseなど)に流す
Live Tail 取り込まれるログをほぼリアルタイムで表示
データ保護 ログに含まれる機密データの検出とマスク
保持期間の設定 ログを残す期間をロググループごとに指定
S3へのエクスポート 長期保管や他のツールでの分析用に書き出し

Logs Insightsでの検索・集計

前述の通り、ログイベントの中身はただの文字列ですが、Logs Insightsは一部のログについて、メッセージの中身を解釈してフィールドとして扱えるようにしてくれます。

ログの種類 自動で検出されるフィールド
Lambda @requestId @duration @billedDuration @type @maxMemoryUsed @memorySize
VPC Flow Logs srcAddr dstAddr srcPort dstPort protocol packets bytes action logStatus など
JSON形式のログ (CloudTrailなど) JSONのキーがそのままフィールドになる
その他 @timestamp @message @logStream などの共通フィールドのみ

LambdaやVPCフローログはテキスト形式のままでも、フィールド名を使って絞り込みや集計ができます。
例えばLambdaのロググループであれば、以下のクエリで実行回数や実行時間、コールドスタートの回数をまとめて確認できます。

実行状況集計
SOURCE logGroups(namePrefix: ["ロググループ名"], class: "STANDARD") START=<集計開始点> END=<集計終了点> |
filter @type = 'REPORT'
| stats count(*) as invocations, avg(@duration) as avg_ms, max(@duration) as max_ms, max(@maxMemoryUsed/1000/1000) as max_mem_mb, count(@initDuration) as cold_starts

REPORTの行に書かれていたDurationやMax Memory Usedが、数値のフィールドとして取り出せるので、平均や最大値をそのまま計算できます。

エラーの発生状況を見たい場合は、メッセージに対する検索が使えます。

エラー件数
filter @message like /ERROR/ | stats count(*) as errors by bin(1d)

AIにクエリの記述を依頼することもできるので、慣れない間は頼った方が良さそうです。
image.png

保持期間とログの置き場所

最後に、ログを溜めていく上で気を付けたい点を2つ。

保持期間はデフォルトで無期限
ロググループの保持期間は、何も設定しなければ無期限。(1日〜10年の範囲で設定可能)
取り込みの料金は1回きりですが、保管の料金はログを消すまでかかり続けるので、必要な期間を決めて設定しておくのが良さそうです。

あまり見ないログには別の置き場所もある

  • ロググループのクラスをInfrequent Accessにすると、取り込みの料金が安くなりますが、使える機能が絞られる点に注意。(Logs Insightsでの検索は可能。メトリクスフィルターやLive Tailが使えない)
    ⇒ 普段は見ないけどトラブル時には検索したいようなログ向き?(クラスはロググループを作成すると変更できない点に注意)
  • VPCフローログなど一部のログは、CloudWatch Logsではなく、S3などを送信先に選ぶこともできます。コストは低くなりますが、CloudWatch Logsの機能では扱えなくなり、分析にはAmazon Athenaなど別の仕組みが必要になります。

まとめ

CloudWatch Logsの仕組みと、代表的なサービスのログ、CloudWatch Logsでできることを整理しました。

  • ログはロググループ(設定単位) → ログストリーム(実行環境) → ログイベント(生のログデータ)の階層構造を持つ
  • ログイベントの中身は時刻とテキストだけ、ログ形式は出力するサービスごとで変わる
  • LambdaはREPORTの行、VPC Flow Logsはactionを見れば、実行状況や通信の許可/拒否が分かる
  • Lambda以外の多くのログは、サービス側で有効化しないとCloudWatch Logsに出力されない
  • Logs Insightsを使えば、LambdaやJSON形式のログをフィールド名で検索・集計できる
  • 保持期間はデフォルトで無期限なので、ロググループごとに設定しておく
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?