Lambdaリアルタイムログ監視、ログレベル毎に通知先をSNSで一括管理してSlackやメールで通知したい
やりたいこと
- CloudWatch Alarmの通知先
- AWS Lambdaのログ監視の通知先
を通知レベルに応じてSNSでソースコード変更なしに柔軟に一括管理できるようにしたく実現方式を検討したメモ。
例えば、以下のように通知レベル毎に通知先を定義する。
通知レベル (SNSトピック) |
通知先 | 定義 |
---|---|---|
INFO | ・Slack #log_info | システムログ。調査時の効率化目的で普段は見ないログ。 |
WARN | ・Slack #log_warn | 異常事態の予兆を知らせる通知。障害の未然防止に繋がるアクション検討するため。 |
ERROR | ・Slack #log_error ・メール サービス運用者のML |
異常事態が明らかな重大なエラー。 |
Lambdaの実行ログはサブスクリプションフィルタでフィルターをかけて、各SNSへ通知するLambdaを噛ませて、SNSからSlack通知はLambdaのBlueprint「cloudwatch-alarm-to-slack」をCloudWatch経由以外の通知にも対応できるよう修正して対応した。
ログ監視対象のLambda
index.js
'use strict';
exports.handler = (event, context, callback) => {
// INFO通知したい時
console.log('SNS-INFO Subject-INFO Message-INFO');
// WARN通知したい時
console.log('SNS-WARN Subject-WARN Message-WARN');
// ERROR通知したい時
console.log('SNS-ERROR Subject-ERROR Message-ERROR');
callback(null);
};
'use strict';
exports.handler = (event, context, callback) => {
// INFO通知したい時
console.log('SNS-INFO Subject-INFO Message-INFO');
// WARN通知したい時
console.log('SNS-WARN Subject-WARN Message-WARN');
// ERROR通知したい時
console.log('SNS-ERROR Subject-ERROR Message-ERROR');
callback(null);
};
以下のログパターンに合致した場合に通知できるようにした。
SNS-<LEVEL> <SUBJECT> <MESSAGE>
CloudWatchLogsのサブスクリプションフィルタでSNS通知まで
サブスクリプションフィルタの設定方法
ログ監視対象のLambdaに対してCloudWatchLogsから対象ロググループに対してLambdaストリーミングを設定する。ログの形式は「AWS Lambda」を選択してサブスクリプションフィルターとして以下を登録。
[timestamp=*Z, request_id="*-*", level="SNS-*", subject, message]
フィルタとパターンの構文を参考にSNS通知時の件名(subject
)とメッセージ本文(message
)をLambdaで扱える変数として自動抽出してくれる機能を使った。
SNSへ通知するLambda
'use strict';
const zlib = require('zlib');
const aws = require('aws-sdk');
const sns = new aws.SNS({apiVersion: '2010-03-31'});
function publishToSnsTopic(topicArn, subject, message) {
sns.publish({
TopicArn: topicArn,
Subject: subject,
Message: message
}, function (err, data) {
if (err) { console.log('[Error] Failed sns published: ' + data);}
});
}
exports.handler = (event, context, callback) => {
const base64Logs = new Buffer(event['awslogs']['data'], 'base64');
zlib.gunzip(base64Logs, function(err, binary) {
var data = JSON.parse(binary.toString('utf8'));
if(!Array.isArray(data.logEvents)) { return; }
data.logEvents.forEach(function(d) {
if (d.extractedFields === undefined ) { return; }
if (d.extractedFields.level === undefined ) { return; }
var topicArn;
switch (d.extractedFields.level) {
case "SNS-INFO":
topicArn = process.env.SNS_INFO_TOPIC_ARN;
break;
case "SNS-WARN":
topicArn = process.env.SNS_WARN_TOPIC_ARN;
break;
case "SNS-ERROR":
topicArn = process.env.SNS_ERROR_TOPIC_ARN;
break;
default:
console.error('[ERROR] Level is not matched: ' + data.message);
return;
}
publishToSnsTopic(topicArn, d.extractedFields.subject, d.extractedFields.message);
});
});
};
ソースコードの変更なくSNSを変更できるようLambdaの環境変数でSNSのARNを管理できるようにした。
Lambdaのロールにはsns:Publish
のポリシー許可が必要。
SNSからSlack通知するLambda
Blueprintの「cloudwatch-alarm-to-slack」を以下のdiffのように修正。
CloudWatch経由じゃないとJSONパースエラーになるので、CloudWatchLogs経由も対応できるように修正した。
KMSとかの設定はこちらの記事を参考にした。
@@ -84,18 +84,23 @@ function postMessage(message, callback) {
}
function processEvent(event, callback) {
- const message = JSON.parse(event.Records[0].Sns.Message);
-
- const alarmName = message.AlarmName;
- //var oldState = message.OldStateValue;
- const newState = message.NewStateValue;
- const reason = message.NewStateReason;
+ const messageStr = event.Records[0].Sns.Message;
+ const subject = event.Records[0].Sns.Subject;
const slackMessage = {
channel: slackChannel,
- text: `${alarmName} state is now ${newState}: ${reason}`,
+ text: subject + "\n" + messageStr
};
+ try {
+ const message = JSON.parse(messageStr);
+ const alarmName = message.AlarmName;
+ //var oldState = message.OldStateValue;
+ const newState = message.NewStateValue;
+ const reason = message.NewStateReason;
+ slackMessage.text = `${alarmName} state is now ${newState}: ${reason}`;
+ } catch (e) {}
これで完了。
Lambdaのログ監視のSlack通知
CloudWatch AlertのSlack通知
参考
* cloudwatchlogs -> lambda -> SNSを試してみた
* AWS Lambda で CloudWatch Logs のログ本文をSlack通知(2)
Author And Source
この問題について(Lambdaリアルタイムログ監視、ログレベル毎に通知先をSNSで一括管理してSlackやメールで通知したい), 我々は、より多くの情報をここで見つけました https://qiita.com/koshilife/items/4b49bd08b92c1bf7d0e9著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .