链路追踪
Midway 采用社区最新的 open-telemetry 方案,其前身是知名的 OpenTracing 和 OpenCensus 规范,现阶段也是 CNCF 的孵化项目,社区许多知名的大公司如 Amazon,Dynatrace,Microsoft,Google,Datadog,Splunk 等都有使用。
open-telemetry 提供了通用的 Node.js 接入方案,以供应商无关的方式将数据接收,处理,导出,支持向一个或多个开源或者商业化的采集端发送可观测的数据(比如阿里云 SLS,Jaeger,Prometheus,Fluent Bit 等)。
Midway 提供了接入 open-telemetry 的 Node.js 方案,并提供了一些简单的使用 API。
信 息
open-telemetry 的 Tracing 部分当前 Node.js SDK 已经 Release 1.0.0,可以在生产使用,Metrics 部分未正式发布,我们依旧在跟进(编码)中。
使用须知
open-telemetry 基于 Node.js 的 Async_Hooks 的稳定 API 实现,经过我们的测试,在最新的 Node.js v14/v16 性能影响已经很小,可以在生产使用,在 v12 情况下虽然可以使用,但是性能依旧有不小的损失,请尽可能在 Node.js >= v14 的版本下使用。
安装基础依赖
# Node.js 的 api 抽象
$ npm install --save @opentelemetry/api
# Node.js 的 api 实现
$ npm install --save @opentelemetry/sdk-node
# 常用 Node.js 模块的埋点实现
$ npm install --save @opentelemetry/auto-instrumentations-node
# jaeger 输出器
$ npm install --save @opentelemetry/exporter-jaeger
以上的包均为 open-telemetry 的官方包。
启用 open-telemetry
open-telemetry 的模块请尽可能加在代码的最开始(比框架还要早),所以在不同场景中,我们有不同的添加方式。
使用 bootstrap 部署
如果使用 bootstrap.js
部署,你可以加在 bootstrap.js
的最顶部,示例代码如下。
const process = require('process');
const { NodeSDK, node, resources } = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions')
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger')
// Midway 启动文件
const { Bootstrap } = require('@midwayjs/bootstrap');
// https://www.npmjs.com/package/@opentelemetry/exporter-jaeger
const tracerAgentHost = process.env['TRACER_AGENT_HOST'] || '127.0.0.1'
const jaegerExporter = new JaegerExporter({
host: tracerAgentHost,
});
// 初始化一个 open-telemetry 的 SDK
const sdk = new NodeSDK({
// 设置追踪服务名
resource: new resources.Resource({
[SemanticResourceAttributes.SERVICE_NAME]: 'my-app',
}),
// 配置当前的导出方式,比如这里配置了一个输出到控制台的,也可以配置其他的 Exporter,比如 Jaeger
traceExporter: new node.ConsoleSpanExporter(),
// 配置当前导出为 jaeger
// traceExporter: jaegerExporter,
// 这里配置了默认自带的一些监控模块,比如 http 模块等
// 若初始化时间很长,可注销此行,单独配置需要的 instrumentation 条目
instrumentations: [getNodeAutoInstrumentations()]
});
// 初始化 SDK,成功启动之后,再启动 Midway 框架
sdk.start()
// 在进程关闭时,同时关闭数据采集
process.on('SIGTERM', () => {
sdk.shutdown()
.then(() => console.log('Tracing terminated'))
.catch((error) => console.log('Error terminating tracing', error))
.finally(() => process.exit(0));
});
Bootstrap
.configure(/**/)
.run();