【CloudWatch Logs】1つのメトリクスフィルターでORパターンマッチングと語句の除外を両立できない(が似たようなことはできる)

メトリクスフィルターにおけるフィルターパターンでORパターンマッチングとキーワード除外を両立させたい場合は、ひと工夫が必要です。挙動をきちんと抑えておきましょう。

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

コンバンハ、千葉(幸)です。

CloudWatch Logsメトリクスフィルターではフィルターパターンで様々な形式に対応することができます。

例えば複数のキーワードのORパターンマッチングや、キーワードの除外に対応しています。ただし、それらを一つのフィルターパターン構文の中で両立させることはできません。そこで試行錯誤することになったので、その結果を書きます。

2020/12/8追記 スペース区切りフィルターパターンを使用することで解消できる旨フィードバックがありましたので追記します

目次

やりたいこと

  • error」もしくは「fail」のキーワードが含まれているログイベントを検知したい
  • ただし、「hoge」ないし「fuga」が含まれているものは検知対象から除外したい
  • つまり、以下のログイベントのうち、★がついているもののみ検知したい。
log
hoge
fuga
error ★
fail ★
error log ★
fail log ★
error hoge
fail hoge
error fuga
fail fuga
error hoge fuga
fail hoge fuga

フィルターパターン構文について

1つのメトリクスフィルターにつき、1つのフィルターパターンを定義することができます。メトリクスフィルターはフィルターパターンの構文に基づきログイベントを評価し、合致する場合にはメトリクスに値を発行します。

詳細は以下に記載があります。ドキュメントの記載内容を参考にしながら実際の挙動を確認していきます。

フィルターとパターンの構文

特記事項としては以下があります。

  • メトリクスフィルターは大文字と小文字を区別する
  • アルファベット文字およびアンダースコア以外の文字を含むメトリクスフィルターの語句は二重引用符 ("") で囲む必要がある

メトリクスフィルター作成時の画面で、カスタムログデータを利用してのパターンのテストが可能なので、そちらを用いて挙動を確認します。

フィルターパターン

ORパターンマッチング

?をキーワードの先頭に付与することで、ORパターンマッチングを使用することができます。

例えば?error ?failとすれば、errorもしくはfailの文字を含むログすべてと一致することになります。

error と fail

?の後に半角スペースがあってもなくても同様の挙動になります。

除外キーワード

-をキーワードの先頭に付与することで、特定のキーワードを除外することが可能です。

例えばerror -hoge -fugaとすれば、errorを含み、かつhogeもしくはfugaを含まないログのみが一致します。

errorからhogeとfuga除外

こちらも、-の後に半角スペースがあってもなくても同様の挙動となります。

ORパターンマッチングと除外キーワードの組み合わせ

?error ?fail -hoge -fugaとすればやりたいことができるのでは、と当初が考えていましたが、想定通りの挙動になりません。

ORと除外の組み合わせ

これは、-hoge -fugaのみを指定している場合と同一のマッチングパターンとなります。

どうやら?を使用できるのは、各キーワードに?が付与されている場合のみのようです。試しに?つきのキーワードとなしのキーワードを組み合わせて?error failで確認すると、前方の?errorが無視されていることがわかります。

failのみ

ならばと思いこんなものも試してみましたが、構文エラーに終わりました。

?error ?fail ?-hoge ?-fuga

ではどうするか

一つのフィルターパターンでは要件を満たせないことがわかったので、複数のフィルターパターンを組み合わせて対応します。

  • error -hoge -fuga
  • fail -hoge -fuga

上記のようなフィルターパターンを持つメトリクスフィルターを2つに分けて作成し、同一のメトリクスに対して値を発行するように設定すれば、やりたいことを満たすことができます。

このくらいの規模なら、問題なく要件を満たすことができます。

追記:スペース区切りフィルターパターンを使用する

社内でフィードバックを受け、以下のような書式を教えてもらいました。

[( a="*error*" || a="*fail*" ) && ( a!="*hoge*" && a!="*fuga*" )]

ここでのaは任意の文字で大丈夫です。msgなどにしても問題ありません。

これはここに記載のパターンを使用したものです。

本来はスペースで区切られたフィールドごとに任意の名前を付けていくものですが、ここではログイベントを一つのフィールドからなるものとして扱っています。

テストを行うと、意図した通りの結果が得られました。

すごいですね。ドキュメントを見ても思いつきもしませんでした。

終わりに

フィルターパターンの構文について確認しました。 30分くらい試行錯誤して答えにたどり着いたので、同じことを疑問に思った方の30分を節約できれば何よりです。

メトリクスフィルターが増えるということは管理するリソースが増えるということなので、なるべく避けたいところです。 ORパターンマッチングさせたいキーワード、除外するキーワードが増えるとその分組み合わせのパターンも増えるので、管理が大変になっていきます。そのあたりを考慮してキーワードを選定する必要があります。

追記したパターンを使用すればメトリクスフィルターも節約できますね。

以上、花粉症気味の千葉(幸)がお届けしました。