前回 AWS Lambda で CloudWatch Logs のログ本文をSlack通知(1) の続きです。
SNSを介さず、Lambdaから直接Slackへ投稿する方法です。
(2) Stream to AWS Lambda でSlack通知
- CloudWatch Logs -> Lambda -> Slack
- CloudWatch Logs のサブスクリプションを使用
- 参考
— サブスクリプションを使用したログデータのリアルタイム処理
— cloudwatchlogs -> lambda -> SNSを試してみた – Qiita
各種設定
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インスタンスに手を入れずにログ監視が行えます。
それ程クリティカルでなく、監視エージェントを導入する程では無いのであれば、 実装候補に入りうると思います。