はじめに
CloudWatchLogsに転送しているログの中に特定の文字列が含まれている場合、
予め用意された日本語の件名・文言で通知メールを送信したいという要件があり、
今回はLambdaとSNSで実装した例をご紹介したいと思います。
主にメインの機能を担うLambda関数のコード(Python)解説になります。
構成図
作成手順
必要な作業は下記の通りになります。
-
SNS設定
1-1. トピック作成
1-2. サブスクリプション作成 -
Lambda関数作成
2-1. Lambda関数用IAMロール作成
2-2. Lambda関数・コード作成 -
CloudWatch Logs サブスクリプション設定
3-1. 検出する文字列指定&検出したら起動するLambda関数の設定
今回はLambda関数のコードを解説します。
その他の詳細な手順については、省略します。
from __future__ import print_function
import base64
import json
import zlib
import boto3
sns = boto3.client('sns')
print('Loading function')
def lambda_handler(event, context):
#CloudWatchLogsから連携されたJSONをデコード&展開
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))
log_message = log_json['message']
#検知文字列を含むログの内容をprint
print(log_message)
#SNSトピック設定
topic = '{SNSトピックのARNを指定する}'
#メール本文・件名の設定 & 宛先のSNSトピックの指定
message = "運用担当者様各位" + "\n" + "\n"
message = message + "なんか検知したよ"
response = sns.publish(
TopicArn=topic,
Message = message,
Subject="がんばって対応してね※自動送信"
)
messageにメール本文の文言を設定します。
"\n"は改行コードです。
Subjectに件名を設定します。
冒頭のデコード&展開はメール本文にログを記載する必要がなければ、不要です。
今回の場合も不要ですが、デバッグ用にLambdaのログに吐くようにしています。
実際に届く通知メール
上記Lambda関数を実行したら、この通知メールが届きます。
件名とメール本文に、Lambda関数のコード内で指定した文言が記載されています。
さいごに
通知メールなので、SESは使わずにSNSで実現したいと思ったものの、
任意の日本語の文言を件名・本文に設定できるのかわからず、検証してみたら可能でした。
ログをそのまま貼り付けただけだと、わかりにくい場合が多いと思うので、
既知のエラーであれば、通知メールに対応手順資料のリンク等が記載されていると、
すごく運用フレンドリーな通知メールになるなぁ、なんてことも思いました。
ご参考になれば幸いです。