|
| 1 | +--- |
| 2 | +title: 导出器 |
| 3 | +default_lang_commit: f49ec57e5a0ec766b07c7c8e8974c83531620af3 |
| 4 | +weight: 50 |
| 5 | +description: 处理并导出你的遥测数据 |
| 6 | +--- |
| 7 | + |
| 8 | +{{% docs/languages/exporters/intro %}} |
| 9 | + |
| 10 | +## 依赖项 {#otlp-dependencies} |
| 11 | + |
| 12 | +若你希望将遥测数据发送至 OTLP 端点(比如 [OpenTelemetry 采集器](#collector-setup)、[Jaeger](#jaeger) 或 [Prometheus](#prometheus)),你可以从三种不同的传输协议中选择一种来传输数据: |
| 13 | + |
| 14 | +- [HTTP/protobuf](https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-proto) |
| 15 | +- [HTTP/JSON](https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-http) |
| 16 | +- [gRPC](https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-grpc) |
| 17 | + |
| 18 | +开始前,先安装相应的导出器包作为项目的依赖项: |
| 19 | + |
| 20 | +{{< tabpane text=true >}} {{% tab "HTTP/Proto" %}} |
| 21 | + |
| 22 | +```shell |
| 23 | +npm install --save @opentelemetry/exporter-trace-otlp-proto \ |
| 24 | + @opentelemetry/exporter-metrics-otlp-proto |
| 25 | +``` |
| 26 | + |
| 27 | +{{% /tab %}} {{% tab "HTTP/JSON" %}} |
| 28 | + |
| 29 | +```shell |
| 30 | +npm install --save @opentelemetry/exporter-trace-otlp-http \ |
| 31 | + @opentelemetry/exporter-metrics-otlp-http |
| 32 | +``` |
| 33 | + |
| 34 | +{{% /tab %}} {{% tab gRPC %}} |
| 35 | + |
| 36 | +```shell |
| 37 | +npm install --save @opentelemetry/exporter-trace-otlp-grpc \ |
| 38 | + @opentelemetry/exporter-metrics-otlp-grpc |
| 39 | +``` |
| 40 | + |
| 41 | +{{% /tab %}} {{< /tabpane >}} |
| 42 | + |
| 43 | +## Node.js 环境使用指南 {#otlp-usage-nodejs} |
| 44 | + |
| 45 | +接下来,配置导出器以指向 OTLP 端点。 |
| 46 | +例如,你可以更新[入门指南](/docs/languages/js/getting-started/nodejs/)中的 `instrumentation.ts`(如果使用 JavaScript 则为 `instrumentation.js`)文件, |
| 47 | +如下所示,通过 OTLP(`http/protobuf`)导出链路和指标数据: |
| 48 | + |
| 49 | +{{< tabpane text=true >}} {{% tab TypeScript %}} |
| 50 | + |
| 51 | +```ts |
| 52 | +/*instrumentation.ts*/ |
| 53 | +import * as opentelemetry from '@opentelemetry/sdk-node'; |
| 54 | +import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; |
| 55 | +import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto'; |
| 56 | +import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-proto'; |
| 57 | +import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'; |
| 58 | + |
| 59 | +const sdk = new opentelemetry.NodeSDK({ |
| 60 | + traceExporter: new OTLPTraceExporter({ |
| 61 | + // 可选 - 默认 URL 为 http://localhost:4318/v1/traces |
| 62 | + url: '<your-otlp-endpoint>/v1/traces', |
| 63 | + // 可选 - 每个请求要发送的自定义头信息,默认为空 |
| 64 | + headers: {}, |
| 65 | + }), |
| 66 | + metricReader: new PeriodicExportingMetricReader({ |
| 67 | + exporter: new OTLPMetricExporter({ |
| 68 | + url: '<your-otlp-endpoint>/v1/metrics', // URL 是可选项并且可以省略,默认值为 http://localhost:4318/v1/metrics |
| 69 | + headers: {}, // 一个可选对象,包含了要随每个请求一同发送的自定义请求头。 |
| 70 | + }), |
| 71 | + }), |
| 72 | + instrumentations: [getNodeAutoInstrumentations()], |
| 73 | +}); |
| 74 | +sdk.start(); |
| 75 | +``` |
| 76 | + |
| 77 | +{{% /tab %}} {{% tab JavaScript %}} |
| 78 | + |
| 79 | +```js |
| 80 | +/*instrumentation.js*/ |
| 81 | +const opentelemetry = require('@opentelemetry/sdk-node'); |
| 82 | +const { |
| 83 | + getNodeAutoInstrumentations, |
| 84 | +} = require('@opentelemetry/auto-instrumentations-node'); |
| 85 | +const { |
| 86 | + OTLPTraceExporter, |
| 87 | +} = require('@opentelemetry/exporter-trace-otlp-proto'); |
| 88 | +const { |
| 89 | + OTLPMetricExporter, |
| 90 | +} = require('@opentelemetry/exporter-metrics-otlp-proto'); |
| 91 | +const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics'); |
| 92 | + |
| 93 | +const sdk = new opentelemetry.NodeSDK({ |
| 94 | + traceExporter: new OTLPTraceExporter({ |
| 95 | + // 可选 - 默认 URL 为 http://localhost:4318/v1/traces |
| 96 | + url: '<your-otlp-endpoint>/v1/traces', |
| 97 | + // 可选 - 每个请求要发送的自定义头信息,默认为空 |
| 98 | + headers: {}, |
| 99 | + }), |
| 100 | + metricReader: new PeriodicExportingMetricReader({ |
| 101 | + exporter: new OTLPMetricExporter({ |
| 102 | + url: '<your-otlp-endpoint>/v1/metrics', // URL 是可选项并且可以省略,默认值为 http://localhost:4318/v1/metrics |
| 103 | + headers: {}, // 一个可选对象,包含了要随每个请求一同发送的自定义请求头。 |
| 104 | + concurrencyLimit: 1, // 一个用于限制待处理请求数量的可选阈值。 |
| 105 | + }), |
| 106 | + }), |
| 107 | + instrumentations: [getNodeAutoInstrumentations()], |
| 108 | +}); |
| 109 | +sdk.start(); |
| 110 | +``` |
| 111 | + |
| 112 | +{{% /tab %}} {{< /tabpane >}} |
| 113 | + |
| 114 | +## 浏览器环境使用指南 {#usage-in-the-browser} |
| 115 | + |
| 116 | +当你在基于浏览器的应用程序中使用 OTLP 导出器时,你需要注意以下几点: |
| 117 | + |
| 118 | +1. 不支持使用 gRPC 进行导出 |
| 119 | +2. 你的网站的[内容安全策略][Content Security Policies](CSP)可能会阻止遥测数据的导出操作。 |
| 120 | +3. [跨域资源共享][Cross-Origin Resource Sharing](CORS)响应头可能不允许发送导出数据 |
| 121 | +4. 你可能需要将采集器暴露到公共互联网 |
| 122 | + |
| 123 | +你可以在下方找到选用合适导出器的操作指南,去配置内容安全策略(CSP)与跨域资源共享(CORS)响应头,以及暴露采集器时需采取的防范措施。 |
| 124 | + |
| 125 | +### 使用 OTLP 导出器结合 HTTP/JSON 或 HTTP/protobuf 协议 {#use-otlp-exporter-with-http-json-or-http-protobuf} |
| 126 | + |
| 127 | +[基于 gRPC 协议的 OpenTelemetry 采集器导出器][OpenTelemetry Collector Exporter with gRPC]仅适用于 Node.js, |
| 128 | +因此你只能使用[基于 HTTP/JSON 协议的 OpenTelemetry 采集器导出器][OpenTelemetry Collector Exporter with HTTP/JSON]或[基于 HTTP/protobuf 协议的 OpenTelemetry 采集器导出器][OpenTelemetry Collector Exporter with HTTP/protobuf]。 |
| 129 | + |
| 130 | +如果你使用的是[基于 HTTP/JSON 协议的 OpenTelemetry 采集器导出器][OpenTelemetry Collector Exporter with HTTP/JSON], |
| 131 | +请确保导出器的接收端(采集器或可观测性后端)支持 `http/json`,并且你将数据导出到正确的端点,端口设置为 4318。 |
| 132 | + |
| 133 | +### 配置 CSP {#configure-csps} |
| 134 | + |
| 135 | +如果你的网站使用了内容安全策略(CSP),请确保包含了 OTLP 端点的域名。 |
| 136 | +如果你的采集器端点是 `https://collector.example.com:4318/v1/traces`,请添加以下指令: |
| 137 | + |
| 138 | +```text |
| 139 | +connect-src collector.example.com:4318/v1/traces |
| 140 | +``` |
| 141 | + |
| 142 | +如果你的 CSP 未包含 OTLP 端点,你会看到一条错误消息,指出对端点的请求违反了 CSP 指令。 |
| 143 | + |
| 144 | +### 配置 CORS 响应头 {#configure-cors-headers} |
| 145 | + |
| 146 | +如果你的网站和采集器托管在不同的域名下,你的浏览器可能会阻止向采集器发送请求。 |
| 147 | +你需要为[跨域资源共享][Cross-Origin Resource Sharing](CORS)配置特殊的响应头。 |
| 148 | + |
| 149 | +OpenTelemetry 采集器为基于 HTTP 协议的接收器提供了[一项功能][a feature], |
| 150 | +可自动添加所需的请求头,使接收器能够接收来自网页浏览器链路数据: |
| 151 | + |
| 152 | +```yaml |
| 153 | +receivers: |
| 154 | + otlp: |
| 155 | + protocols: |
| 156 | + http: |
| 157 | + include_metadata: true |
| 158 | + cors: |
| 159 | + allowed_origins: |
| 160 | + - https://foo.bar.com |
| 161 | + - https://*.test.com |
| 162 | + allowed_headers: |
| 163 | + - Example-Header |
| 164 | + max_age: 7200 |
| 165 | +``` |
| 166 | +
|
| 167 | +### 安全地暴露你的采集器 {#securely-expose-your-collector} |
| 168 | +
|
| 169 | +若要从 Web 应用接收遥测数据,你需要允许终端用户的浏览器向采集器发送数据。 |
| 170 | +若你的 Web 应用可从公共互联网访问,那么你也必须将采集器设置为对所有用户开放访问。 |
| 171 | +
|
| 172 | +建议你不要直接暴露采集器,而是在其前端部署反向代理(如 NGINX、Apache HTTP 服务器等)。 |
| 173 | +反向代理可负责 SSL 卸载、配置正确的跨域资源共享(CORS)响应头,以及实现诸多针对 Web 应用的专属功能。 |
| 174 | +
|
| 175 | +下面是流行的 NGINX Web 服务器的配置示例,供你参考使用: |
| 176 | +
|
| 177 | +```nginx |
| 178 | +server { |
| 179 | + listen 80 default_server; |
| 180 | + server_name _; |
| 181 | + location / { |
| 182 | + # Take care of preflight requests |
| 183 | + if ($request_method = 'OPTIONS') { |
| 184 | + add_header 'Access-Control-Max-Age' 1728000; |
| 185 | + add_header 'Access-Control-Allow-Origin' 'name.of.your.website.example.com' always; |
| 186 | + add_header 'Access-Control-Allow-Headers' 'Accept,Accept-Language,Content-Language,Content-Type' always; |
| 187 | + add_header 'Access-Control-Allow-Credentials' 'true' always; |
| 188 | + add_header 'Content-Type' 'text/plain charset=UTF-8'; |
| 189 | + add_header 'Content-Length' 0; |
| 190 | + return 204; |
| 191 | + } |
| 192 | + |
| 193 | + add_header 'Access-Control-Allow-Origin' 'name.of.your.website.example.com' always; |
| 194 | + add_header 'Access-Control-Allow-Credentials' 'true' always; |
| 195 | + add_header 'Access-Control-Allow-Headers' 'Accept,Accept-Language,Content-Language,Content-Type' always; |
| 196 | + proxy_http_version 1.1; |
| 197 | + proxy_set_header Host $host; |
| 198 | + proxy_set_header X-Real-IP $remote_addr; |
| 199 | + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |
| 200 | + proxy_pass http://collector:4318; |
| 201 | + } |
| 202 | +} |
| 203 | +``` |
| 204 | + |
| 205 | +## 控制台 {#console} |
| 206 | + |
| 207 | +要调试你的插桩代码,或在本地开发环境中查看数值,你可以使用将遥测数据写入控制台(标准输出)的导出器。 |
| 208 | + |
| 209 | +如果你遵循了[入门指南](/docs/languages/js/getting-started/nodejs/)或[手动插桩](/docs/languages/js/instrumentation)指南, |
| 210 | +你已经安装了控制台导出器。 |
| 211 | + |
| 212 | +`ConsoleSpanExporter` 包含在 [`@opentelemetry/sdk-trace-node`](https://www.npmjs.com/package/@opentelemetry/sdk-trace-node) |
| 213 | +包中,而 `ConsoleMetricExporter` 包含在 [`@opentelemetry/sdk-metrics`](https://www.npmjs.com/package/@opentelemetry/sdk-metrics) |
| 214 | +包中。 |
| 215 | + |
| 216 | +{{% include "exporters/jaeger.md" %}} |
| 217 | + |
| 218 | +{{% include "exporters/prometheus-setup.md" %}} |
| 219 | + |
| 220 | +## Prometheus 依赖项 {#prometheus-dependencies} |
| 221 | + |
| 222 | +将[导出器包](https://www.npmjs.com/package/@opentelemetry/exporter-prometheus)作为项目依赖安装到你的应用中: |
| 223 | + |
| 224 | +```shell |
| 225 | +npm install --save @opentelemetry/exporter-prometheus |
| 226 | +``` |
| 227 | + |
| 228 | +将你的 OpenTelemetry 配置更新为使用该导出器,并将数据发送到 Prometheus 后端: |
| 229 | + |
| 230 | +{{< tabpane text=true >}} {{% tab TypeScript %}} |
| 231 | + |
| 232 | +```ts |
| 233 | +import * as opentelemetry from '@opentelemetry/sdk-node'; |
| 234 | +import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; |
| 235 | +import { PrometheusExporter } from '@opentelemetry/exporter-prometheus'; |
| 236 | + |
| 237 | +const sdk = new opentelemetry.NodeSDK({ |
| 238 | + metricReader: new PrometheusExporter({ |
| 239 | + port: 9464, // 可选 - 默认值为 9464 |
| 240 | + }), |
| 241 | + instrumentations: [getNodeAutoInstrumentations()], |
| 242 | +}); |
| 243 | +sdk.start(); |
| 244 | +``` |
| 245 | + |
| 246 | +{{% /tab %}} {{% tab JavaScript %}} |
| 247 | + |
| 248 | +```js |
| 249 | +const opentelemetry = require('@opentelemetry/sdk-node'); |
| 250 | +const { |
| 251 | + getNodeAutoInstrumentations, |
| 252 | +} = require('@opentelemetry/auto-instrumentations-node'); |
| 253 | +const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus'); |
| 254 | +const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics'); |
| 255 | +const sdk = new opentelemetry.NodeSDK({ |
| 256 | + metricReader: new PrometheusExporter({ |
| 257 | + port: 9464, // 可选 - 默认值为 9464 |
| 258 | + }), |
| 259 | + instrumentations: [getNodeAutoInstrumentations()], |
| 260 | +}); |
| 261 | +sdk.start(); |
| 262 | +``` |
| 263 | + |
| 264 | +{{% /tab %}} {{< /tabpane >}} |
| 265 | + |
| 266 | +通过上述配置,你可以在 <http://localhost:9464/metrics> 访问你的指标数据。 |
| 267 | +Prometheus 或 OpenTelemetry 采集器中的 Prometheus 接收器可以从该端点采集指标数据。 |
| 268 | + |
| 269 | +{{% include "exporters/zipkin-setup.md" %}} |
| 270 | + |
| 271 | +## Zipkin 依赖项 {#zipkin-dependencies} |
| 272 | + |
| 273 | +若要将链路数据发送至 [Zipkin](https://zipkin.io/),你可以使用 `ZipkinExporter` 导出器。 |
| 274 | + |
| 275 | +安装[导出器包](https://www.npmjs.com/package/@opentelemetry/exporter-zipkin)作为项目依赖安装到你的应用中: |
| 276 | + |
| 277 | +```shell |
| 278 | +npm install --save @opentelemetry/exporter-zipkin |
| 279 | +``` |
| 280 | + |
| 281 | +将你的 OpenTelemetry 配置更新为使用该导出器,并将数据发送到 Zipkin 后端: |
| 282 | + |
| 283 | +{{< tabpane text=true >}} {{% tab TypeScript %}} |
| 284 | + |
| 285 | +```ts |
| 286 | +import * as opentelemetry from '@opentelemetry/sdk-node'; |
| 287 | +import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; |
| 288 | +import { ZipkinExporter } from '@opentelemetry/exporter-zipkin'; |
| 289 | + |
| 290 | +const sdk = new opentelemetry.NodeSDK({ |
| 291 | + traceExporter: new ZipkinExporter({}), |
| 292 | + instrumentations: [getNodeAutoInstrumentations()], |
| 293 | +}); |
| 294 | +sdk.start(); |
| 295 | +``` |
| 296 | + |
| 297 | +{{% /tab %}} {{% tab JavaScript %}} |
| 298 | + |
| 299 | +```js |
| 300 | +const opentelemetry = require('@opentelemetry/sdk-node'); |
| 301 | +const { |
| 302 | + getNodeAutoInstrumentations, |
| 303 | +} = require('@opentelemetry/auto-instrumentations-node'); |
| 304 | +const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin'); |
| 305 | + |
| 306 | +const sdk = new opentelemetry.NodeSDK({ |
| 307 | + traceExporter: new ZipkinExporter({}), |
| 308 | + instrumentations: [getNodeAutoInstrumentations()], |
| 309 | +}); |
| 310 | +``` |
| 311 | + |
| 312 | +{{% /tab %}} {{< /tabpane >}} |
| 313 | + |
| 314 | +{{% include "exporters/outro.md" `https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_sdk-trace-base.SpanExporter.html` %}} |
| 315 | + |
| 316 | +{{< tabpane text=true >}} {{% tab TypeScript %}} |
| 317 | + |
| 318 | +```ts |
| 319 | +/*instrumentation.ts*/ |
| 320 | +import * as opentelemetry from '@opentelemetry/sdk-node'; |
| 321 | +import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; |
| 322 | + |
| 323 | +const sdk = new NodeSDK({ |
| 324 | + spanProcessors: [new SimpleSpanProcessor(exporter)], |
| 325 | + instrumentations: [getNodeAutoInstrumentations()], |
| 326 | +}); |
| 327 | +sdk.start(); |
| 328 | +``` |
| 329 | + |
| 330 | +{{% /tab %}} {{% tab JavaScript %}} |
| 331 | + |
| 332 | +```js |
| 333 | +/*instrumentation.js*/ |
| 334 | +const opentelemetry = require('@opentelemetry/sdk-node'); |
| 335 | +const { |
| 336 | + getNodeAutoInstrumentations, |
| 337 | +} = require('@opentelemetry/auto-instrumentations-node'); |
| 338 | + |
| 339 | +const sdk = new opentelemetry.NodeSDK({ |
| 340 | + spanProcessors: [new SimpleSpanProcessor(exporter)], |
| 341 | + instrumentations: [getNodeAutoInstrumentations()], |
| 342 | +}); |
| 343 | +sdk.start(); |
| 344 | +``` |
| 345 | + |
| 346 | +{{% /tab %}} {{< /tabpane >}} |
| 347 | + |
| 348 | +[content security policies]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ |
| 349 | +[cross-origin resource sharing]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS |
| 350 | +[opentelemetry collector exporter with grpc]: https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-grpc |
| 351 | +[opentelemetry collector exporter with http/protobuf]: https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-proto |
| 352 | +[opentelemetry collector exporter with http/json]: https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-http |
| 353 | +[a feature]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/confighttp/README.md |
0 commit comments