こんばんわhorikiです。
業務上AWSのCloudWatch Logsのログのインサイトを使って、ログの検索、集計を行なっているのですが、ずっと気になっていることがありました。
それがこちら。
そう、parseですね。
クエリによって処理される 1 つまたは複数のエフェメラルフィールドを作成します。
うーん、何言ってるかわからないですね。
とはいえ、使ってみると便利な機能でしたので、使い方をまとめておきたいと思います。
parse部分の説明
まずはエフェメラルフィールドってなに?ということで調べました。
エフェメラル:つかの間の、一時的な、刹那の、はかない
とのこと。つまり、一時的なフィールドのようです。
肝心のクエリ部分ですが
parse '* - * [*] "* * *" * *' as host, identity, dateTimeString, httpVerb, url, protocol, statusCode, bytes
となっています。
これだけだとわかりづらいですね・・・、なので元のログを一時フィールドから再現してみます。
アスタリスクをas以降のフィールドに置き換えるので、
'host - identity [dateTimeString] "httpVerb url protocol" statusCode bytes'
になります。つまり、Parseの対象となるログは以下のような形であると推測できます。
'128.xxx.xxx.xxx - - [14/Dec/2023:10:40:57 +9000] "GET http:// www.hogehoge HTTP" 200 45'
ですので、ログを一定のフォーマットに従って分解し、要素をフィールドとして切り出せるクエリのようです。
実際の利用例
私が実際に利用した例としては以下のものがあります。
parse endpoint '*?' as endpointbase
例えば、/my/hogehogeというendpointがあるとして、このendpointが何回呼ばれたのか集計しようとしています。
ログのフィールドとしてはそのままendpointというフィールドとして出力しています。
このendpointがidというクエリパラメータを受け付ける場合、
/my/hogehoge?id={ids}
となり、単純にendpointだけで集計してしまうと、idごとに集計することになってしまいます。
このとき
parse endpoint '*?' as endpointbase
を使うと、?より前の値をendpointbaseというフィールドとして抜き出すことができ、/my/hogehoge毎に集計ができるようになります。
名前付きキャプチャグループの利用
parseには名前付きキャプチャグループを利用するという方法があります。
例えば、
/my/hogehoge/{id}
と
/my/hogehoge/fugafuga
というエンドポイントが二つあるとします。
この時{id}ごとに集計しようとして
parse endpoint "/my/hogehoge/*"
と指定してしまうと、fugafugaも集計されてしまいます。
ここで名前付きキャプチャグループを利用します。
名前付きキャプチャグループは(?<Name>pattern)で構成されており、<Name>には一時フィールド名、patternには正規表現が入ります。
名前付きキャプチャグループを利用すると、
parse endpoint /my\/hogehoge/(?<id>[0-9]+)/
というように書けます。
(?<id>[0-9]+)の部分が名前付きキャプチャグループとなり、正規表現(ここでは数値)に一致する{id}部分をidという一時フィールドとして抜き出しています。
正規表現に一致しないendpointは一時フィールドから省かれるためidのもののみ集計できるわけですね。
多少トリッキーになりますが、以下のようにすればidごとではない/my/hogehoge/{id}の集計も可能です。
fields @timestamp, endpoint
| parse endpoint /my\/(?<path_hogehoge>hogehoge)\/(?<id>[0-9]+)/
| filter ispresent(id) and ispresent(path_hogehoge)
| stats count(*) as total_requests by bin(1d), path_hogehoge
※filterのispresentにて値のあるもののみ集計対象としています。
※引用符を使うと正規表現が利用できないため注意が必要です。
まとめ
使いこなせれば非常に強力なクエリになりますね。
また、複雑なparseを書かなくてもいいようにログのフォーマットは整えておいた方がいいですね。