CloudWatch Logsでの特定文字列の検知時の通知をメトリクスフィルターで実装してみた

2021.12.26

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部 IoT事業部の若槻です。

今回は、Amazon CloudWatch Logsでの特定文字列の検知時の通知をメトリクスフィルターで実装してみました。

メトリクスフィルターとは

CloudWatch Logsのロググループに対してメトリクスフィルターを作成することにより、ログデータの語句やパターンをフィルターしてメトリクスを発行することができます。

これにより、例えばLambda関数で特定のエラーでは特定の文言をログに書き込むという実装をしている場合に、エラーによって通知のフィルターや通知先の振り分けができるようになります。

やってみた

マネジメントコンソールから作成を行ってみます。

下記のような構成のうちメトリクスフィルターとCloudWatch Alarmアラームを作成します。

検知対象の用意

次のような特定の文字列をログに書き込むLambda関数testFuncがあります。こちらを検知対象にしてみます。

index.js

exports.handler = (event) => {
    if (event.key === undefined){
        console.log('Error キーが存在しません!');
    }
    return;
};

メトリクスフィルターの作成

まずCloudWatch Logsのコンソール(CloudWatch > Log groups)で上記のLambda関数のロググループを開きます。(この時、ロググループが見つからない場合は手動作成するか1回以上関数を実行している必要があります。)

右上の[アクション]で[メトリクスフィルターを作成]をクリックします。

メトリックフィルターの作成画面が開きます。

まず[フィルターパターン]で検知したい文字列を指定します。今回はキーが存在しませんとします。

[パターンをテスト]ではすでにあるログデータでフィルターのテストができます。すでに該当のパターンを発生させているログストリームがある場合は、選択して[パターンをテスト]をクリックします。

パターンが検知できています。[Next]をクリックします。

[メトリクスの割り当て]では、まずフィルター名を指定します。

[メトリクスの詳細]では、発行されるメトリクスの詳細を指定できます。(ただしコンソールではディメンションを指定できないようです)[Next]をクリックします。

作成内容を確認して、[メトリクスフィルターの作成]をクリックします。

メトリクスフィルターが作成できました。[Metric]のリンクをクリックします。

[testFuncNS > ディメンションなしのメトリクス > keyNotExist]でメトリクスフィルターの発行したメトリクスがグラフで確認できます。(この時、メトリクスがまだ1つも発行されていない場合はメトリクスフィルターのパターンに合致するLambda実行を1回以上行う必要があります)

アラームの作成

[すべてのアラーム]で[アラームの作成]をクリックします。

先程のメトリクスを指定します。

アラーム条件を指定します。今回は1分間に特定文字列が1回でもCloudWatch Logsに書き込まれることを条件とします。[次へ]をクリックします。

通知先のSNSトピックを指定します。[次へ]をクリックします。

アラーム名を指定して[次へ]をクリックします。

[プレビューと作成]で作成内容を確認したら[アラームの作成]をクリックします。

作成できました。

動作

特定文字列(キーが存在しません)がLogに書き込まれるようにLambda関数を実行します。

メトリクスフィルターがメトリクスを発行しました。

SNSトピックをサブスクライブするメールアドレスに通知が届きました!

どのLambda関数で何時頃ログが検知されたかが分かるようになっていますね。

備考

作成はCLIやIaSでした方が良さそう

今回メトリクスフィルターとアラームをマネジメントコンソールから作成しましたが、その際にディメンションが指定できなかったり、メトリクスを手動で発行してアラームの指定対象にできるようにする必要があったりしました。 このようにマネジメントコンソールからの作成だと不便があるので、実際の利用ではCLIやIaSから作成を行ったほうが良さそうです。

ある程度の柔軟な文字列検知も可能

今回は特定の1つの文字列に一致した場合にのみ検知するパターンマッチングとしましたが、実際にはもっと柔軟な文字列検知も可能です。例えばORパターンマッチングを使用すれば「複数の文字列のうちどれか一つに一致すれば検知する」仕組みを一つのメトリクスフィルターで実装可能です。

かつては複数の文字列検知は出来なかったようですが、その後のアップデートで可能となったようです。

このORパターンマッチングなどの深堀りはまたの機会に行いたいと思います。

サブスクリプションフィルターとの使い分け

同じくCloudWatch Logsでの文字列検知を行う機能としてサブスクリプションフィルターがあります。

サブスクリプションフィルターはメトリクスを発行せずに、検知したログをLambda関数やKinesis Data Streamなどに直接連携することができます。これによりメトリクスを介しているメトリクスフィルターとは違って、サブスクリプションフィルターはログの内容の連携が可能となっています。よってメールなどの通知にログ内容を含めたり、また通知内容を自由に成形できるため、アラート対応の効率化が期待できます。

なので使い分けとしては、アラート運用を簡易的に行いたい場合はメトリクスフィルター、ある程度しっかりと行いたい場合はサブスクリプションフィルター、という感じでしょうか。

以上