使用仪表库

如何为应用依赖的库进行仪表化

当你开发一个应用时,你会使用第三方的库和框架来加快你的工作速度,不必重新造轮子。如果你现在用 OpenTelemetry 对你的应用进行仪表化,你不希望再花时间手动为这些库和框架添加追踪、日志和指标。幸运的是,你也不必重新造轮子:库可能本身就提供了 OpenTelemetry 支持,或者你可以使用一个仪表库为库或框架生成遥测数据。

如果你正在对一个应用进行仪表化,你可以在这个页面上学习如何使用本地支持证书化的库和仪表库来处理它的依赖关系。

如果你想仪表化一个库,你可以在这个页面上学习如果本地支持仪表化你自己的库,或者如果没有可用的仪表库,如何为第三方库创建一个仪表库。

使用本地支持的库

如果一个库已经默认支持 OpenTelemetry,你添加并设置了 OpenTelemetry SDK 和你的应用之后,你就可以获得从该库发出的追踪、指标和日志。

这个库可能为仪表化提供了一些额外的配置。请查阅该库的文档以了解更多信息。

使用仪表库

如果一个库没有默认支持 OpenTelemetry,你可以使用仪表库为一个库或框架生成遥测数据。

例如,Express 的仪表库将根据传入的 HTTP 请求自动创建跨度

设置

每个仪表库都是一个 NPM 包。例如,这是如何安装instrumentation-expressinstrumentation-http仪表库来仪表化传入和传出的 HTTP 流量的示例:

npm install --save @opentelemetry/instrumentation-http @opentelemetry/instrumentation-express

OpenTelemetry JavaScript 还定义了元包auto-instrumentation-nodeauto-instrumentation-web,将所有基于 Node.js 或基于 web 的仪表库捆绑到一个单独的包中。这是一种方便的方式,以最少的努力为所有的库添加自动生成的遥测数据:

npm install --save @opentelemetry/auto-instrumentations-node
npm install --save @opentelemetry/auto-instrumentations-web

请注意,使用这些元包会增加你的依赖图的大小。如果你确切地知道你需要哪些仪表库,那么请使用单独的仪表库包。

注册

在安装需要的仪表库之后,将它们注册到用于 Node.js 的 OpenTelemetry SDK 中。如果你按照入门指南操作,你已经使用了元包。如果你按照to initialize the SDK for manual instrumentation中的说明来手动仪表化你的 SDK,那么请按照以下方式更新你的 instrumentation.ts(或 instrumentation.js):

/*instrumentation.ts*/
...
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';

const sdk = new NodeSDK({
  ...
  // 这会注册所有的仪表库
  instrumentations: [getNodeAutoInstrumentations()]
});

sdk.start()
/*instrumentation.js*/
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');

const sdk = new NodeSDK({
  ...
  // 这会注册所有的仪表库
  instrumentations: [getNodeAutoInstrumentations()]
});

如果要禁用单个仪表库,你可以应用以下更改:

/*instrumentation.ts*/
...
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';

const sdk = new NodeSDK({
  ...
  // 这会注册所有的仪表库
  instrumentations: [
    getNodeAutoInstrumentations({
      '@opentelemetry/instrumentation-fs': {
        enabled: false,
      },
    }),
  ],
});

sdk.start()
/*instrumentation.js*/
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');

const sdk = new NodeSDK({
  ...
  // 这会注册所有的仪表库
  instrumentations: [
    getNodeAutoInstrumentations({
      '@opentelemetry/instrumentation-fs': {
        enabled: false,
      },
    }),
  ],
});

如果只加载单个仪表库,请使用你需要的列表替换[getNodeAutoInstrumentations()]

/*instrumentation.ts*/
...
import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";

const sdk = new NodeSDK({
  ...
  instrumentations: [
    // Express 仪表化期望 HTTP 层进行仪表化
    new HttpInstrumentation(),
    new ExpressInstrumentation(),
  ]
});

sdk.start()
/*instrumentation.js*/
const { HttpInstrumentation } = require("@opentelemetry/instrumentation-http");
const { ExpressInstrumentation } = require("@opentelemetry/instrumentation-express");

const sdk = new NodeSDK({
  ...
  instrumentations: [
    // Express 仪表化期望 HTTP 层进行仪表化
    new HttpInstrumentation(),
    new ExpressInstrumentation(),
  ]
});

配置

某些仪表库提供额外的配置选项。

例如,Express 仪表库提供了忽略指定中间件或将自动创建的跨度丰富为请求钩子的方法:

import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
import {
  ExpressInstrumentation,
  ExpressLayerType,
} from '@opentelemetry/instrumentation-express';

const expressInstrumentation = new ExpressInstrumentation({
  requestHook: function (span: Span, info: ExpressRequestInfo) {
    if (info.layerType === ExpressLayerType.REQUEST_HANDLER) {
      span.setAttribute([SemanticAttributes.HTTP_METHOD], info.request.method);
      span.setAttribute([SemanticAttributes.HTTP_URL], info.request.baseUrl);
    }
  },
});
/*instrumentation.js*/
const { SemanticAttributes } = require('@opentelemetry/semantic-conventions');
const {
  ExpressInstrumentation,
  ExpressLayerType,
} = require('@opentelemetry/instrumentation-express');

const expressInstrumentation = new ExpressInstrumentation({
  requestHook: function (span, info) {
    if (info.layerType === ExpressLayerType.REQUEST_HANDLER) {
      span.setAttribute([SemanticAttributes.HTTP_METHOD], info.request.method);
      span.setAttribute([SemanticAttributes.HTTP_URL], info.request.baseUrl);
    }
  },
});

你需要参考每个仪表库的文档来进行高级配置。

可用的仪表库

你可以在注册表中找到可用的仪表库列表。

本地仪表化一个库

如果你想为你的库添加本地仪表化,请查看以下文档:

创建一个仪表库

虽然直接为应用程序提供观测性是首选的方式,但并不总是可能或者是所期望的。在这些情况下,你可以创建一个仪表库,它会使用诸如包装接口、订阅特定于库的回调或将现有的遥测转换为 OpenTelemetry 模型的机制来注入仪表调用。

要创建这样的库,请遵循用于 Node.js 和浏览器的仪表化实现指南

最后修改 December 13, 2023: improve glossary translation (46f8201b)