通过OpenTelemetry为应用埋点并上报链路数据至可观测链路 OpenTelemetry 版后,可观测链路 OpenTelemetry 版即可开始监控应用,您可以查看应用拓扑、调用链路、异常事务、慢事务和SQL分析等一系列监控数据。本文介绍如何使用OpenTelemetry对Node.js Express应用进行自动或手动埋点并上报数据。
前提条件
支持的运行时环境:
OpenTelemetry 目前支持 Node.js v18 及以上版本。
需要注意的是,仅支持 Node.js 的 Active(活跃)或 Maintenance LTS(长期维护)版本。更早的 Node 版本未经过 OpenTelemetry 官方测试,因此不保证能够正常运行。
更多版本兼容性问题,请查看 Supported Runtimes。
支持的库和框架:
许多流行的 Node.js 库都支持自动埋点。有关完整列表,请参阅 Supported instrumentations。
方法一:自动埋点(推荐)
通过 OpenTelemetry 自动插桩技术,无需修改应用代码即可实现 Node.js 应用的可观测性数据采集并接入云监控2.0。
运行以下命令来安装 OpenTelemetry API、SDK 和插桩工具。
npm install --save @opentelemetry/api npm install --save @opentelemetry/auto-instrumentations-node配置 OpenTelemetry。
请将
${httpEndpoint}替换为HTTP接入点,将${serviceName}替换为您的应用名。export OTEL_SERVICE_NAME=${serviceName} export OTEL_TRACES_EXPORTER=otlp export OTEL_METRICS_EXPORTER=none export OTEL_LOGS_EXPORTER=none export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=${httpEndpoint} export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf export NODE_OPTIONS="--require @opentelemetry/auto-instrumentations-node/register" node app.js说明如要添加更多 OpenTelemetry 环境变量,请查看OpenTelemetry Node.js自动埋点配置。
方法二:手动埋点
以下内容使用 OpenTelemetry Node.js SDK 构造 Express 框架应用的 Trace 数据并上传到阿里云可观测链路 OpenTelemetry 版。
步骤一:创建示例应用程序(可选)
这一步将演示如何构建一个简单的 Web 应用程序。如果您已经有编写好的 Node.js 应用程序,请跳过。
新建一个项目目录,在目录下执行
npm init -y命令,会创建一个空的 package.json 文件。执行安装依赖包命令:
npm install express。编写应用代码,创建一个名为 app.js 的文件,添加如下内容,这段代码模拟扔骰子游戏,返回1-6之间的一个随机数。
/*app.js*/ const express = require('express'); const PORT = parseInt(process.env.PORT || '8080'); const app = express(); function getRandomNumber(min, max) { return Math.floor(Math.random() * (max - min + 1) + min); } app.get('/rolldice', (req, res) => { res.send(getRandomNumber(1, 6).toString()); }); app.listen(PORT, () => { console.log(`Listening for requests on http://localhost:${PORT}`); });此时应用已经编写完成,执行
node app.js命令即可运行应用,访问地址为http://localhost:8080/rolldice。
步骤二:导入 OpenTelemetry 相关依赖
安装 OpenTelemetry Node SDK 和自动插桩包。
auto-instrumentations-node会自动监控代码中常用的第三方库(如 Express),当这些库被调用时自动生成追踪数据。npm install @opentelemetry/sdk-node \ @opentelemetry/api \ @opentelemetry/auto-instrumentations-node \ @opentelemetry/sdk-trace-node \ @opentelemetry/exporter-trace-otlp-proto配置 OpenTelemetry:为了让 OpenTelemetry 能够自动收集应用程序的追踪数据并上报到阿里云可观测链路 OpenTelemetry 版,需要创建一个插桩配置文件。该文件负责初始化 SDK、配置数据导出器和启用自动插桩功能。 创建一个名为 instrumentation.js 的文件。
请将
${httpEndpoint}替换为HTTP接入点,请将${serviceName}替换为您的应用名。/*instrumentation.js*/ const opentelemetry = require('@opentelemetry/sdk-node'); const { getNodeAutoInstrumentations, } = require('@opentelemetry/auto-instrumentations-node'); const { OTLPTraceExporter, } = require('@opentelemetry/exporter-trace-otlp-proto'); const sdk = new opentelemetry.NodeSDK({ resource: resourceFromAttributes({ [ATTR_SERVICE_NAME]: '${serviceName}' }), traceExporter: new OTLPTraceExporter({ url: "${httpEndpoint}" }), instrumentations: [getNodeAutoInstrumentations()], }); sdk.start();
步骤三:手动创建 Span(可选)
虽然 auto-instrumentations-node 已经能够捕获大部分常见框架和库的调用,但在某些场景下您可能需要手动创建 Span 来获得更细粒度的追踪信息。手动创建 Span 时,需要做以下几件事情:
获取 Tracer: 在应用程序中任何需要手动编写代码创建 Span 的地方,都应该调用 getTracer 来获取一个 tracer。
创建和管理 Span: 在需要创建 Span 的代码中,调用 startActiveSpan 方法来创建一个 span,并使用 end 方法来结束 span。
在原有的app.js上进行修改,支持输出多次扔骰子的结果。以下代码展示了如何为每次掷骰子操作创建独立的 Span,以获得更细粒度的追踪信息。
/*app.js*/
const { trace } = require('@opentelemetry/api');
const express = require('express');
const tracer = trace.getTracer('demo', '0.1.0');
const PORT = parseInt(process.env.PORT || '8080');
const app = express();
function rollOnce(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
function rollTheDice(rolls, min, max) {
// 创建一个 span
return tracer.startActiveSpan('rollTheDice', (span) => {
const result = [];
for (let i = 0; i < rolls; i++) {
result.push(rollOnce(min, max));
}
// 确保结束 span
span.end();
return result;
});
}
app.get('/rolldice', (req, res) => {
const rolls = req.query.rolls ? parseInt(req.query.rolls.toString()) : NaN;
if (isNaN(rolls)) {
res
.status(400)
.send("Request parameter 'rolls' is missing or not a number.");
return;
}
res.send(JSON.stringify(rollTheDice(rolls, 1, 6)));
});
app.listen(PORT, () => {
console.log(`Listening for requests on http://localhost:${PORT}`);
});步骤四:运行应用
执行命令运行应用:node --require ./instrumentation.js app.js。
在控制台查看Trace
在可观测链路 OpenTelemetry 版控制台的应用列表页面选择目标应用,查看链路数据。