CloudWatch LogsからS3にエクスポート(Lambda/Python)

CloudWatch Logsから、LmabdaでログをS3にエクスポートする。対象のロググループとバケット内の第一階層を引数で指定するようにした。今回の事例ではエクスポートの範囲は「前日0時〜実行当日の0時」となる。 参考 boto3 API Reference LambdaよりCloudWatchログをS3に保存方法紹介 ちなみに過去マネコンから実行する手順書いた。 CloudWatchLogsからS3へログをエクスポートする 今回の検証に使用したアイテム(個人メモ) アイテム 名称 Lambda用IAMロール lambda_basic_execution Lambda関数 log-export-function S3バケット log-export-xxxxxxxx Lambda用IAMロールの権限はlogsフルアクセスのみ。S3もいると思ってたがなくてもできた。バケットポリシー側で許可しているからか。S3バケット名は環境変数で指定した。ちなみに対象バケットは、動作不可になるためオブジェクトロックを設定しないこと。 S3バケットポリシー(log-export-xxxxxxxx) { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "logs.ap-northeast-1.amazonaws.com" }, "Action": "s3:GetBucketAcl", "Resource": "arn:aws:s3:::log-export-xxxxxxxx" }, { "Effect": "Allow", "Principal": { "Service": "logs.ap-northeast-1.amazonaws.com" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::log-export-xxxxxxxx/*", "Condition": { "StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control" } } } ] } Lambdaコード(Python3.9) import boto3 import collections from datetime import datetime, date, time, timedelta import os def lambda_handler(event, context): log_g = event....

December 19, 2021

Terraform loop処理の応用編(4) - Lambda

今日のTerraform loopネタはLambda関数作成。ログ監視の一貫なので、CloudWatchLogsのロググループとサブスクリプションフィルタ作成も一緒にやる。 この例でのディレクトリ構成は以下の通り。lambda/upload配下のzipファイルはTerraformにより生成されたもので、初回は空である。 work_dir ├── config.tf #初期化ファイル ├── lambda │ ├── code │ │ ├── func001 │ │ │ └── lambda-func001.py │ │ ├── func002 │ │ │ └── lambda-func002.py │ │ └── func003 │ │ └── lambda-func003.py │ └── upload │ ├── lambda-func001.zip │ ├── lambda-func002.zip │ └── lambda-func003.zip ├── lambda.auto.tfvars ├── lambda_cwl.tf ├── terraform.tfvars #regionのみ定義 └── variables.tf 最初に、すべて定数で記述したパターン。 lambda_logs.tf(定数バージョン) ################################################# # Lambda archive data ################################################# data "archive_file" "data-lambda-func001" { type = "zip" source_dir = "lambda/code/func001" output_path = "lambda/upload/lambda-func001....

December 12, 2021

CloudWatchLogsのログ監視 - サブスクリプションフィルタ + Lambdaでメール送信(2)

表題の件、以下の過去記事に書いたが、この時点では送信される本文ががログメッセージだけとなっていて、通知メールとしては不十分なため本文もカスタマイズしてみた。 CloudWatchLogsのログ監視 - サブスクリプションフィルタ + Lambdaでメール送信 各種設定は冒頭の過去記事と同様のため割愛するとして、コードは変更前・後両方載せておく。 変更前:lambda_function.py(1) import base64 import json import zlib import datetime import os import boto3 from botocore.exceptions import ClientError print('Loading function') def lambda_handler(event, context): data = zlib.decompress(base64.b64decode(event['awslogs']['data']), 16+zlib.MAX_WBITS) data_json = json.loads(data) log_entire_json = json.loads(json.dumps(data_json["logEvents"], ensure_ascii=False)) log_entire_len = len(log_entire_json) print(log_entire_json) for i in range(log_entire_len): log_json = json.loads(json.dumps(data_json["logEvents"][i], ensure_ascii=False)) try: sns = boto3.client('sns') #SNS Publish publishResponse = sns.publish( TopicArn = os.environ['SNS_TOPIC_ARN'], Message = log_json['message'], Subject = os.environ['ALARM_SUBJECT'] ) except Exception as e: print(e) 参考...

November 14, 2021

AWS監視の方式を整理したい

AWSで過去普通にやってた監視実装も、2,3年経つと(或いはそれより短い周期で)陳腐化する。以前は限られたサービスのリソース範囲でやれることをやっていればよかったが、今はSSM(Systems Manager)、Lambda、EventBridgeなどの「登場人物」が増えて、カスタマイズが可能になったからだ。やれることが増えた分、実装が複雑になる。その分チャレンジングな分野になって楽しめると言えないこともないが…、時間が足りないんだ。頭痛ぇな、まったく。絡み合った糸をほぐすためにまとめてみる。 監視の種別としては大枠としてノード監視、閾値監視、ログ監視、プロセス監視、イベント監視と想定する。それぞれの実装方式が若干異なってくるため整理したい。 監視方式大枠 ノード監視 CloudWatchアラーム(ステータスチェック) ー> (EventBridgeルール) ー> Lambda ー> SNSトピック ー> メール送信 ※ハード障害等でインスタンスが落ちた時に発動される想定。手動で落とした時は発動しないので通知は来ない。 閾値監視 CloudWatchアラーム(閾値チェック) ー> (EventBridgeルール) ー> Lambda ー> SNSトピック ー> メール送信 ※EC2インスタンスのCPU使用率、ディスク使用率を想定。メモリ監視は別途カスタムメトリクスの実装がいる。 ログ監視 CloudWatchLogsでログ出力(サブスクリプションフィルタキーワード検知)ー> Lambda ー> SNSトピック ー> メール送信 ※これだけEventBridgeを使用しない。 プロセス監視 EC2インスタンス上のプロセス数監視に相当する。検索すると「プロセス落ちていたらインスタンス再起動」アクションの事例が多いが、今回やりたいのはメール通知だけ。一応メモっておくけど。 CWエージェント + SSM + インスタンス停止、Lamabdaなし EC2上のプロセスを監視し自動復旧する CWエージェント + SSM + 自動再起動、Lamabdaなし AWSでプロセス監視を実装したい CWエージェント + Lamabda + SSM + 自動再起動 EC2のプロセス監視と自動再起動 procstat事例 以下はSSMを使用せず、procstatプラグインを使用してプロセス監視する例。記事には監視設定以降の通知イベント事例はなし。 CloudWatch Agent でProcstatプラグインの利用が可能になりました SSMを使わずCloudwatchでEC2上のプロセス監視をしてみる 以下は途中まで参照したところ(後半は有料サービスの案内)、アラームを作成するところまでわかりやすかった。であれば、閾値監視と同様にEBルールを挟んでLambdaをターゲットに指定 ー> SNSトピックに渡されてメール送信、でいけるはず。 CloudWatchでプロセス監視する手順をLinuxとWindowsともに詳しく紹介 イベント監視 イベント発生 ー> (EventBridgeルール) ー> Lambda ー> SNSトピック ー> メール送信 ※1....

November 7, 2021

CloudWatchLogsのログ監視 - サブスクリプションフィルタ + Lambdaでメール送信

AWSでのログ監視メール送信はサブスクリプションフィルタ + Lambda + SNSを使用するのがスタンダード。みんなやっていそうなことだが未経験だったのでやってみた。基本参考にしたのは王道クラメソさんの記事だったが、ちょっとわかりにくいところがあったので他の記事も合わせて参照して若干やり方変えつつ検証した。 今回はマネコン作業メインでやったが、CLIやTerraformなどAPI経由で実装する場合追加作業が発生するため注意が必要。(後述 補足事項に記載) 参考 CloudWatch Logs を文字列検知してログ内容をメールを送信してみた サブスクリプションフィルター版 【AWS】CloudWatch Logsからシステムログをメール通知する。 CloudWatch Logs のサブスクリプションフィルタを使って特定文字列を検知したログをEメール通知する ※CLI実装例 以下は今後の参考用 CloudWatchLogsの内容をフィルタリングしてLambdaで通知させたい ※除外キーワードをコードで記述する例 CloudWatchLogsからLambda経由でログメッセージを通知する ※Terraform実装例 処理概要 CWLにログが出力される CWLのサブスクリプションフィルタでキーワード検知 Lambda関数起動 SNSに連携される メール通知 作業概要 SNSトピック作成〜サブスクライブ Lambda用IAMロール作成 Lambda関数作成 ロググループ/ログストリーム作成 ロググループにサブスクリプションフィルタ作成 (配信先に3.のLambda関数を指定) テストログ送信〜メール通知確認 ※ログストリーム作成は検証時のみ。通常は自動生成される。 今回の検証に使用したアイテム(個人メモ) アイテム 名称 SNSトピック log-monitor-topic Lambda用IAMロール send-log-filter-role Lambda関数 send-log-filter-function サブスクリプションフィルタ send-log-filter やったこと SNSトピック作成〜サブスクライブ 過去記事:AWS EventBridge + SNSからのメール件名をカスタマイズするに書いたので省略。ここではCLIでやってるけどマネコンでも特にハマるところはない。アクセスポリシーはデフォルトにした。 Lambda用IAMロール作成 とりあえず以下のマネージドポリシーをアタッチ。 CloudEatchLogsFullAccess AmazonSNSFullAccess Lambda関数作成 (1) 参考ブログのコード貼り付け import base64 import json import zlib import datetime import os import boto3 from botocore....

October 31, 2021

CloudWatchLogsからS3へログをエクスポートする

CloudWatchLogsからS3へログをエクスポートする。基本的に以下の通りにやればできるのだが、説明が冗長だったりわかりにくいところがあるので自分用に書いておく。IAMユーザ作成の手順とかいらん。親切のつもりだろうけど、無駄に記事が長くなって読む気が失せる… コンソールを使用してログデータを Amazon S3 にエクスポートする 概要。ログストリームのエクスポートはログストリームの画面ではなく、ロググループの画面から行う。事前にログエクスポート専用S3バケットを用意し、ドキュメントの通りにバケットポリシーを設定しておく。適当なランダム値のプレフィクスを作成し、バケットポリシーに反映する。バケットにオブジェクトロックがかかっていると動作しないので注意。 バケットポリシーサンプル { "Version": "2012-10-17", "Statement": [ { "Action": "s3:GetBucketAcl", "Effect": "Allow", "Resource": "arn:aws:s3:::my-app-logs", "Principal": { "Service": "logs.ap-northeast-1.amazonaws.com" } }, { "Action": "s3:PutObject" , "Effect": "Allow", "Resource": "arn:aws:s3:::my-app-logs/sjh6dert3a/*", "Condition": { "StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control" } }, "Principal": { "Service": "logs.ap-northeast-1.amazonaws.com" } } ] } 上記前提条件が整った上で、以下実行する。カッコ内は英語表記の場合。 対象のログストリーム画面上で、「アクション」(Actions)のプルダウンから、「データをAmazon S3に エクスポート」(Export data to Amazon S3)を選択。 次画面でバケット名、作成しておいたS3のプレフィクス名、ログストリーム、時間の範囲指定を行い、「エクスポート」実行 エクスポート先のS3では確かzip化された状態で格納されていたと思う。 ドキュメント中の表現一部「ランダムに生成されたプレフィクス」、これがわかりにくかった。ログエクスポート先のS3にランダム文字列のプレフィクスが存在するのが望ましいようだ。なぜ普通の文字列ではなくランダム値が望ましいのかはよくわからん。「生成されたランダム文字列」と書かれているもんだから、どこで生成してるんだ?と混乱した。これは自分で適当に決めた値でよい。 上記に書いた作業は必要に応じてアドホック的に行う対応であり、定常的対応であればLambdaなりshellなりでバッチ化するだろう。 追記 ということで、Lambdaによるログエクスポートの記事書いた。 CloudWatch LogsからS3にエクスポート(Lambda/Python)

October 23, 2021