CloudWatch日志订阅流至Lambda转SNS出现乱码,解码失败求助
解决CloudWatch Logs转Lambda再到SNS的乱码问题
你的问题出在对CloudWatch Logs订阅事件的处理逻辑上——你错误地把整个event对象转成JSON后做base64解码,但实际上CloudWatch传过来的event.awslogs.data是经过base64编码的gzip压缩数据,需要先解码再解压才能得到可读的日志内容。
先给你修正后的完整代码:
console.log("Loading function"); const AWS = require("aws-sdk"); const zlib = require("zlib"); exports.handler = function(event, context, callback) { // 1. 提取base64编码的压缩日志数据 const compressedData = event.awslogs.data; // 2. 解码base64得到二进制压缩包 const buffer = Buffer.from(compressedData, 'base64'); // 3. 解压gzip格式的日志数据 zlib.gunzip(buffer, (err, decompressedBuffer) => { if (err) { console.error("日志解压失败:", err); callback(err); return; } // 4. 转成UTF-8字符串并解析为JSON(CloudWatch日志原始格式是JSON) const logData = JSON.parse(decompressedBuffer.toString('utf8')); const logText = JSON.stringify(logData, null, 2); console.log("解析后的日志内容:", logText); // 5. 发送处理后的日志到SNS const sns = new AWS.SNS(); const params = { Message: logText, Subject: "CloudWatch Logs 转发通知", TopicArn: "arn:aws:sns:region:account:snsTopic" }; sns.publish(params, (err, data) => { if (err) { console.error("SNS消息发布失败:", err); callback(err); } else { console.log("SNS消息发布成功:", data); callback(null, data); } }); }); };
关键修正点说明:
- 提取正确的目标字段:要处理的核心数据是
event.awslogs.data,而不是整个event对象的JSON字符串 - 双层编码的正确处理顺序:
data字段是「base64编码 + gzip压缩」的双层处理结果,必须先解码base64得到二进制压缩数据,再用zlib.gunzip解压 - 字符编码选择:解压后转字符串用
utf8(CloudWatch日志默认采用UTF-8编码),避免中文等非ASCII字符出现乱码 - 异步操作的正确处理:zlib解压和SNS发布都是异步操作,要使用Lambda的
callback来正确传递执行结果或错误信息
之前的代码出现乱码,本质是因为你把整个event的JSON结构(比如{"awslogs": {"data": "..."} })当成了base64数据去解码,完全不符合CloudWatch的事件格式规范,自然会得到无法识别的乱码内容。
内容的提问来源于stack exchange,提问作者Kelvin
相关产品推荐
相关产品推荐

