re:Invent 2023で追加された、CloudWatch Logsの自動パターン分析と異常検出がとても良い

本記事 `Cocone Advent Calendar 2023` 2日目の記事となります。

[1日目のCTO](https://qiita.com/kura_shuichi/items/89999d0041fc8aaebf06)よりバトンを受け取り、記事を書かせていただきます。

日頃はエンジニアリングマネージャー / チーム長をしておりコードを書いたり技術を適用する機会も限られておりますが、私はバックエンドエンジニアの魂を持っております。
バックエンドエンジニアの最近の話題といえば、、、あれしかありません。

そう、AWS re:Invent 2023 の時期です。


# 記事の内容
日本から新機能を眺めていると、今年も気になる機能がありました。
CloudWatch Logsに新たについた、自動パターン分析と異常検出機能です。

こちらを実際の運用ログで試してみました。


## 参考資料
既存の機能にも異常検出という概念がありややこしいのですが、ドキュメントは以下となります。

News Blog
https://aws.amazon.com/jp/blogs/aws/amazon-cloudwatch-logs-now-offers-automated-pattern-analytics-and-anomaly-detection/

Document
https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/LogsAnomalyDetection.html


# 使い方

## 自動パターン分析
まずは、どのロググループを、どのように見れば良いのか？ということで、パターン分析を行います。CloudWatchのメニューより「ログのインサイト」へ向かいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2981892/1fe2b426-521e-2c30-160c-f44633746e5c.png)

## ロググループの選択
普段一番よく見るアプリケーションサーバーのログみたいなものを誰しもお持ちだと思います。
選びましょう。

## クエリの実行
[このあたり](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/CWL_QuerySyntax-Filter.html) を参考に、クエリを書いてみます。例えば 具体的なRPC名 を含むログにクエリを実行し、パターン分析をする場合は以下のような書き方になります(RPC名は伏せます)。

※後述のトークンによってある程度ログはまとまりますが、意図せずパターンが増大することを考えると、検証ということもあり対象のログ期間は、適当に今回は12時間分を選択しています。

### シンプルな性質のRPCの場合
```
fields @timestamp, @message, @logStream, @log
| filter message like "(問題があまり起きない性質のRPC名)"
| sort @timestamp desc
| pattern @message
```

すると、以下のように３パターンに分かれました。共通部分は「トークン」と呼ばれ `<*>` で表現されています。内容を見ていくと、以下の3つに分類されました。
- 通常っぽいパターン
- 「INFOで扱っているがエラーとして判断されているもの」
- 「なにかまずそうなエラーが出ているもの」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2981892/49186f7b-5011-3df2-ccf3-e29213d64817.png)


正直、これだけでもすごいですね...

具体的なRPC名で絞っていて、かつシンプルな機能なので３パターンですが、ここの filter によっては当然パターン数は無数になります。ドキュメントによると、このパターン数が３００以下くらいだと異常検出がうまく機能する可能性があるそうです。


### 複雑性があるRPCの場合
```
fields @timestamp, @message, @logStream, @log
| filter message like "(ガチャを引くようなRPC)"
| sort @timestamp desc
| pattern @message
```

ガチャを引くようなRPCの結果を見てみます。
マスキングしまくってすみません。想定通りのパターンが多いのですが、とても特徴的だったのが、12件も「ガチャを引くコイン的なものが足りないのに実行をしている」というログがあった点です（下から3つ目）。

これは気になります。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2981892/612536e2-9e2a-1797-6952-f9ef1e0ff08d.png)

気になったものは、画面のInspectの列の虫眼鏡マークをクリックします。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2981892/882c78d3-c584-e152-73cd-28e46ac288f3.png)

すると、具体的に、トークン部分を一覧で見ることができます。
このログはトークン1が時刻、トークン2が実行した人のIDなのですが、一番下のトークン2のイベント数が6つもあることが分かります。トークン1の時刻を見ると、6つ短時間に実行していそうです。

これだけで断定することはできませんが、一般的に不正なアクセスである可能性はあるかと思います。


...という、こうしたログを異常検知できるってことですよね。これはすごい。
ちなみにドキュメントには長いJSONは向かないとありますが、最初の1500文字のみ分析とあるので、通常のアプリケーションログとしてのJSONであれば問題なく分析できております。


# 異常検出の設定方法
さて、ではこれを実際に異常検出として設定してみましょう。

「ログ」メニューより「異常をログ記録」というところから設定が可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2981892/e17c70ea-b80a-6889-33ae-ee49f56f7866.png)

こんな画面での設定となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2981892/8c28b8a6-26b9-e32e-ccd6-77208f9d372f.png)

パターンをフィルタリング、の部分で、先ほどのパターン分析で書いたようなフィルタをかけることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2981892/b7a1a26a-c029-d2d7-02fb-9b1f0b7a6bc1.png)


上記の画面には、ロググループの一覧からも遷移が可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2981892/90f90431-f6b7-7f25-c654-cee0e70d92cf.png)


## 設定してみた
※検証の都合により、機能を試すために、上記のパターン分析とは異なる広めの設定で試しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2981892/19e1efff-3d69-a69e-da32-e0fbf24d9e5f.png)

こんな感じで、検知した異常が設定した日数分残るようです。
ラジオボタンをクリックすると、先ほどのパターン分析と類似のUIで、パターン検査も見られます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2981892/49f1e521-d54c-63b5-9cdb-34c779cdf02b.png)

マスキングしまくっていますが、フィルターしたログに該当するRPCのうちアクセストークンエラーを踏みやすいRPCが一覧化されています。
なお自前にseverityという文字が出ているのでややこしいのですが、ログの中にErrorと含まれると異常検出としてはERRORとして扱ってくれます。




# 使い道などの考察
- もちろん既存機能でもERROR自体はアラートできますが、運用して時間が経つサービスの分析に非常に適していそうです。
- 思いつきで色々な機能のログを見ているだけでも、まさに異常検知にもつながりそうです
- ありそうで無かったUIが見やすいです。
- パターン分析の時点で非常に面白く、ブログにも使用例としてあるように、新機能のリリース時のエラーチェックなどに非常に適しているように思えます。


# 気になった点
- 調べきれていないだけの可能性もありますが、異常検知について、すでに選択されたロググループは再度選択できなくなっており、これを「パターンをフィルタリング」ごとに「異常ディテクター」が作れると良いなと感じ、パターン分析の方と、そこがやや齟齬あるように感じます。何か方法があるかも？


# 感想
「ログのパターンを分析する」というのは、思い付いたり、方法論自体は分かっても、ビッグデータ集計の分野となり、難易度が高い話だと思っています。それが画面操作1つでAWSの集計パワーを使って、定常的に高速に分析できるのが非常に良いと思いました。
気になった点、の課題を解消できれば、実際に本気で運用したい機能と出会えて幸せな気持ちです。




明日は @cocongo さんによる、M5Stackを使った記事となります！明日もぜひご覧下さい。