CloudWatchでメトリクスフィルタの設定でちょこっとだけ苦戦した

皆さん、CloudWatch使ってますか!?
という、どこかで見たようなことがあることを自分も言ってみたくなったごきげんまるです。

今日はCloudWatchのメトリクスフィルタの設定です。

メトリクスフィルタとは何ぞやというのは、ほかの方々にお任せをします。
まぁ、何が出来るかというと、LambdaやECSのログはCloudWatchに出力されますが、そのログの一部(パターン)にマッチしたものをメトリックスにしてグラフで見たり出来るようになります。
監視ツールを入れると、ログ全部を監視ツールに送って、そちら側で絞りこみ等をするかと思いますが、例えば監視ツールを使わずに簡単な監視をさせるとかであればメトリクスフィルタは1つの対応方法になるかと思います。

例えば、メトリクスフィルタでERRORをフィルタし、その結果をSQSに送ってメールで受け取るとか。。。

自分がいる国とは別のリージョンのAWS環境を使っているが、その国の法律でデータの持ち出しが制限されているとか。。。

会社のルールでデータをAWS外に出すことが極端に制限されているので、エラーが出たことだけを通知して実際の内容はAWSにログインして確認しないといけないとか。。。

そんなときに使われる?


ということで、CloudWatchでメトリクスフィルタの設定の仕方です。

CloudWatchでメトリクスフィルタ設定

AWSのマネジメントコンソールからCloudWatchを選びます。

CloudWatchの画面から、「ログ」を選びます。
※ここでメトリクスは選ばないように!

f:id:gokigenmaru:20190708140823p:plain

メトリクスるフィルタを設定したいログを選択してから「メトリクスフィルタの作成」を選びます。

f:id:gokigenmaru:20190708141034p:plain

この画面でフィルタをする文字列を設定します。

f:id:gokigenmaru:20190708141237p:plain

フィルタパターンのところで、ログに対してどのようなフィルタをするかを設定できます。
ログ内でERRORをフィルタしたい場合は、フィルタパターンに"ERROR"を記載すればOK!

フィルタパターンの記載方法は、「例の表示」という箇所をクリックすると、よく使われるフィルタの記載方法が出てきます。
めっちゃ便利やーーん!

f:id:gokigenmaru:20190708141517p:plain

さらに、説明文中の「パターン構文の詳細を確認してください。」や「メトリクスフィルタ構文と例については、CloudWatch ログのヘルプを参照してください。」をクリックするとAWSのサイトに飛んで、詳細な設定方法が見れます。
docs.aws.amazon.com

いやぁ、便利っすね。さすがAWSです。
これを見ながらやればできちゃいます!

設定するフィルタパターンを入力したら、メトリクスの割り当てを選んで、次の画面に。
メトリクス名を決めて入力したらフィルタの作成を選択。これでメトリクスフィルタの作成は完了。簡単でしょ!?

f:id:gokigenmaru:20190708142249p:plain


で、今回自分はJAVAのプログラムで書かれたアプリケーションのログをフィルタすることになっていました。
先方からの要望は、
JAVAで作成したアプリケーションが出力するloglovelのエラーとワーニングをフィルタしてほしい。」

実際に、どのようにログが出てるかを見てみると、JSON形式で出力されていました。
ログにはJSON(1行で出力される)と、なぜかJSON形式の後に適当なメッセージが出ている。
あれ、JSON形式+1ですか?
ログは以下のような感じで出力される。

{"timestamp": "2019-07-07T06:25:19.420Z","log_level": "ERROR","loggername": "ApplicationExceptionHandler.handleCommonException","message": "AABBCCDDEEFFGG"} nazekahitokoto

先ほど紹介したAWSのサイトには、「JSON ログイベントから値を取得するメトリクスフィルターの使用」という項があり、この通りやればJSON形式のログのフィルタは簡単に出来そう。

{ $.log_level = "ERROR" }

というわけで試してみることに。
ちなみにですが、以下のように枠の中にテストしたいログを書いて、フィルタパターンにフィルタしたい文字列を記載して「パターンのテスト」をおすとフィルタが出来るかどうか試せます。
AW便利やーん(2回目
f:id:gokigenmaru:20190708143413p:plain

やってみたらフィルタ失敗…。なんでだ…。

f:id:gokigenmaru:20190708143706p:plain

お察しの方もいると思いますが、このログ、さっき言った通り、JSON+1なんです。。。
JSONに余計なものがついているせいで、JSON形式と認められず、結果、「JSON ログイベントから値を取得するメトリクスフィルターの使用」の通りにはいかない。。。

じゃあ、フィルタパターンにログで出るそのままの文字列、"log_level": "ERROR"を入れてみるが、失敗。。。
ダブルコーテーションで囲われている中身を文字列として認識するっぽいですね。まぁ、よくある当たり前の話か。。。

さて困った。。。
どうすればログをフィルタ出来るかもう一度さっきのAWSのサイトを隈なく読んでみる。
が、方法は出ていない。。。

ということで、どうすればフィルタ出来るか考えて…考えて…はっと思いつく。

「ダブルコーテーションをエスケープすればいいんでね?」

ということでやってみる。

フィルタパターンに「"\"log_level\": \"ERROR\""」を記載してテスト。
結果うまくいきました。

今回はERRORとWARNINGをフィルタしたいので、フィルタパターンの設定は以下の通りに。
「?"\"log_level\": \"ERROR\"" ?"\"log_level\": \"WARNING\""」

これでERRORとWARNINGのフィルタが出来ました。
めでたしめでたし。

ってか、JSON+1のログってなんすか???w


じゃあどうやってグラフとかを見てみるかというと、
CloudWatchの画面から、メトリクスを選んで

f:id:gokigenmaru:20190708145001p:plain


カスタム名前空間のLogMetricsを選んで、グラフを見たい対象のメトリクス名にチェックを入れると見れます。
※大人の事情で画面は無いです。


ということで、最後は端折りまくってメトリクスフィルタのお話でした。






教訓:ログはJSONならJSONで出してください。。。