がじぇったー

お金と家電とプログラミングのブログ

【AWS】CloudWatchLogsのロググループをLambdaでストリーム処理を行う際、timestampはミリ秒付きのUNIXTIMEで表示される

こんにちわ

がじぇったー (@hackmylife7) | Twitter


です。

仕事でCodeを書いてる際に若干ハマったのでメモとして共有です。





TL;DR(要約)

  • CloudWatchLogsのタイムスタンプはデフォルトだと、ミリ秒付きのUNIXTIMEで出力されるので扱いに注意が必要
  • ミリ秒を削るには後ろ3桁を削る

背景

以下のAWSのドキュメントの通りですが、

Lambda 関数を使用して、Amazon CloudWatch Logs ログストリームのログをモニタリングして分析することができます。

AWS Lambda を Amazon CloudWatch Logs に使用する - AWS Lambda

自分の場合はログをlambda(Python)でフィルタリングして、S3に送る、ということをやろうとしていました。

その過程でCloudWatchLogsコンソールでログを表示した際の「時間 (UTC +00:00)」の列に表示されるタイムスタンプをログにくっつけてS3に送る、ということをやりたかったのですが、若干ハマりました。

LambdaでCloudWatchLogsのタイムスタンプを受け取るにはどうすれば良いか?

こちらもドキュメントの通りですが、CloudWatchLogsのログがLambdaに送られる際、データフィールドの値は Base64エンコードされた ZIP アーカイブで早出されます。

{
  "awslogs": {
    "data": "ewogICAgIm1lc3NhZ2VUeXBlIjogIkRBVEFfTUVTU0FHRSIsCiAgICAib3duZXIiOiAiMTIzNDU2Nzg5MDEyIiwKICAgICJsb2dHcm91cCI6I..."
  }
}


これを圧縮解除すると以下の構造のJSONドキュメントになります。

以下に記載の通り、logEventsのtimestampのフィールドが時間を示しています。

{
    "messageType": "DATA_MESSAGE",
    "owner": "123456789012",
    "logGroup": "/aws/lambda/echo-nodejs",
    "logStream": "2019/03/13/[$LATEST]94fa867e5374431291a7fc14e2f56ae7",
    "subscriptionFilters": [
        "LambdaStream_cloudwatchlogs-node"
    ],
    "logEvents": [
        {
            "id": "34622316099697884706540976068822859012661220141643892546",
            "timestamp": 1552518348220,
            "message": "REPORT RequestId: 6234bffe-149a-b642-81ff-2e8e376d8aff\tDuration: 46.84 ms\tBilled Duration: 100 ms \tMemory Size: 192 MB\tMax Memory Used: 72 MB\t\n"
        }
    ]
}

 

このlogEventsのtimestampのフィールドこそが、CloudWatch Logsコンソールでログを表示した際に「時間 (UTC +00:00)」の列に表示される内容と同一となります


このtimestampの形式は、「UNIXミリ秒」です。

timestampの末尾の3桁を取り除くと「UNIX秒(UNIX時間)」となるため、上記の例だと「1552518348220」の末尾の3桁を除いて、「1552518348」という値に変換すると、UTCとして扱えます。

具体的なCodeは次の記事でまとめます。