1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【AWS】CloudWatchLogsサブスクリプションフィルタ+Lambdaによるログデータの確認

Last updated at Posted at 2023-11-20

目次

  1. はじめに
  2. CloudWatchLogsサブスクリプションフィルタとは
  3. Lambdaでパラメータを受け取る
  4. 改善してほしいところ

はじめに

WindowsServer内でバッチファイルを実行し、その処理結果(ログ)に基づいて成功・失敗通知を行いたかったのですが、Lambda呼び出しのとこでいきなり躓いたので備忘録としてまとめました。

(EventBridge+Lambdaの構成と同じようにLambdaハンドラーのEventから取り出せばいいだろうと思っていたらちょっと違った...)

CloudWatchLogsサブスクリプションフィルタとは

CloudWatchLogsに指定した文字列が記録されたら特定のアクションを実行させるようなトリガーを設定できる機能です。
サブスクリプションフィルタはロググループごとに作成出来ますが、ログストリームごとには設定できないようなので注意してください。

サブスクリプションフィルタでトリガー可能なアクションは以下の4つです。

  • OpenSerch Serviceサブスクリプションフィルタ
  • Kinesis サブスクリプションフィルタ
  • Kinesis Firehoseサブスクリプションフィルタ
  • Lambdaサブスクリプションフィルタ

Lambdaでパラメータを受け取る

早速ですが、Lambda関数を作成していきます。
サブスクリプションフィルタにLambdaを指定することで、
CloudWatchLogに書き込まれたログがLambdaにパラメータとして渡されます。

以下の文字列に対してサブスクリプションフィルタを設定したとします。

  • 検知する文字列:end_time

ログファイルに「end_time」が書き込まれるとサブスクリプションフィルタによってLambdaが呼び出されます。
Lambdaハンドラーの引数:eventに上記ログが渡されるのですが、Lambdaでeventの中身を出力してみると以下のようになってます。

Create-CloudwatchAlarm-List.sh
{'awslogs': {'data': 'H4sIAAAAAAAA/zWQPU7DMBhAr1J9c6La/uL4R2KIoHRiaiUGVFVp4gZLSRzFLlWpunRADFyACXEBNha4DgWOgQpif+8NbwuN8T6vzHTTGdBwlk2z+cVoMsnGI4jArVvTgwbKkWHCKAqZQgS1q8a9W3WgYZg1+a1rT2u3Ki/zUFzHtat8MD7Ea9uWbu2Htati19abP3ESepM3oMHGpJDLHPkSmVwopbCECPxq4YvedsG69tzWwfQe9BUcXp6+nx++Xvcfb3efj/vD/TvMfnOjG9OGI7IFW4IGFIpiigQJESlLKeVKCEppolgqqRRcMcmQUWSEk1RIqmSCXCYQQbCN8SFvOtBUEEIJV5Iil9H/I9Bg2nJ+5AYnA0I0StjNdj81GMMwRAEAAA=='}}

このメッセージをどんなログが書き込まれたのか判断できません。
実はこのデータはデコードすることで正しいデータを取り出せます

以下のコードで中身を取り出せます
データの中身は「end_time = 00:38」というログメッセージです

decode.py
import json
import base64
import gzip

#サブスクリプションフィルタで検知した文字列を取得
def decode_function(event):
    decoded_message = base64.b64decode(event['awslogs']['data'])
    decompressed_data = gzip.decompress(decoded_message)
    json_data = json.loads(decompressed_data)
    log_message = json_data['logEvents'][0]['message']
    
    return log_message
    
def lambda_handler(event, context):
    print(event)
    log_message = decode_function(event)
    print("log_messageを取得しました:{}".format(log_message))

実行してみるとこんな感じです。
image.png

これでサブスクリプションフィルタから受け取ったデータの中身を確認できるようになりました。
あとはこのメッセージを基に、SNS通知したり別のLambdaを呼び出したり,etc...作りこめばOKです。

改善してほしい点

EventBridgeとの大きな違いとしてイベント検知後にSNSが指定できない点があるかと思います。実際私もサブスクリプションフィルタで検知→SNS通知という処理をやりたかったのですが、上記4つのアクションしか指定できないため、仕方なくLambdaを間に挟みました。
多くの人が不便に感じてるポイントな気がするのでそのうちアップデートが入ってくれる日を心待ちしています...w

さいごに

EventBridgeトリガーの感覚でデータの中身を取り出そうとすると躓くポイントになるかも。。。と思い書きました。

社内ブログのほうではCloudWatchAgentのインストールからCloudWatchLogへのログ出力設定、サブスクリプションフィルタ作成、LambdaによるSNS通知までを一気に紹介しようと思っていますので気になる方は読んでいただけると嬉しいです。

今回は以上になります。
最後まで読んでいただきありがとうございました!

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?