AWS CloudWatch Logs Insights でログを調査してみよう!!
こんにちは!
株式会社TAIANでバックエンドエンジニアをしています、sekkeyです。
今回は、AWS CloudWatch Logs Insights について、簡単に紹介します!
エンジニアとしてアプリケーション開発をしていると、問い合わせやバグの調査時など、ログを遡りたい場面がよくあるかと思います。
その際、当初は CloudWatch のロググループから直接検索して調査していましたが、「 CloudWatch Logs Insight の方が調査しやすいかもよ!」というアドバイスをもらったので、少し触ってみました。
実際に使ってみると、SQL のような感じで検索できて調査しやすく、非常に便利だと感じたので、
に簡単にまとめてみました!
CloudWatch Logs Insight とは?
CloudWatch Logs Insight は、AWS CloudWatch に保存されたログに対して、クエリを投げて調査・分析できるツールです。
ロググループを横断して検索できたり、集計処理ができたりと、CloudWatch Logs よりも効率的な調査が可能です。
ただし、古いログが保持期間の制限により消えていたり、一部サービスではクエリ対象外のログもある?らしいため、あくまで CloudWatch Logs の検索と補完的に使うのがベストのようです。
ログ解析/調査の基本的な流れ
1. 調査対象のロググループを選ぶ
CloudWatch コンソールの「Logs Insights」から、調査対象のロググループを選択します。
例:aws/lambda/xxxxx
や aws/ecs/yyyyy
など。
複数のロググループを同時に選択できるため、ecs
と lambda
のログをまとめて調査することも可能です。
2. 時間範囲を設定する
画面右上の「時間範囲」セレクタから、調査したいログの時間を設定します。
- 「過去5分」「過去1時間」などのプリセットから選択
- または「カスタム」から手動で日時を指定(例: 5/1〜5/7)
3. クエリを書く
クエリエディタに以下のようなクエリを書いて、対象のログを絞り込んでいきます。
fields @timestamp, @message
| filter @message like /Error/
| sort @timestamp desc
| limit 20
よく使う構文はこの後で詳しく紹介します!
CloudWatch Logs Insight で確認できるログフィールド
CloudWatch Logs Insight では、ログを検索・分析するためにログの各項目(フィールド) を扱います。
フィールドとはざっくり言えば、「ログの中のそれぞれの値に付けられたラベル」 のようなものです。CloudWatch Logs Insight は、このフィールドを指定して絞り込み、集計、可視化などができます。
(SQL の SELECT で指定する箇所に近いと思います。)
標準フィールド
CloudWatch Logs Insight で自動的に表示される基本フィールドです。
フィールド名 | 説明 |
---|---|
@timestamp |
ログの発生時刻(明示またはログ本文から抽出) |
@message |
ログの本文そのもの |
@log |
ロググループ名(例:/aws/lambda/xxxx )※アカウントIDは含まれません |
@logStream |
ログストリーム名(例: 各ECSタスクやLambda関数ごとのログ) |
@ingestionTime |
CloudWatch に取り込まれた時刻(内部的な取り込み時間) |
さらに、各AWSサービスに応じて以下のようなフィールドが自動付与されることもあります。
ログ送信元 | 特徴的なフィールド |
---|---|
Lambda |
@requestId , @functionName など |
API Gateway |
@httpMethod , @status , @latency など |
ECS |
@entity.* , @Attributes.ECS.* など |
VPC Flow Logs |
srcAddr , dstAddr , action , protocol など |
詳細はAWS公式ドキュメントにも掲載されています。
クエリの基本構造
Logs Insight のクエリは、|
パイプでつなぐ一連のコマンドで構成されます。
ログイベントに対してフィルタ、整形、並び替え、集計などを順番に実行できます。
色々なコマンド
コマンド | 説明 | 例 |
---|---|---|
fields |
表示するフィールドを指定する | fields @timestamp, @message |
filter |
条件に一致するログを抽出 | filter @message like /error/i |
sort |
並べ替え(昇順/降順) | sort @timestamp desc |
limit |
表示件数の制限 | limit 20 |
stats |
集計関数を使ってデータを分析 | stats count() as errorCount |
parse |
パターンに基づいてフィールドを抽出 | parse 'request_id: *' as request_id |
dedup |
重複するログを削除 | dedup @message |
display |
結果の表示形式を変更 | display json |
結果の表示形式を変更します。テーブル形式やJSON形式など、見やすい形式で出力できます。
こちらも、詳細はAWS公式ドキュメントに掲載されています。
下記のクエリで大体なんでもできる
以下は、ログ本文に「xxx」と「yyy」の両方を含むログ行を、新しい順に20件まで表示するクエリです。
特定のログを見つけたいだけであれば、下記のクエリで大体特定できると思います。
fields @message
| filter @message like /xxx/ and @message like /yyy/
| sort @timestamp desc
| limit 20
Rails の API が叩かれた際の一連の流れを追ってみる
各アプリケーションや AWS リソースで、ログ出力設定が正しく行われていることが前提です。
たとえば、「ユーザが自分の情報を更新できない」という問い合わせが来たとします。
ユーザー更新APIのログを検索する
まずは、対象APIのパスと、対象ユーザーのIDを含むログを検索してみます。
fields @message
| filter @message like /\/api\/v1\/users/ # 対象のAPI
and @message like /12345/ # 対象のユーザid
| sort @timestamp desc
| limit 20
/../
は正規表現です。
そのため、パスを検索したいときは、\
でエスケープする必要があります。
ログからリクエストidを特定する
以下のようなログが見つかれば、リクエストID(例:abcdefghijk
)を抜き出します。
@message
I, [時間] INFO -- : [abcdefghijk] Started PATCH "/api/v1/users/12345" # リクエストidを取得
リクエストidで一連の処理を追跡する
リクエストIDをもとに、関連するログを時系列で追いかけます。
これにより、APIのパラメータ、実行されたSQL、非同期Jobの処理など、1リクエストに関連するすべてのログを一連で確認できます。
fields @message
| filter @message like /abcdefghijk/
| sort @timestamp asc
We are hiring!
TAIANでは、このような開発・技術・思想に向き合い、未来をつくる仲間を一人でも多く探しています。少しでも興味を持っていただいた方は弊社の紹介ページをご覧ください。
Discussion