CloudWatchのログで特定の文字列が出たらLambdaを起動させる
CloudWatchのサブスクリプションフィルターという機能を使うことで、例えばECSでバッチ処理を行っていて、開始,終了やエラーをCloudWatchログに出してそれらをLambda経由でSlackへ通知することができます。
Lambda作成
あらかじめLambdaを作成しておく必要があります。
後にCloudWatchサブスクリプションフィルターを作成する時にどのLmanda関数を使うか選択する画面があるので。
Lambdaが起動されたか確認するために、
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/SubscriptionFilters.html にあるように以下のようにindex.jsを実装します。
console.log
の部分がCloudWatchログへ出力されます。
input
にはClouWatchサブスクリプションフィルターから送られてくるデータが入っています。
// index.js
var zlib = require('zlib');
exports.handler = function(input, context) {
var payload = Buffer.from(input.awslogs.data, 'base64');
zlib.gunzip(payload, function(e, result) {
if (e) {
context.fail(e);
} else {
result = JSON.parse(result.toString('ascii'));
console.log("Event Data:", JSON.stringify(result, null, 2));
context.succeed();
}
});
};
サブスクリプションフィルター
ログの検知を行いたいCloudWatchログでサブスクリプションフィルターを作成します。
先ほど作成したLambdaを選択。
パターンは
を参考に
?start ?end
とします。
(日本語や一部記号は使えませんでした)
これでstart
もしくはend
の文字列が含まれるログが出力されるとLambdaが起動します。
動作確認
実際にECSのタスクを起動->CloudWatchへのログ出力->サブスクリプションフィルターでLamnda起動->LambdaのCloudWatchログをみて起動を確認
ECSタスク定義にてコマンドをecho start
とし、タスクが実行されるとstart
という文字が出力されるようにしておきます。
タスクを実行してみるとstart
がCloudWatchログへ出力。
このログをサブスクリプションで拾ってLambdaが実行されているはず。
Lambdaのログをみてみると、実行されていることが確認できました。
Lambdaが受け取れるパラメータは以下のようになっています。
{
"messageType": "DATA_MESSAGE",
"owner": "hogehogehoge",
"logGroup": "/ecs/embulk",
"logStream": "ecs/embulk/0cd3f8e4a13840c396f45fa9b7ff90c9",
"subscriptionFilters": [
"embulk-test-filter-name"
],
"logEvents": [
{
"id": "36048248338279890932333964403104620581013505171129171968",
"timestamp": 1616459361217,
"message": "start"
}
]
}
どのログで検知したのか、検知したログの内容などが取得できます。
あとは、Lambdaに行いたい処理を書けば、例えばslackへ通知したりSNSでメールを送信したりすることができます。
Discussion
Slack への投稿であれば AWS Chatbot が便利ですよ
ありがとうございます。参考にします!