导出器

处理并导出遥测数据

In order to visualize and analyze your telemetry, you will need to export your data to an OpenTelemetry Collector or a backend such as Jaeger, Zipkin, Prometheus or a vendor-specific one.

As part of OpenTelemetry JavaScript you will find many exporters being available. Among them, the OpenTelemetry Protocol (OTLP) exporters provide the best experience for you as an end-user, since it is a general-purpose telemetry data delivery protocol designed in the scope of the OpenTelemetry project.

To learn more about the OTLP protocol, you can read the OTLP Specification.

Below you will find some introductions on how to set up exporters for OTLP and other common protocols in your code.

OTLP 终端节点

若要将追踪数据发送到 OTLP 终端节点(如收集器或 Jaeger),您将需要使用一个导出器包,比如 @opentelemetry/exporter-trace-otlp-proto

npm install --save @opentelemetry/exporter-trace-otlp-proto \
  @opentelemetry/exporter-metrics-otlp-proto

然后,配置导出器指向 OTLP 终端节点。例如,您可以像下面这样更新来自入门指南instrumentation.ts|js

/*instrumentation.ts*/
import * as opentelemetry from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-proto';
import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';

const sdk = new opentelemetry.NodeSDK({
  traceExporter: new OTLPTraceExporter({
    // 可选项 - 默认 url 为 http://localhost:4318/v1/traces
    url: '<your-otlp-endpoint>/v1/traces',
    // 可选项 - 每个请求发送时附带的自定义头集合,默认为空
    headers: {},
  }),
  metricReader: new PeriodicExportingMetricReader({
    exporter: new OTLPMetricExporter({
      url: '<your-otlp-endpoint>/v1/metrics', // 可选项,可以省略,默认为 http://localhost:4318/v1/metrics
      headers: {}, // 包含自定义头的可选对象,每个请求都会带上这些头
    }),
  }),
  instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
/*instrumentation.js*/
const opentelemetry = require('@opentelemetry/sdk-node');
const {
  getNodeAutoInstrumentations,
} = require('@opentelemetry/auto-instrumentations-node');
const {
  OTLPTraceExporter,
} = require('@opentelemetry/exporter-trace-otlp-proto');
const {
  OTLPMetricExporter,
} = require('@opentelemetry/exporter-metrics-otlp-proto');
const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics');

const sdk = new opentelemetry.NodeSDK({
  traceExporter: new OTLPTraceExporter({
    // 可选项 - 默认 url 为 http://localhost:4318/v1/traces
    url: '<your-otlp-endpoint>/v1/traces',
    // 可选项 - 每个请求发送时附带的自定义头集合,默认为空
    headers: {},
  }),
  metricReader: new PeriodicExportingMetricReader({
    exporter: new OTLPMetricExporter({
      url: '<your-otlp-endpoint>/v1/metrics', // 可选项,可以省略,默认为 http://localhost:4318/v1/metrics
      headers: {}, // 包含自定义头的可选对象,每个请求都会带上这些头
      concurrencyLimit: 1, // 可选项,限制并发请求数的最大数量
    }),
  }),
  instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();

要快速尝试 OTLPTraceExporter,您可以在 Docker 容器中运行 Jaeger:

docker run -d --name jaeger \
  -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
  -e COLLECTOR_OTLP_ENABLED=true \
  -p 6831:6831/udp \
  -p 6832:6832/udp \
  -p 5778:5778 \
  -p 16686:16686 \
  -p 4317:4317 \
  -p 4318:4318 \
  -p 14250:14250 \
  -p 14268:14268 \
  -p 14269:14269 \
  -p 9411:9411 \
  jaegertracing/all-in-one:latest

使用 WebTracer

当您在基于浏览器的应用程序中使用 OTLP 导出器时,需要注意以下事项:

  1. 不支持使用 gRPC 进行导出
  2. 您的网站的内容安全策略(CSP)可能会阻止导出
  3. 跨源资源共享(CORS)标头可能不允许发送导出
  4. 您可能需要将收集器公开到公共互联网

下面是使用正确的导出器、配置 CSP 和 CORS 标头以及在公开收集器时需要注意的预防措施的说明。

使用 HTTP/JSON 或 HTTP/protobuf 的 OTLP 导出器

OpenTelemetry 收集器导出器使用 gRPC 仅适用于 Node.js,因此您只能使用 OpenTelemetry 收集器导出器使用 HTTP/JSONOpenTelemetry 收集器导出器使用 HTTP/protobuf

确保导出器的接收端(收集器或可观察性后端)接受 http/json,如果使用 OpenTelemetry 收集器导出器使用 HTTP/JSON,则将数据导出到正确的终端节点,端口设置为 4318。

配置 CSP

如果您的网站使用了内容安全策略(CSP),请确保包括您的 OTLP 终端节点域。如果您的收集器终端节点是 https://collector.example.com:4318/v1/traces,添加以下指令:

connect-src collector.example.com:4318/v1/traces

如果您的 CSP 不包括 OTLP 终端节点,您将会看到一个错误消息,指出请求违反了 CSP 指令。

配置 CORS 标头

如果您的网站和收集器托管在不同的来源,您的浏览器可能会阻止向收集器发送的请求。您需要为跨源资源共享(CORS)配置特殊的标头。

OpenTelemetry 收集器提供了一种特性,可供基于 HTTP 的接收器添加所需的标头,以允许接收器接受来自 Web 浏览器的追踪:

receivers:
  otlp:
    protocols:
      http:
        include_metadata: true
        cors:
          allowed_origins:
            - https://foo.bar.com
            - https://*.test.com
          allowed_headers:
            - Example-Header
          max_age: 7200

安全公开收集器

为了接收来自 Web 应用程序的遥测数据,您需要允许最终用户的浏览器向收集器发送数据。如果您的 Web 应用程序从公共互联网可访问,您还需要使您的收集器对所有用户可访问。

建议不要直接公开您的收集器,而是将反向代理(NGINX、Apache HTTP Server 等)放在它的前面。反向代理可以负责 SSL 卸载、设置正确的 CORS 标头和许多其他面向 Web 应用程序的特性。

以下是流行的 NGINX Web 服务器的配置示例:

server {
    listen 80 default_server;
    server_name _;
    location / {
        # 处理预检请求
        if ($request_method = 'OPTIONS') {
             add_header 'Access-Control-Max-Age' 1728000;
             add_header 'Access-Control-Allow-Origin' 'name.of.your.website.example.com' always;
             add_header 'Access-Control-Allow-Headers' 'Accept,Accept-Language,Content-Language,Content-Type' always;
             add_header 'Access-Control-Allow-Credentials' 'true' always;
             add_header 'Content-Type' 'text/plain charset=UTF-8';
             add_header 'Content-Length' 0;
             return 204;
        }

        add_header 'Access-Control-Allow-Origin' 'name.of.your.website.example.com' always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        add_header 'Access-Control-Allow-Headers' 'Accept,Accept-Language,Content-Language,Content-Type' always;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://collector:4318;
    }
}

Zipkin

要尽快设置 Zipkin,请在 Docker 容器中运行它:

docker run --rm -d -p 9411:9411 --name zipkin openzipkin/zipkin

将导出器包安装为应用程序的依赖项:

npm install --save @opentelemetry/exporter-zipkin

更新您的 OpenTelemetry 配置以使用导出器并将数据发送到 Zipkin 后端:

import { ZipkinExporter } from '@opentelemetry/exporter-zipkin';
import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';

provider.addSpanProcessor(new BatchSpanProcessor(new ZipkinExporter()));
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');
const { BatchSpanProcessor } = require('@opentelemetry/sdk-trace-base');

provider.addSpanProcessor(new BatchSpanProcessor(new ZipkinExporter()));
最后修改 December 13, 2023: improve glossary translation (46f8201b)