こんにちわ
がじぇったー (@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は次の記事でまとめます。