You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Lambda写入CloudWatch日志重复问题排查求助

问题:CloudWatch日志重复写入排查

为满足移动应用开发需求,我们部署了一个通过ApiGateway触发的Node.js AWS Lambda,用于向预定义的CloudWatch LogGroup和LogStream写入日志,核心代码如下:

export const handler = async (event: APIGatewayEvent): Promise<{ headers: { "content-type": string }; body: string; statusCode: number }> => {
  const logs = new CloudWatchLogs();
  const events: PutLogEventsRequest = JSON.parse(event.body!);
  await logs.putLogEvents(events, function (err, data) {
        if (err) {
            console.log(err, err.stack);
        }
        result = data;

    }).promise();
  return {statusCode: 200, headers: {"content-type": "plain/text"}, body: "OK"};
}

调用测试情况

  • 首次调用
    请求体:

    {
       "logEvents": [ 
          { 
             "message": "Something happened 001",
             "timestamp": 1695215849616
          }
       ],
       "logGroupName": "the-log-group",
       "logStreamName": "the-log-stream"
    }
    

    日志结果(正常):

    Something happened 001
    
  • 第二次调用
    请求体:

    {
       "logEvents": [ 
          { 
             "message": "Something happened 002",
             "timestamp": 1695215849616
          }
       ],
       "logGroupName": "the-log-group",
       "logStreamName": "the-log-stream"
    }
    

    日志结果(出现重复):

    Something happened 001
    Something happened 001
    Something happened 002
    Something happened 002
    
  • 第三次调用
    请求体:

    {
       "logEvents": [ 
          { 
             "message": "Something happened 003",
             "timestamp": 1695215849618
          }
       ],
       "logGroupName": "the-log-group",
       "logStreamName": "the-log-stream"
    }
    

    日志结果(仍重复):

    Something happened 001
    Something happened 001
    Something happened 002
    Something happened 002
    Something happened 003
    Something happened 003
    

问题根源分析

  1. CloudWatch PutLogEvents的sequenceToken机制:
    向已存在的LogStream写入日志时,必须携带上一次调用putLogEvents返回的nextSequenceToken。如果不携带这个token,CloudWatch会将当前请求判定为前一次请求的重试,从而重复写入之前的日志条目,同时也会写入当前请求的新条目,最终导致重复。

  2. 代码中的关键问题:

    • 未保存并复用nextSequenceToken:每次调用仅传入请求体参数,完全忽略了sequenceToken的强制要求。
    • 错误混用回调与Promise:logs.putLogEvents()同时传入回调函数并调用.promise(),导致逻辑混乱,且未正确定义result变量,无法获取返回的nextSequenceToken。
  3. 首次调用正常的原因:
    首次向LogStream写入日志时,LogStream刚创建,无历史sequenceToken,因此无需传入,日志写入正常。但从第二次调用开始,必须携带上一次的nextSequenceToken,否则会触发重复写入逻辑。

内容的提问来源于stack exchange,提问作者Tomáš Mika

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 06:22:43