AWSの知識を血肉にするための「AWS 100日チャレンジ」の52日目です。
今日も頑張ります。
AWS 100日チャレンジの記事を書く上でのルール
・100日連続アウトプット!
・継続が第一、クオリティは第二
・「社会人のリアル」を忘れない(持続可能な完走を目指す)
・コアな学習に全集中!
テーマとするサービス以外は、CloudFormationや構築済みの資産をフル活用。効率よく「核心」を突き詰めます。
課題
CloudWatch LogsのサブスクリプションフィルターでLambdaへ転送してみる
実施
CloudWatch Logsのサブスクリプションフィルターは、ロググループに届いたログデータをリアルタイムで他のAWSサービス(Lambda、Kinesis Data Streams、Kinesis Data Firehoseなど)に転送するための仕組みです。
転送先は複数種類がありますが、Lambdaにします。
1.CloudWatchのロググループ設定
EC2にエージェントをインストールして、CloudWatch Logsにログが記録されるようにします。
CWエージェントのconfig.jsonはAPACHEのerror_logのみを収集する設定にしました。
sudo vi /opt/aws/amazon-cloudwatch-agent/bin/config.json
{
"agent": {
"run_as_user": "root"
},
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/etc/httpd/logs/error_log",
"log_group_name": "Apache-Error-Logs",
"timestamp_format": "[%a %b %d %H:%M:%S.%f %Y]"
}
]
}
}
}
}
CWエージェントを起動。
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json -s
CWエージェント起動確認
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a status
2.Lambda関数作成
サブスクリプションフィルタの送信先にLambdaを指定するので受け皿であるLambda関数が必要。

関数プログラムは以下
import base64
import json
import gzip
import boto3
sns = boto3.client('sns')
def lambda_handler(event, context):
# データのデコードと解凍
data = event['awslogs']['data']
decoded_data = base64.b64decode(data)
log_json = json.loads(gzip.decompress(decoded_data))
# ログメッセージの抽出
for log_event in log_json['logEvents']:
msg = log_event['message']
# SNSへ送信(ARNを直接指定)
sns.publish(
TopicArn='SNSのARN',
Subject="Apache Error Alert",
Message=f"Server Log: {msg}"
)
return {'statusCode': 200}
3.サブスクリプションフィルターの作成
CloudWatchの管理画面よりログ「Apache-Error-Logs」をクリック。
サブスクリプションフィルタータブをクリック。
作成ボタンを押す。

作成するのは、Lambdaサブスクリプションフィルタ。


SNSはすでに作成しているものを使用しました。
3.動作確認
Ec2にログインして、以下コマンドを実行しログを出力する。
echo "[$(date)] [error] これは本物のApacheから送られたテストメッセージです!" | sudo tee -a /etc/httpd/logs/error_log
Gmailを確認するとメールが飛んできているのがわかりました。
