
前回 AWS Lambda で CloudWatch Logs のログ本文をSlack通知(1) の続きです。
SNSを介さず、Lambdaから直接Slackへ投稿する方法です。

(2) Stream to AWS Lambda でSlack通知
- CloudWatch Logs -> Lambda -> Slack
- CloudWatch Logs のサブスクリプションを使用
- 参考
各種設定
Blueprints冒頭に記載されている Slack Integration や KMS の設定については割愛します。
Lambda Function 作成
- [Services] -> [Lambda] -> [Create a Lambda Function]

cloudwatchlog-alarm-to-slack.py
今回使用するFunctionです。 Blueprintと同様に ENCRYPTED_HOOK_URL、SLACK_CHANNEL にSlackの設定値を入れます。
from __future__ import print_function
import base64
import json
import zlib
import datetime
import boto3
import logging
from base64 import b64decode
from urllib2 import Request, urlopen, URLError, HTTPError
ENCRYPTED_HOOK_URL = '' # Enter the base-64 encoded, encrypted key (CiphertextBlob)
SLACK_CHANNEL = '#' # Enter the Slack channel to send a message to
HOOK_URL = "https://" + boto3.client('kms').decrypt(CiphertextBlob=b64decode(ENCRYPTED_HOOK_URL))['Plaintext']
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
data = zlib.decompress(base64.b64decode(event['awslogs']['data']), 16+zlib.MAX_WBITS)
data_json = json.loads(data)
log_json = json.loads(json.dumps(data_json["logEvents"][0], ensure_ascii=False))
if data_json["logGroup"]:
date = datetime.datetime.fromtimestamp(int(str(log_json["timestamp"])[:10])) + datetime.timedelta(hours=9)
message = str(date) + " [CloudWatch Log Alarm] " + data_json["logGroup"] + " / " + data_json["logStream"] + "\nLogMessages:"
logger.info(data_json)
for e in data_json["logEvents"]:
message = message + '\n' + e['message']
logger.info("LogMessage: " + str(message))
slack_message = {
'channel': SLACK_CHANNEL,
'text': "%s" % (message)
}
req = Request(HOOK_URL, json.dumps(slack_message))
try:
response = urlopen(req)
response.read()
logger.info("Message posted to %s", slack_message['channel'])
except HTTPError as e:
logger.error("Request failed: %d %s", e.code, e.reason)
except URLError as e:
logger.error("Server connection failed: %s", e.reason)
IAM role 設定
Lambda Function 作成時に指定した Role に下記が実行できるよう権限を付与します。
- lambda_basic_execution (Function作成時に付与するポリシー)
- KMS復号化
- filter-log-events実行

Metric Filter 作成
CloudWatch Logs からメトリックフィルタを作成します。
- CloudWatch -> Logs -> LogGroup -> Stream to AWS Lambda

- 作成した Lambda Function を指定

- Filter Pattern を設定

- 設定後のロググループ一覧
Subscription に Lambda が表示されます。

Metric Filter の追加
CloudWatch 側からだけでなく、 Lambda 側からもメトリックフィルタの追加が可能です。

- [Lambda] -> [Function] -> [Event source]

通知例

CloudWatchLogsにログを転送していることが前提ですが、
EC2インスタンスに手を入れずにログ監視が行えます。
それ程クリティカルでなく、監視エージェントを導入する程では無いのであれば、
実装候補に入りうると思います。