AWS CloudWatch LogsからS3へログを自動で保存するため、LambdaにPythonを書く(2/2)
前回記事「これ」。少し長くなったので、二つに分けて本記事では続きを書きます。
手順全体像
1. Amazon S3で準備をする
2. CloudWatch Logsでログをエクスポート出来るか確認する
3. Lambda準備
4. Python in Lambda
5. 定期的な動作設定
この記事では4以降について書きます。1-3については前記事を参照ください。
4. Python in Lambda
環境変数に下記の3つを設定します。あとでLambda内からパラメータを取り出すクチとして利用します。暗号化はaws/lambdaにしてます。
[TargetLogGroupName](CloudWatch の取得したいロググループ名)
[DestinationS3BucketName](ログを格納するS3バケット名)
[DestinationS3Prefix](ログを格納するディレクトリ(プレフィックス))
lambda_function.py の中を下記に置換します。
import datetime
import time
import boto3
import os
def get_from_timestamp():
today = datetime.date.today()
yesterday = datetime.datetime.combine(today - datetime.timedelta(days = 1), datetime.time(0, 0, 0))
timestamp = time.mktime(yesterday.timetuple())
return int(timestamp)
def get_to_timestamp(from_ts):
return from_ts + (60 * 60 * 24) - 1
def lambda_handler(event, context):
from_ts = get_from_timestamp()
to_ts = get_to_timestamp(from_ts)
print('[My Function] Timestamp: from_ts %s, to_ts %s' % (from_ts, to_ts))
client = boto3.client('logs')
response = client.create_export_task(
logGroupName = os.environ['TargetLogGroupName'],
fromTime = from_ts * 1000,
to = to_ts * 1000,
destination = os.environ['DestinationS3BucketName'],
destinationPrefix = os.environ['DestinationS3Prefix']
)
return response
実行開始時間をだして、create_export_taskにパラメータを設定しています。
テストを実行して、テストイベントを作成します。イベント用の引数は何もいらないのでブレース{}だけで名前つけて保存しておきます。
上手く動かない場合は、Execution Resultsに問題が出てると思います。Pythonコードのエラーが読めない方は、環境変数とキー値が間違ってないか?、S3バケットのアクセス権限は正しいか?、S3バケットの暗号化タイプ(256のみが使える)、などを見直してください。
HTTPコードに"HTTPStatusCode": 200が返り、Function Logs:に[My Function] Timestamp: ~がでると成功してます。S3の方も見に行きましょう。
Lambda環境変数に書いたバケットのプレフィックスの場所に「aws-logs-write-test」と出ていればOKです。既にCloudWatch Logsのロググループにログがある場合は、そのログデータも出力されます。
あと、関数を作る際にちょっと忘れていました。ログの出力にはそれなりに時間がかかる可能性がありLambda関数のタイムアウトを伸ばしておきます。
根拠はそんなに無いですが、30秒ぐらいで大丈夫だと思いますが余裕を見て45秒に設定してみました。ログの量で変わるので、完了しないなどが起きると「Daily毎にログを削除して日付ごとに分けて出力する」などを検討していく事になります。
5. 定期的な動作設定
トリガーにCloudWatch Events (Logsじゃない)を選びます。
ルールタイプ「スケジュール式」でスケジュールを下記のように設定
cron(0 16 ? * * *)
UTC表記なので、16:00でJST(01:00)ですね。トリガーは一旦無効化しましょう。記載ミスでの暴走は避けたい。皆さんお好きな時間に設定してもらって大丈夫です。
Lambdaの実行ログはCloudWatch Logsにでています。これで定期的な設定が動いた実行時間がわかります。
/aws/lambda/(Your Function's Name)/
終わりに
皆様、いかがだったでしょうか。自らの失敗ベースで備忘録として記載しましたが、ご覧いただいた方にプラスになれば幸いです。もし良ければ記事スキとフォロー頂けますと励みになります。ありがとうございました。
引用
タイトル写真はUnsplashより
前回記事「これ」。