CloudWatch Logsのログデータは下記のようなJSON形式でLambdaに転送されます。
具体的なログデータはevent['awslogs']['data']で取得できますが、このエンコードされたデータのデコードに少々戸惑ったので記事にしておきます。
{
"awslogs": {
"data": "H4sIAAAAAAAAAHWPwQqCQBCGX0Xm7EFtK+smZBEUgXoLCdMhFtKV3akI8d0bLYmibvPPN3wz00CJxmQnTO41whwWQRIctmEcB6sQbFC3CjW3XW8kxpOpP+OC22d1Wml1qZkQGtoMsScxaczKN3plG8zlaHIta5KqWsozoTYw3/djzwhpLwivWFGHGpAFe7DL68JlBUk+l7KSN7tCOEJ4M3/qOI49vMHj+zCKdlFqLaU2ZHV2a4Ct/an0/ivdX8oYc1UVX860fQDQiMdxRQEAAA=="
}
}
#動作環境
AWS Lambda (Node.js 4.3)
#実装
結論から言うとbase64によるエンコードのみならずgzipでさらに圧縮がなされているので、Node.js側ではevent['awslogs']['data']に対してbase64でのデコードとgunzipをしてあげれば解決します。
公式ドキュメントにもさらっと書いてあったりもしますが。
http://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/Subscriptions.html
コードは下記の通りです。
const zlib = require('zlib');
//略
function processEvent(event, callback) {
const base64Logs = new Buffer(event['awslogs']['data'], 'base64');
zlib.gunzip(base64Logs, function (err, binary) {
var uncompressedLogs = binary.toString('ascii');
const slackMessage = {
channel: slackChannel,
text: ${uncompressedLogs}
};
//略
});
}
ほぼLambdaで既に用意されているCloudWatch Logs用のテンプレートの使い回しになってます。
なので[//略]の部分にはslackにログを通知するための別の記述をしています、今回はデコードのためのコードを説明したいのでここについては省略させてください。
base64によるデコード、gunzipによる解凍もdataを16進数表現で取り扱っているので、gunzipしたデータはtoString('ascii')で文字列に変換する必要があります、もしログに英数字以外が入りうる場合は適宜utf8等に変更してください。
以上になります、参考になれば幸いです。