AWS
CloudWatch
lambda
CloudWatch-Logs

AWS Lambda で CloudWatch Logsのイベントを期間指定&フィルターして処理する方法

AWS Lambda で CloudWatch Logsのイベントを期間指定&フィルターして処理する方法

CloudWatch Eventsで、定期的にCloudWatch Logsのイベントをゴニョゴニョする場合に有効。
他にもやる人がいそうなのでその人の助けになれば。

コード例

import boto3
from datetime import datetime

#ロググループ名を指定
CLOUDWATCH_LOG_GROUP = "XXXX"

#フィルターパターンを指定
CLOUDWATCH_LOF_FILTER = "XXXX"


def lambda_handler(event, context):
    #期間を指定する タイムゾーンに注意
    from_datetime = datetime(2018, 9, 1, 0, 0, 0)
    to_datetime = datetime(2018, 9, 11, 23, 59, 59)

    #filter_log_eventsの期間指定はミリ秒なので1000倍する必要がある
    from_timestamp = int(from_datetime.timestamp()) * 1000
    to_timestamp = int(to_datetime.timestamp()) * 1000

    client = boto3.client("logs")

    next_token = ''

    while True:
        if next_token:
            #トークンが得られている場合でも他のリクエストは設定しないといけない。
            response = client.filter_log_events(
                logGroupName=CLOUDWATCH_LOG_GROUP,
                filterPattern=CLOUDWATCH_LOF_FILTER,
                startTime=from_timestamp,
                endTime=to_timestamp,
                nextToken=next_token #次の結果セットを取得するためのトークン
            )
        else:
            response = client.filter_log_events(
                logGroupName=CLOUDWATCH_LOG_GROUP,
                filterPattern=CLOUDWATCH_LOF_FILTER,
                startTime=from_timestamp,
                endTime=to_timestamp
            )

        for event in response['events']:
            #イベントのタイムスタンプ
            print(event.get("timestamp"))
            #イベントのメッセージをここで取得
            print(event.get("message"))

        if response.get("nextToken"):
            next_token = response["nextToken"]
        else:
            break

    return

filter_log_events リクエストの仕様

response = client.filter_log_events(
    logGroupName='string',          #ロググループ名
    logStreamNames=[                #ログストリーム名(複数指定可能)
        'string',
    ],
    logStreamNamePrefix='string',   #ログストリーム名のプレフィックス
    startTime=123,                  #対象期間 開始タイムスタンプ(ミリ秒)
    endTime=123,                    #対象期間 終了タイムスタンプ(ミリ秒)
    filterPattern='string',         #フィルターパターン
    nextToken='string',             #次のデータセットのトークン
    limit=123,                      #取得件数 デフォルトは10000
    interleaved=True|False          #Trueにすると一度のレスポンスで複数のログストリームにまたがってイベントを返す努力をするらしい。デフォルトはFalse
)

filter_log_events レスポンスの仕様

{
    'events': [
        {
            'logStreamName': 'string',  #ログストリーム名
            'timestamp': 123,           #イベントが出力されたタイムスタンプ
            'message': 'string',        #イベントの本文
            'ingestionTime': 123,       #取り込み時刻
            'eventId': 'string'         #イベントのID
        },
    ],
    'searchedLogStreams': [                     #検索対象となったログストリームについて
        {
            'logStreamName': 'string',          #ログストリーム名
            'searchedCompletely': True|False    #全てのログを検索したか
        },
    ],
    'nextToken': 'string'               #次のデータセットのトークン
}

注意事項

 IAMロールの権限設定を忘れずに

参考

boto3公式ドキュメントのfilter_log_eventsの部分
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/logs.html#CloudWatchLogs.Client.filter_log_events