Node.js处理AWS CloudWatch日志时触发Incorrect Header Check(Z_DATA_ERROR)错误
解决CloudWatch日志转Slack的Lambda zlib解压错误
错误原因分析
你遇到的Z_DATA_ERROR(incorrect header check)是因为传入zlib.gunzipSync()的Buffer不是有效的gzip压缩数据,常见触发场景:
- 测试事件不合法:使用Lambda控制台自定义测试事件时,未遵循CloudWatch Logs触发的真实事件结构,
event.awslogs.data并非正确的base64编码gzip数据 - 事件源配置错误:Lambda触发源不是CloudWatch Logs,导致传入的事件格式不符合预期
分步解决方案
1. 验证事件源与测试数据
- 确认Lambda的触发源为CloudWatch Logs,而非其他AWS服务
- 如需测试,不要手动编写测试事件,从真实日志生成测试数据:
- 进入CloudWatch Logs控制台,找到目标日志组
- 选中一条日志,点击「Actions」→「Send to Lambda」
- 选择你的Lambda函数,生成真实触发事件并用于测试
2. 修复代码问题
除了解压错误,代码中存在一个会导致Slack请求失败的拼写错误:requestOptions中的header应为复数headers,否则请求头无法被正确识别。同时建议增加数据校验逻辑,避免无效数据导致崩溃。
修改后的完整代码:
const https = require('https'); const zlib = require('zlib'); exports.handler = async (event, context) => { try { // 校验事件结构合法性 if (!event.awslogs?.data) { throw new Error("Invalid event: missing awslogs.data field"); } const payload = Buffer.from(event.awslogs.data, 'base64'); console.log('payload:', payload); // 单独捕获解压错误,增加排查信息 let decompressedData; try { decompressedData = zlib.gunzipSync(payload).toString('utf8'); } catch (zlibError) { console.error("Zlib decompression failed. Payload length:", payload.length); throw zlibError; } const parsedPayload = JSON.parse(decompressedData); console.log('parsedPayload:', parsedPayload); const logEvents = parsedPayload.logEvents; let cwlErrorMessage = ''; for (let logEvent of logEvents) { cwlErrorMessage += logEvent.message + "\n"; } let userAccountNotification = { 'username': 'someUser', 'blocks': [ { "type": "section", "text": { "type": "mrkdwn", "text": cwlErrorMessage.replace(/"/g, 'Bug!') } } ], }; await sendSlackMessage(userAccountNotification); return `Successfully processed ${logEvents.length} log events.`; } catch(error) { console.error('Stg CloudWatch Error Alarm: error sending slack notification ', error); throw error; // 抛出错误便于Lambda监控告警 } }; const sendSlackMessage = (messageBody) => { return new Promise((resolve, reject) => { // 修复header为headers const requestOptions = { method: 'POST', headers: { 'Content-Type': 'application/json' } }; const req = https.request('your-slack-webhook-url', requestOptions, (res) => { let response = ''; res.on('data', (d) => { response += d; }); res.on('end', () => { // 校验Slack响应状态 if (res.statusCode >= 200 && res.statusCode < 300) { resolve(response); } else { reject(new Error(`Slack request failed with status ${res.statusCode}: ${response}`)); } }) }); req.on('error', (e) => { reject(e); }); req.write(JSON.stringify(messageBody)); req.end(); }); };
3. 额外排查点
- 检查Lambda执行权限:确保拥有
logs:CreateLogStream和logs:PutLogEvents权限,以便查看完整的错误日志详情 - 验证Slack Webhook地址:确认
sendSlackMessage中的URL为有效的Slack Incoming Webhook地址
内容的提问来源于stack exchange,提问作者risingTide
相关产品推荐
相关产品推荐

