#問題
Lambda標準のログを抑止してCloudWatchLogsのコストを節約したい。けど、特定の場合にはログを出力したいといった問題を解決します。
#Lambdaコード
早速ですが、このような関数を用意してlambda_handler内で使用します。
必要な権限(IAMポリシー)は後で解説します。標準のログを出さないようにするのも、IAMポリシーの定義で行います。
import boto3
import time
import datetime
logs_client = boto3.client('logs')
lgn = '/aws/lambda/PutLog'
def lambda_handler(event, context):
put_log('test')
put_log('テスト')
def put_log(message):
# ロググループがない場合作成
res = logs_client.describe_log_groups(
logGroupNamePrefix=lgn
)
if not res['logGroups']:
res = logs_client.create_log_group(
logGroupName=lgn
)
# putするログストリームを取得
lsn = datetime.datetime.now().strftime("%Y/%m/%d") + '[PutLog]'
res = logs_client.describe_log_streams(
logGroupName=lgn,
logStreamNamePrefix=lsn,
)
# ログストリームがない場合作成し、取得
if not res['logStreams']:
res = logs_client.create_log_stream(
logGroupName=lgn,
logStreamName=lsn
)
res = logs_client.describe_log_streams(
logGroupName=lgn,
logStreamNamePrefix=lsn,
)
# シーケンストークンがある場合指定する
if 'uploadSequenceToken' in res['logStreams'][0]:
seq_token = res['logStreams'][0]['uploadSequenceToken']
res = logs_client.put_log_events(
logGroupName=lgn,
logStreamName=lsn,
logEvents=[
{
'timestamp': int(time.time()) * 1000,
'message': message
},
],
sequenceToken=seq_token
)
# ない場合指定しない
else:
res = logs_client.put_log_events(
logGroupName=lgn,
logStreamName=lsn,
logEvents=[
{
'timestamp': int(time.time()) * 1000,
'message': message
},
]
)
コード解説
コードはこちらの記事を参考にしました。
Lambda標準のログと同じような感覚で使いたかったので、ロググループ作成とログストリーム作成を追加しました。これにより、あらかじめそれらを作成する必要がなくなります。
Lambda内の変数lgnでロググループ名の指定と、変数lsnでログストリーム名の指定をします。ここでは、ロググループ名は標準のログと同じ、ログストリーム名は日付+[PutLog]にしています。ログストリーム名を調整すれば、任意の単位でまとめることができると思います。
そして、少し理解が難しいのがシーケンストークンの指定です。参考記事でも触れられていますが、2回目以降同じログストリームに書き込むためには、シーケンストークンの指定が必要です。
#IAMポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams"
],
"Resource": "arn:aws:logs:リージョン名:アカウントID:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:リージョン名:アカウントID:log-group:/aws/lambda/PutLog:log-stream:*[PutLog]"
]
}
]
}
##ポリシー解説
ポリシーの内容も前述の記事を参考にしています。リージョン名とアカウントIDは置き換えてください。
CreateLogStreamおよびPutLogEventsを独自に指定することで、標準のログが出力されるのを回避しています。
ここでは、関数内で指定している日付+[PutLog]に対応させるために*[PutLog]で、ワイルドカードの指定をしています。
#実行結果
通常であればこのような文字列が付与されたログストリームが作成され、開始終了のログやprint等で指定した文字列が出力されます。前述のポリシーを定義することで、このような標準のログ出力を抑止します。