如何让winston-cloudwatch在AWS Lambda环境中正常输出日志?
问题原因与解决方法
首先回答你最初的猜测
你的判断完全正确,AWS JavaScript SDK的凭证优先级从高到低排序为:
- 代码中显式传入的凭证参数
- 进程环境变量中的
AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY - 本地
~/.aws/credentials配置文件中的凭证 - 运行环境的IAM角色凭证(EC2、Lambda、ECS等服务自带的运行时凭证)
因此你本地测试时,代码内硬编码的凭证优先级高于全局aws configure的配置,可以正常运行。
Lambda中winston日志不生效的核心原因
Lambda执行逻辑差异导致日志未完成上报就被冻结
winston-cloudwatch默认采用异步批量上报的策略,你在async handler中调用logger.info后,日志还没完成上报就执行了return true,Lambda会立即冻结当前执行环境,未完成的异步请求直接被中断,自然不会生成对应的日志流和日志记录。你本地测试时Node.js进程会一直运行到所有异步任务完成才退出,所以没有这个问题。硬编码凭证的潜在问题
你代码中硬编码的awsAccessKeyId和awsSecretKey可能存在两种问题:
- 部署时未替换掩码占位符,写入的是无效的
********************值 - 硬编码凭证对应的AWS账号和Lambda运行的账号不是同一个,日志被写入了其他账号的CloudWatch中,你无法查到
而且你已经给Lambda绑定的角色授予了CloudWatchFullAccess权限,完全不需要硬编码凭证,AWS SDK会自动读取Lambda运行时的角色凭证,既安全又能避免凭证写错的问题。
修复方案
1. 修改winston配置,删除硬编码凭证,调整上报策略
const logger = winston.createLogger({ transports: [ new WinstonCloudWatch({ logGroupName: '/aws/lambda/FN50', logStreamName: 'stream-FN50', // 删除硬编码的密钥配置,自动使用Lambda运行时角色凭证 awsRegion: 'us-east-1', jsonMessage: true, uploadRate: 1, // 单位秒,有日志立即上报,不攒批减少等待时间 retentionInDays: 14 // 可选,配置日志留存周期 }) ] });
2. 修改handler逻辑,等待日志上报完成后再返回
exports.handler = async (event) => { var d1 = new Date().toISOString(); // 等待info日志上报完成再往下执行 await new Promise((resolve, reject) => { logger.info('WinstonCloudWatch - logging '+d1, (err) => { if (err) { console.error('日志上报失败:', err); return reject(err); } resolve(); }); }); console.log('Console - logging '+d1); try { for (var record of event.Records) { const SNSmessage = JSON.parse(record.Sns.Message); console.log('SNSmessage: ', SNSmessage); } } catch (err) { console.log(err); // 异常场景下等待所有日志上报完成再返回 await new Promise(resolve => logger.on('finish', resolve)); logger.end(); return err; } // 正常返回前等待所有日志上报完成 await new Promise(resolve => logger.on('finish', resolve)); logger.end(); return true; };
额外排查点
如果修改后还是不生效,可以去Lambda默认生成的CloudWatch日志组中,查看是否有winston-cloudwatch的报错日志,常见的错误包括:
- 依赖未打包:部署的zip包中没有包含
winston、winston-cloudwatch对应的node_modules文件 - 权限错误:虽然角色绑定了FullAccess,但存在资源层级的权限限制
- 日志组名称冲突:你手动创建过同名的日志组,权限配置不一致
内容的提问来源于stack exchange,提问作者chris-j
相关产品推荐
相关产品推荐

