Lambda NodeJS 运行时链路接入观测云

背景

为有效监控无服务器架构的业务性能,我们需要将 AWS Lambda 函数的全链路数据接入观测云进行统一可观测性分析。由于 Lambda 环境的特殊性,最佳实践是构建一个集成了 OpenTelemetry 的官方 Layer。该 Layer 能自动捕获函数调用链与性能指标,并通过标准 OTLP 协议上报。为确保数据传输的高效性与前瞻性,我们特别将社区常见的 JSON 格式调整为 Protobuf 编码,以适配观测云后端的技术演进,为函数性能优化与故障诊断提供坚实的数据基础。

前提条件

运行时:NodeJS 22

安装 DataKit 并配置采集器

进入观测云控制台 -「集成」-「DataKit」-「Linux」复制命令安装 DataKit 。

进入 /usr/local/datakit/conf.d/samples ,将 opentelemetry.conf.sample 复制到上级目录 /conf.d 中,并修改文件后缀为 conf

bash 复制代码
cp opentelemetry.conf.sample ../opentelemetry.conf

编辑 opentelemetry 配置文件,修改如下部分,添加 enable = true ,然后保存。

执行以下命令重启 DataKit 。

复制代码
datakit service -R

打开 datakit.confhttp_api 开启 0.0.0.0:9529

准备一个 Lambda 函数

以下 demo 脚本调用了一个 Java 服务 52.83.66.70:8090/user

javascript 复制代码
const http = require('http');

exports.handler = async (event, context) => {
    console.log('=== 开始调用Java服务验证TraceID ===');
    
    try {
        console.log('准备调用Java服务: 52.83.66.70:8090/user');
        
        // 调用您的Java服务
        const javaServiceResult = await callJavaService();
        
        console.log('Java服务调用成功');
        
        return {
            statusCode: 200,
            body: JSON.stringify({
                success: true,
                message: 'Java服务调用完成',
                javaServiceResponse: javaServiceResult,
                requestId: context.awsRequestId,
                timestamp: new Date().toISOString()
            })
        };
        
    } catch (error) {
        console.error('调用Java服务失败:', error);
        return {
            statusCode: 500,
            body: JSON.stringify({
                success: false,
                message: 'Java服务调用失败',
                error: error.message
            })
        };
    }
};

function callJavaService() {
    return new Promise((resolve, reject) => {
        console.log('开始发起HTTP请求到Java服务...');
        
        const options = {
            hostname: '52.83.66.70',
            port: 8090,
            path: '/user',
            method: 'GET',
            timeout: 5000,  // 5秒超时
            headers: {
                'User-Agent': 'Lambda-OTEL-Test/1.0',
                'Accept': 'application/json'
            }
        };
        
        const req = http.request(options, (res) => {
            console.log(`Java服务响应状态码: ${res.statusCode}`);
            console.log('响应头:', JSON.stringify(res.headers));
            
            let data = '';
            res.on('data', (chunk) => {
                data += chunk;
            });
            
            res.on('end', () => {
                console.log('Java服务响应数据长度:', data.length);
                console.log('原始响应:', data);
                
                try {
                    // 尝试解析JSON响应
                    const parsedData = data ? JSON.parse(data) : {};
                    resolve({
                        statusCode: res.statusCode,
                        data: parsedData,
                        headers: res.headers,
                        rawResponse: data
                    });
                } catch (e) {
                    // 如果JSON解析失败,返回原始数据
                    console.log('响应不是JSON格式,返回原始数据');
                    resolve({
                        statusCode: res.statusCode,
                        data: data,
                        headers: res.headers,
                        isJson: false
                    });
                }
            });
        });
        
        req.on('error', (error) => {
            console.error('请求Java服务错误:', error.message);
            reject(error);
        });
        
        req.on('timeout', () => {
            console.error('请求Java服务超时');
            req.destroy();
            reject(new Error('请求Java服务超时'));
        });
        
        // 发送请求
        req.end();
        console.log('HTTP请求已发送到Java服务');
    });
}

测试事件:

构建 Layer

