# 导出器

> 处理并导出你的遥测数据

---

LLMS index: [llms.txt](/llms.txt)

---


将遥测数据发送到 [OpenTelemetry Collector](/docs/collector/)，以确保其被正确导出。
在生产环境中使用 Collector 是最佳实践。若要可视化你的遥测数据，可将其导出到后端系统，例如
[Jaeger](https://jaegertracing.io/)、[Zipkin](https://zipkin.io/)、
[Prometheus](https://prometheus.io/)，或某个[特定厂商的](/ecosystem/vendors/)后端。



## 可用的导出器 {#available-exporters}

镜像仓库中包含一份 [JavaScript 可用导出器的列表][reg]。





在所有导出器中，[OpenTelemetry 协议 (OTLP)][OTLP] 导出器是以 OpenTelemetry 数据模型为基础设计的，
能够无信息丢失地输出 OTel 数据。此外，许多处理遥测数据的工具都支持 OTLP
（例如 [Prometheus][]、[Jaeger][] 和大多数[厂商][vendors]），在你需要时为你提供高度的灵活性。
若要了解更多关于 OTLP 的信息，请参阅 [OTLP 规范][OTLP]。

[Jaeger]: /blog/2022/jaeger-native-otlp/
[OTLP]: /docs/specs/otlp/
[Prometheus]: https://prometheus.io/docs/prometheus/2.55/feature_flags/#otlp-receiver
[reg]: </ecosystem/registry/?component=exporter&language=js>
[vendors]: /ecosystem/vendors/



本页面介绍了主要的 OpenTelemetry JavaScript 导出器以及如何进行配置。





<div class="alert alert-primary" role="alert"><div class="h4 alert-heading" role="heading">注意</div>



如果你使用了[零代码自动插桩](</docs/zero-code/js>)，
你可以参考[配置指南](</docs/zero-code/js/configuration/>)来了解如何设置导出器。

</div>






## OTLP

### Collector 设置 {#collector-setup}

<div class="alert alert-primary" role="alert"><div class="h4 alert-heading" role="heading">注意</div>



如果你已经配置好 OTLP Collector 或后端，可以跳过此部分，
直接[设置应用的 OTLP 导出器依赖](#otlp-dependencies)。

</div>


为测试和验证你的 OTLP 导出器，你可以运行一个 Docker 容器形式的 Collector，将遥测数据直接输出到控制台。

在一个空目录下创建名为 `collector-config.yaml` 的文件，并添加以下内容：

```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：

```shell
docker run -p 4317:4317 -p 4318:4318 --rm -v $(pwd)/collector-config.yaml:/etc/otelcol/config.yaml otel/opentelemetry-collector
```

现在，这个 Collector 已能通过 OTLP 接收遥测数据。
之后你可能需要配置 Collector，将遥测数据发送到你的可观测性后端。


{{__hugo_ctx/}}


## 依赖项 {#otlp-dependencies}

若你希望将遥测数据发送至 OTLP 端点（比如 [OpenTelemetry 采集器](#collector-setup)、[Jaeger](#jaeger) 或 [Prometheus](#prometheus)），你可以从三种不同的传输协议中选择一种来传输数据：

- [HTTP/protobuf](https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-proto)
- [HTTP/JSON](https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-http)
- [gRPC](https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-grpc)

开始前，先安装相应的导出器包作为项目的依赖项：

    <ul class="nav nav-tabs" id="tabs-1" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-01-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-01-00" role="tab"
          data-td-tp-persist="http/proto" aria-controls="tabs-01-00" aria-selected="true">
        HTTP/Proto
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-01-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-01-01" role="tab"
          data-td-tp-persist="http/json" aria-controls="tabs-01-01" aria-selected="false">
        HTTP/JSON
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-01-02-tab" data-bs-toggle="tab" data-bs-target="#tabs-01-02" role="tab"
          data-td-tp-persist="grpc" aria-controls="tabs-01-02" aria-selected="false">
        gRPC
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-1-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-01-00" role="tabpanel" aria-labelled-by="tabs-01-00-tab" tabindex="1">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">npm install --save @opentelemetry/exporter-trace-otlp-proto <span class="se">\
</span></span></span><span class="line"><span class="cl">  @opentelemetry/exporter-metrics-otlp-proto
</span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-01-01" role="tabpanel" aria-labelled-by="tabs-01-01-tab" tabindex="1">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">npm install --save @opentelemetry/exporter-trace-otlp-http <span class="se">\
</span></span></span><span class="line"><span class="cl">  @opentelemetry/exporter-metrics-otlp-http
</span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-01-02" role="tabpanel" aria-labelled-by="tabs-01-02-tab" tabindex="1">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">npm install --save @opentelemetry/exporter-trace-otlp-grpc <span class="se">\
</span></span></span><span class="line"><span class="cl">  @opentelemetry/exporter-metrics-otlp-grpc
</span></span></code></pre></div>
    </div>
</div>


## Node.js 环境使用指南 {#otlp-usage-nodejs}

接下来，配置导出器以指向 OTLP 端点。
例如，你可以更新[入门指南](/docs/languages/js/getting-started/nodejs/)中的 `instrumentation.ts`（如果使用 JavaScript 则为 `instrumentation.js`）文件，
如下所示，通过 OTLP（`http/protobuf`）导出链路和指标数据：

   <ul class="nav nav-tabs" id="tabs-2" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-02-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-02-00" role="tab"
          data-td-tp-persist="typescript" aria-controls="tabs-02-00" aria-selected="true">
        TypeScript
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-02-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-02-01" role="tab"
          data-td-tp-persist="javascript" aria-controls="tabs-02-01" aria-selected="false">
        JavaScript
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-2-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-02-00" role="tabpanel" aria-labelled-by="tabs-02-00-tab" tabindex="2">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="cm">/*instrumentation.ts*/</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="o">*</span> <span class="kr">as</span> <span class="nx">opentelemetry</span> <span class="kr">from</span> <span class="s1">&#39;@opentelemetry/sdk-node&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">getNodeAutoInstrumentations</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;@opentelemetry/auto-instrumentations-node&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">OTLPTraceExporter</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;@opentelemetry/exporter-trace-otlp-proto&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">OTLPMetricExporter</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;@opentelemetry/exporter-metrics-otlp-proto&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">PeriodicExportingMetricReader</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;@opentelemetry/sdk-metrics&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">sdk</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">opentelemetry</span><span class="p">.</span><span class="nx">NodeSDK</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">traceExporter</span>: <span class="kt">new</span> <span class="nx">OTLPTraceExporter</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 可选 - 默认 URL 为 http://localhost:4318/v1/traces
</span></span></span><span class="line"><span class="cl">    <span class="nx">url</span><span class="o">:</span> <span class="s1">&#39;&lt;your-otlp-endpoint&gt;/v1/traces&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 可选 - 每个请求要发送的自定义头信息，默认为空
</span></span></span><span class="line"><span class="cl">    <span class="nx">headers</span><span class="o">:</span> <span class="p">{},</span>
</span></span><span class="line"><span class="cl">  <span class="p">}),</span>
</span></span><span class="line"><span class="cl">  <span class="nx">metricReader</span>: <span class="kt">new</span> <span class="nx">PeriodicExportingMetricReader</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">exporter</span>: <span class="kt">new</span> <span class="nx">OTLPMetricExporter</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">      <span class="nx">url</span><span class="o">:</span> <span class="s1">&#39;&lt;your-otlp-endpoint&gt;/v1/metrics&#39;</span><span class="p">,</span> <span class="c1">// URL 是可选项并且可以省略，默认值为 http://localhost:4318/v1/metrics
</span></span></span><span class="line"><span class="cl">      <span class="nx">headers</span><span class="o">:</span> <span class="p">{},</span> <span class="c1">// 一个可选对象，包含了要随每个请求一同发送的自定义请求头。
</span></span></span><span class="line"><span class="cl">    <span class="p">}),</span>
</span></span><span class="line"><span class="cl">  <span class="p">}),</span>
</span></span><span class="line"><span class="cl">  <span class="nx">instrumentations</span><span class="o">:</span> <span class="p">[</span><span class="nx">getNodeAutoInstrumentations</span><span class="p">()],</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="nx">sdk</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span>
</span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-02-01" role="tabpanel" aria-labelled-by="tabs-02-01-tab" tabindex="2">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="cm">/*instrumentation.js*/</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">opentelemetry</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;@opentelemetry/sdk-node&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">getNodeAutoInstrumentations</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;@opentelemetry/auto-instrumentations-node&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">OTLPTraceExporter</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;@opentelemetry/exporter-trace-otlp-proto&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">OTLPMetricExporter</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;@opentelemetry/exporter-metrics-otlp-proto&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">{</span> <span class="nx">PeriodicExportingMetricReader</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;@opentelemetry/sdk-metrics&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">sdk</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">opentelemetry</span><span class="p">.</span><span class="nx">NodeSDK</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">traceExporter</span><span class="o">:</span> <span class="k">new</span> <span class="nx">OTLPTraceExporter</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 可选 - 默认 URL 为 http://localhost:4318/v1/traces
</span></span></span><span class="line"><span class="cl">    <span class="nx">url</span><span class="o">:</span> <span class="s1">&#39;&lt;your-otlp-endpoint&gt;/v1/traces&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 可选 - 每个请求要发送的自定义头信息，默认为空
</span></span></span><span class="line"><span class="cl">    <span class="nx">headers</span><span class="o">:</span> <span class="p">{},</span>
</span></span><span class="line"><span class="cl">  <span class="p">}),</span>
</span></span><span class="line"><span class="cl">  <span class="nx">metricReader</span><span class="o">:</span> <span class="k">new</span> <span class="nx">PeriodicExportingMetricReader</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">exporter</span><span class="o">:</span> <span class="k">new</span> <span class="nx">OTLPMetricExporter</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">      <span class="nx">url</span><span class="o">:</span> <span class="s1">&#39;&lt;your-otlp-endpoint&gt;/v1/metrics&#39;</span><span class="p">,</span> <span class="c1">// URL 是可选项并且可以省略，默认值为 http://localhost:4318/v1/metrics
</span></span></span><span class="line"><span class="cl">      <span class="nx">headers</span><span class="o">:</span> <span class="p">{},</span> <span class="c1">// 一个可选对象，包含了要随每个请求一同发送的自定义请求头。
</span></span></span><span class="line"><span class="cl">      <span class="nx">concurrencyLimit</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="c1">// 一个用于限制待处理请求数量的可选阈值。
</span></span></span><span class="line"><span class="cl">    <span class="p">}),</span>
</span></span><span class="line"><span class="cl">  <span class="p">}),</span>
</span></span><span class="line"><span class="cl">  <span class="nx">instrumentations</span><span class="o">:</span> <span class="p">[</span><span class="nx">getNodeAutoInstrumentations</span><span class="p">()],</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="nx">sdk</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span>
</span></span></code></pre></div>
    </div>
</div>


## 浏览器环境使用指南 {#usage-in-the-browser}

当你在基于浏览器的应用程序中使用 OTLP 导出器时，你需要注意以下几点：

1. 不支持使用 gRPC 进行导出
2. 你的网站的[内容安全策略][Content Security Policies]（CSP）可能会阻止遥测数据的导出操作。
3. [跨域资源共享][Cross-Origin Resource Sharing]（CORS）响应头可能不允许发送导出数据
4. 你可能需要将采集器暴露到公共互联网

你可以在下方找到选用合适导出器的操作指南，去配置内容安全策略（CSP）与跨域资源共享（CORS）响应头，以及暴露采集器时需采取的防范措施。

### 使用 OTLP 导出器结合 HTTP/JSON 或 HTTP/protobuf 协议 {#use-otlp-exporter-with-http-json-or-http-protobuf}

[基于 gRPC 协议的 OpenTelemetry 采集器导出器][OpenTelemetry Collector Exporter with gRPC]仅适用于 Node.js，
因此你只能使用[基于 HTTP/JSON 协议的 OpenTelemetry 采集器导出器][OpenTelemetry Collector Exporter with HTTP/JSON]或[基于 HTTP/protobuf 协议的 OpenTelemetry 采集器导出器][OpenTelemetry Collector Exporter with HTTP/protobuf]。

如果你使用的是[基于 HTTP/JSON 协议的 OpenTelemetry 采集器导出器][OpenTelemetry Collector Exporter with HTTP/JSON]，
请确保导出器的接收端（采集器或可观测性后端）支持 `http/json`，并且你将数据导出到正确的端点，端口设置为 4318。

### 配置 CSP {#configure-csps}

如果你的网站使用了内容安全策略（CSP），请确保包含了 OTLP 端点的域名。
如果你的采集器端点是 `https://collector.example.com:4318/v1/traces`，请添加以下指令：

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

如果你的 CSP 未包含 OTLP 端点，你会看到一条错误消息，指出对端点的请求违反了 CSP 指令。

### 配置 CORS 响应头 {#configure-cors-headers}

如果你的网站和采集器托管在不同的域名下，你的浏览器可能会阻止向采集器发送请求。
你需要为[跨域资源共享][Cross-Origin Resource Sharing]（CORS）配置特殊的响应头。

OpenTelemetry 采集器为基于 HTTP 协议的接收器提供了[一项功能][a feature]，
可自动添加所需的请求头，使接收器能够接收来自网页浏览器链路数据：

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

### 安全地暴露你的采集器 {#securely-expose-your-collector}

若要从 Web 应用接收遥测数据，你需要允许终端用户的浏览器向采集器发送数据。
若你的 Web 应用可从公共互联网访问，那么你也必须将采集器设置为对所有用户开放访问。

建议你不要直接暴露采集器，而是在其前端部署反向代理（如 NGINX、Apache HTTP 服务器等）。
反向代理可负责 SSL 卸载、配置正确的跨域资源共享（CORS）响应头，以及实现诸多针对 Web 应用的专属功能。

下面是流行的 NGINX Web 服务器的配置示例，供你参考使用：

```nginx
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;
    }
}
```

## 控制台 {#console}

要调试你的插桩代码，或在本地开发环境中查看数值，你可以使用将遥测数据写入控制台（标准输出）的导出器。

如果你遵循了[入门指南](/docs/languages/js/getting-started/nodejs/)或[手动插桩](/docs/languages/js/instrumentation)指南，
你已经安装了控制台导出器。

`ConsoleSpanExporter` 包含在 [`@opentelemetry/sdk-trace-node`](https://www.npmjs.com/package/@opentelemetry/sdk-trace-node)
包中，而 `ConsoleMetricExporter` 包含在 [`@opentelemetry/sdk-metrics`](https://www.npmjs.com/package/@opentelemetry/sdk-metrics)
包中。


## Jaeger

### 后端设置 {#jaeger-backend-setup}

[Jaeger](https://www.jaegertracing.io/) 原生支持 OTLP，用于接收链路数据。
你可以通过运行一个 Docker 容器来启动 Jaeger，其 UI 默认在端口 16686 上可访问，并在端口 4317 和 4318 上启用 OTLP：

```shell
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
```

### 使用方法 {#jaeger-usage}

现在，按照说明设置 [OTLP 导出器](#otlp-dependencies)。
{{__hugo_ctx/}}



## Prometheus

要将你的指标数据发送到 [Prometheus](https://prometheus.io/)，
你可以选择[启用 Prometheus 的 OTLP 接收器](https://prometheus.io/docs/guides/opentelemetry/#enable-the-otlp-receiver)并且使用
[OTLP 导出器](#otlp)，或者使用 Prometheus 导出器，这是一种 `MetricReader`，
他启动一个 HTTP 服务器，根据请求收集指标并将数据序列化为 Prometheus 文本格式。

### 后端设置 {#prometheus-setup}

<div class="alert alert-primary" role="alert"><div class="h4 alert-heading" role="heading">注意</div>



如果你已经设置了 Prometheus 或兼容 Prometheus 的后端，可以跳过本节，直接为你的应用设置
[Prometheus](#prometheus-dependencies) 或者 [OTLP](#otlp-dependencies) 导出器依赖。

</div>


你可以按照以下步骤在 Docker 容器中运行 [Prometheus](https://prometheus.io)，并通过端口 9090 访问：

创建一个名为 `prometheus.yml` 的文件，并将以下内容写入文件：

```yaml
scrape_configs:
  - job_name: dice-service
    scrape_interval: 5s
    static_configs:
      - targets: [host.docker.internal:9464]
```

使用以下命令在 Docker 容器中运行 Prometheus，UI 可通过端口 `9090` 访问：

```shell
docker run --rm -v ${PWD}/prometheus.yml:/prometheus/prometheus.yml -p 9090:9090 prom/prometheus --web.enable-otlp-receiver
```

<div class="alert alert-primary" role="alert"><div class="h4 alert-heading" role="heading">注意</div>



当使用 Prometheus 的 OTLP 接收器时，确保在应用中设置 OTLP 端点为
`http://localhost:9090/api/v1/otlp`。

并非所有的 Docker 环境都支持 `host.docker.internal`。在某些情况下，你可能需要将
`host.docker.internal` 替换为 `localhost` 或你机器的 IP 地址。

</div>

{{__hugo_ctx/}}


## Prometheus 依赖项 {#prometheus-dependencies}

将[导出器包](https://www.npmjs.com/package/@opentelemetry/exporter-prometheus)作为项目依赖安装到你的应用中：

```shell
npm install --save @opentelemetry/exporter-prometheus
```

将你的 OpenTelemetry 配置更新为使用该导出器，并将数据发送到 Prometheus 后端：

   <ul class="nav nav-tabs" id="tabs-5" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-05-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-05-00" role="tab"
          data-td-tp-persist="typescript" aria-controls="tabs-05-00" aria-selected="true">
        TypeScript
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-05-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-05-01" role="tab"
          data-td-tp-persist="javascript" aria-controls="tabs-05-01" aria-selected="false">
        JavaScript
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-5-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-05-00" role="tabpanel" aria-labelled-by="tabs-05-00-tab" tabindex="5">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="kr">import</span> <span class="o">*</span> <span class="kr">as</span> <span class="nx">opentelemetry</span> <span class="kr">from</span> <span class="s1">&#39;@opentelemetry/sdk-node&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">getNodeAutoInstrumentations</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;@opentelemetry/auto-instrumentations-node&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">PrometheusExporter</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;@opentelemetry/exporter-prometheus&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">sdk</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">opentelemetry</span><span class="p">.</span><span class="nx">NodeSDK</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">metricReader</span>: <span class="kt">new</span> <span class="nx">PrometheusExporter</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">port</span>: <span class="kt">9464</span><span class="p">,</span> <span class="c1">// 可选 - 默认值为 9464
</span></span></span><span class="line"><span class="cl">  <span class="p">}),</span>
</span></span><span class="line"><span class="cl">  <span class="nx">instrumentations</span><span class="o">:</span> <span class="p">[</span><span class="nx">getNodeAutoInstrumentations</span><span class="p">()],</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="nx">sdk</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span>
</span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-05-01" role="tabpanel" aria-labelled-by="tabs-05-01-tab" tabindex="5">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">opentelemetry</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;@opentelemetry/sdk-node&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">getNodeAutoInstrumentations</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;@opentelemetry/auto-instrumentations-node&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">{</span> <span class="nx">PrometheusExporter</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;@opentelemetry/exporter-prometheus&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">{</span> <span class="nx">PeriodicExportingMetricReader</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;@opentelemetry/sdk-metrics&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">sdk</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">opentelemetry</span><span class="p">.</span><span class="nx">NodeSDK</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">metricReader</span><span class="o">:</span> <span class="k">new</span> <span class="nx">PrometheusExporter</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">port</span><span class="o">:</span> <span class="mi">9464</span><span class="p">,</span> <span class="c1">// 可选 - 默认值为 9464
</span></span></span><span class="line"><span class="cl">  <span class="p">}),</span>
</span></span><span class="line"><span class="cl">  <span class="nx">instrumentations</span><span class="o">:</span> <span class="p">[</span><span class="nx">getNodeAutoInstrumentations</span><span class="p">()],</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="nx">sdk</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span>
</span></span></code></pre></div>
    </div>
</div>


通过上述配置，你可以在 <http://localhost:9464/metrics> 访问你的指标数据。
Prometheus 或 OpenTelemetry 采集器中的 Prometheus 接收器可以从该端点采集指标数据。


## Zipkin

### 后端设置 {#zipkin-setup}

<div class="alert alert-primary" role="alert"><div class="h4 alert-heading" role="heading">提示</div>



如果你已经设置了 Zipkin 或兼容 Zipkin 的后端，可以跳过本节并直接为你的应用设置
[Zipkin 导出器依赖](#zipkin-dependencies)。

</div>


你可以通过执行以下命令，在 Docker 容器中运行 [Zipkin](https://zipkin.io/)：

```shell
docker run --rm -d -p 9411:9411 --name zipkin openzipkin/zipkin
```
{{__hugo_ctx/}}


## Zipkin 依赖项 {#zipkin-dependencies}

若要将链路数据发送至 [Zipkin](https://zipkin.io/)，你可以使用 `ZipkinExporter` 导出器。

安装[导出器包](https://www.npmjs.com/package/@opentelemetry/exporter-zipkin)作为项目依赖安装到你的应用中：

```shell
npm install --save @opentelemetry/exporter-zipkin
```

将你的 OpenTelemetry 配置更新为使用该导出器，并将数据发送到 Zipkin 后端：

   <ul class="nav nav-tabs" id="tabs-7" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-07-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-07-00" role="tab"
          data-td-tp-persist="typescript" aria-controls="tabs-07-00" aria-selected="true">
        TypeScript
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-07-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-07-01" role="tab"
          data-td-tp-persist="javascript" aria-controls="tabs-07-01" aria-selected="false">
        JavaScript
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-7-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-07-00" role="tabpanel" aria-labelled-by="tabs-07-00-tab" tabindex="7">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="kr">import</span> <span class="o">*</span> <span class="kr">as</span> <span class="nx">opentelemetry</span> <span class="kr">from</span> <span class="s1">&#39;@opentelemetry/sdk-node&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">getNodeAutoInstrumentations</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;@opentelemetry/auto-instrumentations-node&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">ZipkinExporter</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;@opentelemetry/exporter-zipkin&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">sdk</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">opentelemetry</span><span class="p">.</span><span class="nx">NodeSDK</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">traceExporter</span>: <span class="kt">new</span> <span class="nx">ZipkinExporter</span><span class="p">({}),</span>
</span></span><span class="line"><span class="cl">  <span class="nx">instrumentations</span><span class="o">:</span> <span class="p">[</span><span class="nx">getNodeAutoInstrumentations</span><span class="p">()],</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="nx">sdk</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span>
</span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-07-01" role="tabpanel" aria-labelled-by="tabs-07-01-tab" tabindex="7">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">opentelemetry</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;@opentelemetry/sdk-node&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">getNodeAutoInstrumentations</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;@opentelemetry/auto-instrumentations-node&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">{</span> <span class="nx">ZipkinExporter</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;@opentelemetry/exporter-zipkin&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">sdk</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">opentelemetry</span><span class="p">.</span><span class="nx">NodeSDK</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">traceExporter</span><span class="o">:</span> <span class="k">new</span> <span class="nx">ZipkinExporter</span><span class="p">({}),</span>
</span></span><span class="line"><span class="cl">  <span class="nx">instrumentations</span><span class="o">:</span> <span class="p">[</span><span class="nx">getNodeAutoInstrumentations</span><span class="p">()],</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div>
    </div>
</div>



## 自定义导出器 {#custom-exporters}

最后，你还可以编写自己的导出器。有关更多信息，请参见
[API 文档中的 SpanExporter 接口](https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_sdk-trace-base.SpanExporter.html).

## 批量处理 Span 和日志记录 {#batching-span-and-log-records}

OpenTelemetry SDK 提供了一组默认的 Span 和日志记录处理器，
允许你选择按单条（simple）或按批量（batch）方式导出一个或多个 Span。
推荐使用批量处理，但如果你不想批量处理 Span 或日志记录，可以使用 simple 处理器，方法如下：
{{__hugo_ctx/}}


   <ul class="nav nav-tabs" id="tabs-9" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-09-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-09-00" role="tab"
          data-td-tp-persist="typescript" aria-controls="tabs-09-00" aria-selected="true">
        TypeScript
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-09-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-09-01" role="tab"
          data-td-tp-persist="javascript" aria-controls="tabs-09-01" aria-selected="false">
        JavaScript
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-9-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-09-00" role="tabpanel" aria-labelled-by="tabs-09-00-tab" tabindex="9">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="cm">/*instrumentation.ts*/</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="o">*</span> <span class="kr">as</span> <span class="nx">opentelemetry</span> <span class="kr">from</span> <span class="s1">&#39;@opentelemetry/sdk-node&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">getNodeAutoInstrumentations</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;@opentelemetry/auto-instrumentations-node&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">sdk</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">NodeSDK</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">spanProcessors</span><span class="o">:</span> <span class="p">[</span><span class="k">new</span> <span class="nx">SimpleSpanProcessor</span><span class="p">(</span><span class="nx">exporter</span><span class="p">)],</span>
</span></span><span class="line"><span class="cl">  <span class="nx">instrumentations</span><span class="o">:</span> <span class="p">[</span><span class="nx">getNodeAutoInstrumentations</span><span class="p">()],</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="nx">sdk</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span>
</span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-09-01" role="tabpanel" aria-labelled-by="tabs-09-01-tab" tabindex="9">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="cm">/*instrumentation.js*/</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">opentelemetry</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;@opentelemetry/sdk-node&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">getNodeAutoInstrumentations</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;@opentelemetry/auto-instrumentations-node&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">sdk</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">opentelemetry</span><span class="p">.</span><span class="nx">NodeSDK</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">spanProcessors</span><span class="o">:</span> <span class="p">[</span><span class="k">new</span> <span class="nx">SimpleSpanProcessor</span><span class="p">(</span><span class="nx">exporter</span><span class="p">)],</span>
</span></span><span class="line"><span class="cl">  <span class="nx">instrumentations</span><span class="o">:</span> <span class="p">[</span><span class="nx">getNodeAutoInstrumentations</span><span class="p">()],</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="nx">sdk</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span>
</span></span></code></pre></div>
    </div>
</div>


[content security policies]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/
[cross-origin resource sharing]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
[opentelemetry collector exporter with grpc]: https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-grpc
[opentelemetry collector exporter with http/protobuf]: https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-proto
[opentelemetry collector exporter with http/json]: https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-http
[a feature]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/confighttp/README.md
