Serverless Framework无法为直接导入的DynamoDB客户端生成Span
解决Serverless Framework中单独导入DynamoDB客户端无法生成链路Span的问题
问题原因
Serverless Framework 2.72.3的自动链路追踪通过patch顶层AWS对象的原型方法(如makeRequest)实现Span生成。直接导入aws-sdk/clients/dynamodb时,该模块的客户端原型未被Serverless的patch逻辑覆盖;同时错误的DocumentClient初始化方式(直接调用Dynamodb.DocumentClient(config)而非使用new关键字),会导致实例无法继承已patch的方法,最终无法生成调用链路Span。
无额外依赖解决方案
方案1:调整DocumentClient初始化方式
修改单独客户端的初始化代码,使用new关键字创建实例,并通过Dynamodb.config统一配置,确保继承被Serverless patch的原型方法:
const Dynamodb = require('aws-sdk/clients/dynamodb'); // 通过config.update设置区域,而非传入构造函数 Dynamodb.config.update({ region: 'us-east-1' }); // 使用new关键字初始化DocumentClient const dbclient = new Dynamodb.DocumentClient(); // 后续调用保持不变 const data = await dbclient.query(params).promise();
方案2:手动复用已patch的原型方法(环境存在全局AWS对象时)
若Lambda环境因其他依赖已加载完整AWS SDK(全局存在AWS对象),可手动将已patch的方法赋值给单独导入的Dynamodb客户端原型:
const Dynamodb = require('aws-sdk/clients/dynamodb'); // 复用全局AWS对象的已patch方法 Dynamodb.Service.prototype.makeRequest = AWS.Service.prototype.makeRequest; const config = { region: 'us-east-1' }; const dbclient = new Dynamodb.DocumentClient(config); const data = await dbclient.query(params).promise();
方案3:手动生成符合格式的追踪日志
若上述方案无效,可通过输出Serverless追踪系统识别的日志格式手动标记Span:
const Dynamodb = require('aws-sdk/clients/dynamodb'); const dbclient = new Dynamodb.DocumentClient({ region: 'us-east-1' }); // 从环境变量获取Trace ID(适配X-Ray/Serverless追踪) const traceId = process.env._X_AMZN_TRACE_ID || ''; // 记录Span开始 console.log(`serverless.trace.span.start: {"name": "dynamodb-query", "traceId": "${traceId}"}`); const data = await dbclient.query(params).promise(); // 记录Span结束 console.log(`serverless.trace.span.end: {"name": "dynamodb-query", "traceId": "${traceId}"}`);
验证方法
部署修改后的代码,触发Lambda执行后查看Serverless追踪面板,确认DynamoDB查询的Span已正常生成。
内容的提问来源于stack exchange,提问作者dcstingray
相关产品推荐
相关产品推荐

