Amazon CloudWatch で、ログクエリをもとに直接アラームを作成できるようになりました。
従来は CloudWatch Logs の内容を監視したい場合、メトリクスフィルターを作成し、そのメトリクスに対して CloudWatch Alarm を作成する、という流れが一般的でした。
今回のアップデートにより、CloudWatch Logs Insights のクエリ結果に対して、そのまましきい値を設定してアラーム化できるようになっています。
概要
今回追加されたのは、CloudWatch Logs のクエリ結果を直接評価する Log Alarm という仕組みです。
ざっくり言うと、以下のようなことができます。
- CloudWatch Logs Insights のクエリを書く
- クエリ結果を
count(*)やavg(duration)などで集計する - 集計結果にしきい値を設定する
- しきい値を超えたら SNS 通知などのアクションを実行する
従来も、CloudWatch Logs の内容をもとにアラームを作ることはできました。
ただしその場合は、まずメトリクスフィルターを作成し、ログイベントを CloudWatch Metrics に変換する必要がありました。
今回の Log Alarm では、この中間ステップを挟まずに、CloudWatch Logs Insights のクエリ結果を直接アラーム条件として扱えます。
何が新しいのか
個人的には、今回のアップデートのポイントは単に「メトリクスフィルター作成の手間が減った」ことだけではないと思っています。
より大きいのは、CloudWatch Logs Insights のクエリ表現力を使ってログを抽出・加工・集計し、その結果を直接アラーム評価できるようになった点です。
メトリクスフィルターは便利ですが、基本的にはログイベントに対するパターンマッチや、特定フィールドの抽出をもとにメトリクス化する仕組みです。
一方、CloudWatch Logs Insights では、fields、filter、parse、stats などを組み合わせて、より柔軟にログを分析できます。
例えば以下のように、ログメッセージからステータスコードやレイテンシを取り出し、条件に合うログだけを対象にできます。
fields @timestamp, @message
| parse @message "status=* latency=*ms" as status, latency
| filter status like /^5/
| filter latency > 1000
このようなクエリで対象ログを絞り込んだうえで、
count(*)
のように集計し、その件数に対してしきい値を設定できます。
つまり、これまでログ調査で使っていた Logs Insights のクエリを、監視条件としてかなり使いやすくなった、という理解です。
ただし、アラームとして評価するためには、最終的に count(*)、avg(field)、sum(field) などの数値に集約できる形にする必要があります。
Log Alarm の動作イメージ
Log Alarm は、指定したスケジュールに従って Logs Insights のクエリを実行し、その結果を集計してしきい値と比較します。
しきい値を超えた場合は、通常の CloudWatch Alarm と同じように SNS 通知などのアクションを実行できます。
コンソールから作成してみる
今回は CloudWatch コンソールから Log Alarm を作成してみます。(CLIでやろうとしたのですが、まだコマンドが入っていないようでした)
CloudWatch のアラーム作成画面で、データソースとして Logs を選択します。
次に、Log Analytics で Logs Insights クエリを作成します。
今回は テスト用のロググループを対象に、ERROR を含むログを数える例にします。
集約の方式と閾値等を設定します。
スケジュールでは、クエリの実行間隔と、各クエリで参照するログの時間範囲を指定します。
例えば、10分に1回クエリを実行し、各実行で直近10分間のログを対象にする、といった設定ができます。
最後に、通常の CloudWatch Alarm と同じようにしきい値と通知先を設定します。(画像は省略)
ロググループに適当なレコードを追加して動作を確認できました。
SNS 通知にログ行を含められる
Log Alarm では、SNS メール通知にクエリ結果のログ行を含めることもできるようです。
従来のメトリクスアラームでは、通知に含まれるのはアラーム名、状態変化、しきい値、評価されたデータポイントなどが中心でした。
今回の Log Alarm では、ActionLogLineCount を指定することで、アラーム判定に関連するログ行を通知に含められます。
通知を受け取った時点で原因となったログの一部を確認できるため、初動調査はしやすくなりそうです。
一方で、ログ内に個人情報や認証情報などが含まれる場合、それらが SNS メール通知に載る可能性があります。そのため、本番環境で有効化する場合は、通知先やログ内容を確認したうえで使うのがよさそうです。
権限まわり
Log Alarm では、CloudWatch Logs が Logs Insights クエリをスケジュール実行するための IAM ロールが必要です。
このロールは logs.amazonaws.com から AssumeRole され、対象ロググループに対して logs:StartQuery、logs:StopQuery、logs:GetQueryResults、logs:DescribeLogGroups を許可します。
また、SNS メール通知にログ行そのものを含めたい場合は、別途 cloudwatch.amazonaws.com から AssumeRole されるロールが必要です。このロールには logs:GetQueryResults を許可します。
ログ行を通知に含める場合、ログ内の個人情報や認証情報などが SNS メッセージに含まれる可能性があるため注意が必要です。
注意点
いくつか気にしておきたい点もあります。
まず、Logs Insights のクエリを定期実行するため、対象ログ量や実行頻度によってはコストやクエリ負荷を意識する必要があります。
また、ログの取り込み遅延も考慮した方がよさそうです。スケジュール実行の対象時間を直近ぎりぎりにしすぎると、まだ取り込まれていないログを評価してしまう可能性があります。
公式ドキュメントでも、StartTimeOffset や EndTimeOffset を使って評価対象の時間範囲を調整することが説明されています。
対応リージョン
この機能は、商用 AWS リージョンで利用できます。
ただし、発表時点では以下のリージョンは対象外です。
- Middle East (UAE)
- Middle East (Bahrain)
東京リージョンでは利用可能です。
最後に
CloudWatch Logs のクエリをそのままアラームにできるようになったことで、ログ調査と監視設定の距離がかなり近くなった印象です。
直近数か月においてもCloudWatch Insightには多くの関数が追加され、より詳細な分析ができるようになっているので、それをアラームに活かせると思います。
従来のメトリクスフィルターでもログベースの監視はできましたが、今回の Log Alarm では Logs Insights のクエリを使えるため、より柔軟な条件でログを評価できます。
特に、アプリケーションログに含まれるエラー、特定の例外、レイテンシ、ステータスコードなどを監視したい場合には便利そうです。
一方で、継続的に監視するものなので、クエリの書き方、実行頻度、ログ量、通知に含める内容はきちんと設計した方がよさそうです。
まずは既存の Logs Insights クエリをベースに、軽く試してみるのがよいと思いました。
参考:







