通过OpenTelemetry为应用埋点并上报链路数据至可观测链路 OpenTelemetry 版后,可观测链路 OpenTelemetry 版即可开始监控应用,您可以查看应用拓扑、调用链路、异常事务、慢事务和SQL分析等一系列监控数据。本文介绍如何使用OpenTelemetry对Node.js Express应用进行自动或手动埋点并上报数据。
前提条件
Node.js版本需要14及以上,其他版本请使用Jaeger接入。Jaeger接入操作,请参见通过Jaeger上报Node.js应用数据。
背景信息
OpenTelemetry提供了若干自动埋点插件,支持为常见框架自动创建Span,支持的框架列表如下,完整信息请参见OpenTelemetry官方文档。
示例Demo
示例代码仓库地址:opentelemetry-nodejs-demo
方法一:自动埋点(推荐)
下载运行项目所需的依赖。
cd auto-instrumentation npm init -y npm install express npm install axios
下载OpenTelemetry自动埋点所需的依赖。
npm install --save @opentelemetry/api npm install --save @opentelemetry/auto-instrumentations-node
编写应用代码。
以下代码是通过Express实现的简单应用示例:
"use strict"; const axios = require("axios").default; const express = require("express"); const app = express(); app.get("/", async (req, res) => { const result = await axios.get("http://localhost:7001/hello"); return res.status(201).send(result.data); }); app.get("/hello", async (req, res) => { console.log("hello world!") res.json({ code: 200, msg: "success" }); }); app.use(express.json()); app.listen(7001, () => { console.log("Listening on http://localhost:7001"); });
通过环境变量设置OpenTelemetry参数并运行应用。
请将
${httpEndpoint}
替换为前提条件中获取的HTTP接入点,请将${serviceName}
替换为您的应用名。export OTEL_TRACES_EXPORTER="otlp" export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="${httpEndpoint}" export OTEL_NODE_RESOURCE_DETECTORS="env,host,os" export OTEL_SERVICE_NAME="${serviceName}" export NODE_OPTIONS="--require @opentelemetry/auto-instrumentations-node/register" node main.js
说明有关OpenTelemetry环境变量的说明,请参见OpenTelemetry Node.js自动埋点配置。
访问应用。
通过以下命令访问应用,或者直接在浏览器中访问该地址,即可生成调用链并上报至可观测链路 OpenTelemetry 版。
curl localhost:7001/hello
方法二:手动埋点
在package.json中配置对OpenTelemetry的依赖。
"dependencies": { "@opentelemetry/api": "^1.0.4", "@opentelemetry/exporter-trace-otlp-grpc": "^0.27.0", "@opentelemetry/instrumentation": "^0.27.0", "@opentelemetry/instrumentation-express": "^0.27.0", "@opentelemetry/instrumentation-http": "^0.27.0", "@opentelemetry/resources": "^1.0.1", "@opentelemetry/sdk-trace-base": "^1.0.1", "@opentelemetry/sdk-trace-node": "^1.0.1" }
创建Provider。
const { Resource } = require("@opentelemetry/resources"); const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node"); const { SemanticResourceAttributes, } = require("@opentelemetry/semantic-conventions"); const provider = new NodeTracerProvider({ resource: new Resource({ [SemanticResourceAttributes.HOST_NAME]: require("os").hostname(), [SemanticResourceAttributes.SERVICE_NAME]: "opentelemetry-express", //opentelemetry-express可替换为任意名称。 }), });
通过Provider注册HTTP和Express框架,自动监测并拦截HTTP和Express。
说明如需监测其他框架下的Node.js应用,请参见OpenTelemetry官方文档。
const { registerInstrumentations } = require("@opentelemetry/instrumentation"); const { HttpInstrumentation } = require("@opentelemetry/instrumentation-http"); const { ExpressInstrumentation, } = require("@opentelemetry/instrumentation-express"); registerInstrumentations({ tracerProvider: provider, instrumentations: [new HttpInstrumentation(), ExpressInstrumentation], });
配置Exporter,导出数据到可观测链路 OpenTelemetry 版。
请将下面代码中的
<ENDPOINT>
和<AUTHENTICATION>
替换成前提条件中获取的Endpoint和Authentication。const metadata = new grpc.Metadata(); metadata.set("Authentication", "<AUTHENTICATION>"); const exporter = new OTLPTraceExporter({ url: "<ENDPOINT>", metadata }); provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); provider.register();
可选:添加自定义事件和属性。
说明OpenTelemetry API的使用方法,请参见OpenTelemetry官方文档。
const api = require("@opentelemetry/api"); const currentSpan = api.trace.getSpan(api.context.active()); currentSpan.addEvent("timestamp", { value: Date.now() }); currentSpan.setAttribute("tagKey-01", "tagValue-01");
在控制台查看Trace
在可观测链路 OpenTelemetry 版控制台的应用列表页面选择目标应用,查看链路数据。