导出器
将遥测数据发送到 OpenTelemetry Collector,以确保其被正确导出。 在生产环境中使用 Collector 是最佳实践。若要可视化你的遥测数据,可将其导出到后端系统,例如 Jaeger、Zipkin、 Prometheus,或某个特定厂商的后端。
可用的导出器
镜像仓库中包含一份 JavaScript 可用导出器的列表。
在所有导出器中,OpenTelemetry 协议 (OTLP) 导出器是以 OpenTelemetry 数据模型为基础设计的, 能够无信息丢失地输出 OTel 数据。此外,许多处理遥测数据的工具都支持 OTLP (例如 Prometheus、Jaeger 和大多数厂商),在你需要时为你提供高度的灵活性。 若要了解更多关于 OTLP 的信息,请参阅 OTLP 规范。
本页面介绍了主要的 OpenTelemetry JavaScript 导出器以及如何进行配置。
OTLP
Collector 设置
如果你已经配置好 OTLP Collector 或后端,可以跳过此部分, 直接设置应用的 OTLP 导出器依赖。
为测试和验证你的 OTLP 导出器,你可以运行一个 Docker 容器形式的 Collector,将遥测数据直接输出到控制台。
在一个空目录下创建名为 collector-config.yaml 的文件,并添加以下内容:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
exporters:
debug:
verbosity: detailed
service:
pipelines:
traces:
receivers: [otlp]
exporters: [debug]
metrics:
receivers: [otlp]
exporters: [debug]
logs:
receivers: [otlp]
exporters: [debug]
然后运行以下命令,在 Docker 容器中启动 Collector:
docker run -p 4317:4317 -p 4318:4318 --rm -v $(pwd)/collector-config.yaml:/etc/otelcol/config.yaml otel/opentelemetry-collector
现在,这个 Collector 已能通过 OTLP 接收遥测数据。 之后你可能需要配置 Collector,将遥测数据发送到你的可观测性后端。
依赖项
若你希望将遥测数据发送至 OTLP 端点(比如 OpenTelemetry 采集器、Jaeger 或 Prometheus),你可以从三种不同的传输协议中选择一种来传输数据:
开始前,先安装相应的导出器包作为项目的依赖项:
npm install --save @opentelemetry/exporter-trace-otlp-proto \
@opentelemetry/exporter-metrics-otlp-proto
npm install --save @opentelemetry/exporter-trace-otlp-http \
@opentelemetry/exporter-metrics-otlp-http
npm install --save @opentelemetry/exporter-trace-otlp-grpc \
@opentelemetry/exporter-metrics-otlp-grpc
Node.js 环境使用指南
接下来,配置导出器以指向 OTLP 端点。
例如,你可以更新入门指南中的 instrumentation.ts(如果使用 JavaScript 则为 instrumentation.js)文件,
如下所示,通过 OTLP(http/protobuf)导出链路和指标数据:
/*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', // URL 是可选项并且可以省略,默认值为 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', // URL 是可选项并且可以省略,默认值为 http://localhost:4318/v1/metrics
headers: {}, // 一个可选对象,包含了要随每个请求一同发送的自定义请求头。
concurrencyLimit: 1, // 一个用于限制待处理请求数量的可选阈值。
}),
}),
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
浏览器环境使用指南
当你在基于浏览器的应用程序中使用 OTLP 导出器时,你需要注意以下几点:
你可以在下方找到选用合适导出器的操作指南,去配置内容安全策略(CSP)与跨域资源共享(CORS)响应头,以及暴露采集器时需采取的防范措施。
使用 OTLP 导出器结合 HTTP/JSON 或 HTTP/protobuf 协议
基于 gRPC 协议的 OpenTelemetry 采集器导出器仅适用于 Node.js, 因此你只能使用基于 HTTP/JSON 协议的 OpenTelemetry 采集器导出器或基于 HTTP/protobuf 协议的 OpenTelemetry 采集器导出器。
如果你使用的是基于 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 协议的接收器提供了一项功能, 可自动添加所需的请求头,使接收器能够接收来自网页浏览器链路数据:
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 服务器等)。 反向代理可负责 SSL 卸载、配置正确的跨域资源共享(CORS)响应头,以及实现诸多针对 Web 应用的专属功能。
下面是流行的 NGINX Web 服务器的配置示例,供你参考使用:
server {
listen 80 default_server;
server_name _;
location / {
# Take care of preflight requests
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;
}
}
控制台
要调试你的插桩代码,或在本地开发环境中查看数值,你可以使用将遥测数据写入控制台(标准输出)的导出器。
如果你遵循了入门指南或手动插桩指南, 你已经安装了控制台导出器。
ConsoleSpanExporter 包含在 @opentelemetry/sdk-trace-node
包中,而 ConsoleMetricExporter 包含在 @opentelemetry/sdk-metrics
包中。
Jaeger
后端设置
Jaeger 原生支持 OTLP,用于接收链路数据。 你可以通过运行一个 Docker 容器来启动 Jaeger,其 UI 默认在端口 16686 上可访问,并在端口 4317 和 4318 上启用 OTLP:
docker run --rm \
-e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
-p 16686:16686 \
-p 4317:4317 \
-p 4318:4318 \
-p 9411:9411 \
jaegertracing/all-in-one:latest
使用方法
现在,按照说明设置 OTLP 导出器。
Prometheus
要将你的指标数据发送到 Prometheus,
你可以选择启用 Prometheus 的 OTLP 接收器并且使用
OTLP 导出器,或者使用 Prometheus 导出器,这是一种 MetricReader,
他启动一个 HTTP 服务器,根据请求收集指标并将数据序列化为 Prometheus 文本格式。
后端设置
如果你已经设置了 Prometheus 或兼容 Prometheus 的后端,可以跳过本节,直接为你的应用设置 Prometheus 或者 OTLP 导出器依赖。
你可以按照以下步骤在 Docker 容器中运行 Prometheus,并通过端口 9090 访问:
创建一个名为 prometheus.yml 的文件,并将以下内容写入文件:
scrape_configs:
- job_name: dice-service
scrape_interval: 5s
static_configs:
- targets: [host.docker.internal:9464]
使用以下命令在 Docker 容器中运行 Prometheus,UI 可通过端口 9090 访问:
docker run --rm -v ${PWD}/prometheus.yml:/prometheus/prometheus.yml -p 9090:9090 prom/prometheus --enable-feature=otlp-write-receive
当使用 Prometheus 的 OTLP 接收器时,确保在应用中设置 OTLP 端点为
http://localhost:9090/api/v1/otlp。
并非所有的 Docker 环境都支持 host.docker.internal。在某些情况下,你可能需要将
host.docker.internal 替换为 localhost 或你机器的 IP 地址。
Prometheus 依赖项
将导出器包作为项目依赖安装到你的应用中:
npm install --save @opentelemetry/exporter-prometheus
将你的 OpenTelemetry 配置更新为使用该导出器,并将数据发送到 Prometheus 后端:
import * as opentelemetry from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';
const sdk = new opentelemetry.NodeSDK({
metricReader: new PrometheusExporter({
port: 9464, // 可选 - 默认值为 9464
}),
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
const opentelemetry = require('@opentelemetry/sdk-node');
const {
getNodeAutoInstrumentations,
} = require('@opentelemetry/auto-instrumentations-node');
const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus');
const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics');
const sdk = new opentelemetry.NodeSDK({
metricReader: new PrometheusExporter({
port: 9464, // 可选 - 默认值为 9464
}),
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
通过上述配置,你可以在 http://localhost:9464/metrics 访问你的指标数据。 Prometheus 或 OpenTelemetry 采集器中的 Prometheus 接收器可以从该端点采集指标数据。
Zipkin
后端设置
如果你已经设置了 Zipkin 或兼容 Zipkin 的后端,可以跳过本节并直接为你的应用设置 Zipkin 导出器依赖。
你可以通过执行以下命令,在 Docker 容器中运行 Zipkin:
docker run --rm -d -p 9411:9411 --name zipkin openzipkin/zipkin
Zipkin 依赖项
若要将链路数据发送至 Zipkin,你可以使用 ZipkinExporter 导出器。
安装导出器包作为项目依赖安装到你的应用中:
npm install --save @opentelemetry/exporter-zipkin
将你的 OpenTelemetry 配置更新为使用该导出器,并将数据发送到 Zipkin 后端:
import * as opentelemetry from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { ZipkinExporter } from '@opentelemetry/exporter-zipkin';
const sdk = new opentelemetry.NodeSDK({
traceExporter: new ZipkinExporter({}),
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
const opentelemetry = require('@opentelemetry/sdk-node');
const {
getNodeAutoInstrumentations,
} = require('@opentelemetry/auto-instrumentations-node');
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');
const sdk = new opentelemetry.NodeSDK({
traceExporter: new ZipkinExporter({}),
instrumentations: [getNodeAutoInstrumentations()],
});
自定义导出器
最后,你还可以编写自己的导出器。有关更多信息,请参见 API 文档中的 SpanExporter 接口.
批量处理 Span 和日志记录
OpenTelemetry SDK 提供了一组默认的 Span 和日志记录处理器, 允许你选择按单条(simple)或按批量(batch)方式导出一个或多个 Span。 推荐使用批量处理,但如果你不想批量处理 Span 或日志记录,可以使用 simple 处理器,方法如下:
/*instrumentation.ts*/
import * as opentelemetry from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
const sdk = new NodeSDK({
spanProcessors: [new SimpleSpanProcessor(exporter)],
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
/*instrumentation.js*/
const opentelemetry = require('@opentelemetry/sdk-node');
const {
getNodeAutoInstrumentations,
} = require('@opentelemetry/auto-instrumentations-node');
const sdk = new opentelemetry.NodeSDK({
spanProcessors: [new SimpleSpanProcessor(exporter)],
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
意见反馈
这个页面对您有帮助吗?
Thank you. Your feedback is appreciated!
Please let us know how we can improve this page. Your feedback is appreciated!