构建官方的 Layer 做导出器,通过 Layer 集成,无侵入式地自动捕获 Lambda 函数执行的链路数据可以自动采集 Lambda 函数的链路数据,将采集的数据转换为 OpenTelemetry(OTel)标准格式,确保与观测后端平台的兼容性。

注意:Node.js 社区提供的默认 OpenTelemetry 导出器通常使用 HTTP/JSON 方式发送数据,需要将默认的导出协议从 HTTP/JSON 改为 HTTP/PROTOBUF,DataKit 后续可能考虑废弃 HTTP/JSON 方式。Protobuf 编码具有更高的序列化/反序列化效率,能显著降低传输数据大小和网络开销,尤其适用于 Lambda 的短时执行环境。

具体可以参考 Opentelemetry 的社区:github.com/open-teleme...

克隆仓库

bash 复制代码
git clone https://github.com/open-telemetry/opentelemetry-lambda

修改协议

进入项目目录,将相关文件的 @opentelemetry/exporter-trace-otlp-http 改成@opentelemetry/exporter-trace-otlp-proto,一共需要修改 3 个文件。

bash 复制代码
cd opentelemetry-lambda/nodejs

./packages/layer/src/wrapper.ts

./packages/layer/package.json

./packages/layer/test/wrapper.spec.ts

安装依赖

复制代码
npm  install

构建项目

arduino 复制代码
npm run build

./nodejs/packages/layer/build/ 会有一个 layer.zip 文件。

添加 Layer

创建 Layer

在 AWS 控制台 Lambda 进入「layer」,新建一个 Layer,选择上传 .zip 文件方式上传刚才生成的 layer.zip 文件,架构选择 x86、运行时选择 nodejs。创建好后复制 ARN 。

添加 Layer

在 Demo 函数中添加 Layer,选择指定一个 ARN ,将刚才的 ARN 复制进去,点击「添加」。

配置环境变量

配置 Lambda 环境变量,选择「配置」-「环境变量」。

添加如下变量:

KEY VALUE
AWS_LAMBDA_EXEC_WRAPPER /opt/otel-handler
OTEL_EXPORTER_OTLP_ENDPOINT http://<datakit主机地址>:9529/otel
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL http/protobuf
OTEL_NODE_ENABLED_INSTRUMENTATIONS aws-lambda,aws-sdk,http,https,pg,mysql,redis
OTEL_SERVICE_NAME 服务名称
OTEL_TRACES_SAMPLER always_on

测试函数

回到函数点击测试

观测云效果

链路上报效果如下:

相关推荐
2501_930472441 天前
03_AWS迁移腾讯云_组件差异风险清单与工作量WBS
云计算·腾讯云·aws
Akiyama_Mio-Kon1 天前
CVE-2026-85654 深度解读:DynamoDB MCP Server 如何把数据模型风险带到 CDK 部署宿主
aws·dynamodb·cdk·mcp·cve-2026-85654·lac·agent 安全
范桂飓2 天前
AWS Kiro Agent 架构解析
架构·云计算·aws
GreatVicent4 天前
AI Agent互操作标准化加速:A2A协议正式加入Linux基金会
linux·运维·人工智能·agent·aws·a2a
Akiyama_Mio-Kon5 天前
AWS AI 自动安全修复深度解读:从生成脚本到最小权限、双人审批与回滚审计闭环
aws·ai agent·security hub·guardduty·安全自动化·云安全治理
l1t9 天前
DeepSeek总结的DuckDB访谈:DuckDB的崛起、扩展与AWS收购
数据库·云计算·aws·duckdb
snpgroupcn10 天前
云端共筑·数据跃迁——德勤×SNP×AWS联袂解读SAP ECC升级实战
云计算·aws
yyuuuzz10 天前
企业出海云服务器部署踩坑记录:从频繁超时到稳定运行的复盘
运维·服务器·网络·人工智能·aws
李兆龙的博客10 天前
从一到无穷大 #84:AWS 收购 DuckLabs——DuckDB 与分析系统正在变化的物理边界
云计算·aws
Akiyama_Mio-Kon10 天前
计算机每日时报(2026-08-27):算力继续加码,Agent 先补好安全与交付边界
aws·nvidia·microsoft 365·github copilot·ai 基础设施·ai agent 安全·excel python