

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 迁移到 OpenTelemetry Node.js
<a name="migrate-xray-to-opentelemetry-nodejs"></a>

本节介绍如何将你的 Node.js 应用程序从 X-Ray SDK 迁移到 OpenTelemetry。它涵盖了自动和手动检测方法，并提供了常见使用案例的具体示例。

X-Ray Node.js SDK 可帮助您手动检测 Node.js 应用程序以进行跟踪。本节提供从 X-Ray 迁移到 OpenTelemetry 仪器的代码示例。

**Topics**
+ [

## 零代码自动检测解决方案
](#zero-code-instrumentation)
+ [

## 手动检测解决方案
](#manual-instrumentation)
+ [

## 跟踪传入请求
](#tracing-incoming-requests)
+ [

## AWS SDK JavaScript V3 插件
](#aws-sdk-instrumentation)
+ [

## 检测传出 HTTP 调用
](#http-instrumentation)
+ [

## 对其他库的检测支持
](#other-libraries)
+ [

## 手动创建跟踪数据
](#manual-trace-creation)
+ [

## Lambda 检测
](#lambda-instrumentation)

## 零代码自动检测解决方案
<a name="zero-code-instrumentation"></a>

要使用 X-Ray SDK for Node.js 跟踪请求，您必须修改应用程序代码。借 OpenTelemetry助，您可以使用零代码自动检测解决方案来跟踪请求。

**使用 OpenTelemetry基于自动仪表的零码自动检测。**

1. 将 AWS 发行版用于 Node.js 的 OpenTelemetry (ADOT) 自动检测 — 有关 Node.js 应用程序的自动检测，请参阅使用[AWS 发行版进行跟踪和衡量指标以进行](https://aws-otel.github.io/docs/getting-started/js-sdk/trace-metric-auto-instr)自动插入。 OpenTelemetry JavaScript 

   （可选）您还可以在使用 ADOT JavaScript 自动检测 CloudWatch 应用程序时启用应用程序信号，以监控当前应用程序的运行状况并根据 AWS 业务目标跟踪长期应用程序性能。Application Signals 为您提供统一的、以应用程序为中心的应用程序、服务和依赖项视图，帮助您监控应用程序的运行状况并对其进行分类。有关更多信息，请参阅 [Application Signals](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Application-Monitoring-Sections.html)。

1. 使用 OpenTelemetry JavaScript 零代码自动检测-要使用自动检测 OpenTelemetry JavaScript，请参阅[JavaScript 零代码](https://opentelemetry.io/docs/zero-code/js/)检测。

## 手动检测解决方案
<a name="manual-instrumentation"></a>

------
#### [ Tracing setup with X-Ray SDK ]

使用 X-Ray SDK for Node.js 时，需要先安装一个 `aws-xray-sdk` 软件包来配置 X-Ray SDK 的服务插件或本地采样规则，然后再使用 SDK 检测代码。

```
var AWSXRay = require('aws-xray-sdk');

AWSXRay.config([AWSXRay.plugins.EC2Plugin,AWSXRay.plugins.ElasticBeanstalkPlugin]);
AWSXRay.middleware.setSamplingRules(<path to file>);
```

------
#### [ Tracing setup with OpenTelemetry SDK ]

**注意**  
AWS 目前无法为 OpenTelemetry JS 配置 X-Ray 远程采样。但是，目前可通过适用于 Node.js 的 ADOT 自动检测获取对 X-Ray 远程采样的支持。

对于下面的代码示例，您将需要以下依赖项：

```
npm install --save \
  @opentelemetry/api \
  @opentelemetry/sdk-node \
  @opentelemetry/exporter-trace-otlp-proto \
  @opentelemetry/propagator-aws-xray \
  @opentelemetry/resource-detector-aws
```

在运行应用程序代码之前，必须设置和配置 OpenTelemetry SDK。这可以通过使用 [–-require ](https://nodejs.org/api/cli.html#-r---require-module) 标志来完成。创建一个名为 *instrumentation.js* 的文件，其中将包含您的 OpenTelemetry 仪器配置和设置。

建议您配置以下组件：
+ OTLPTrace导出器-需要向 CloudWatch 代理/收集器导出追踪信息 OpenTelemetry 
+ AWSXRay传播器-需要将跟踪上下文传播到与 X-Ray 集成的 AWS 服务
+ 资源检测器（例如 Amazon EC2 资源检测器）– 检测运行应用程序的主机的元数据

```
/*instrumentation.js*/
// Require dependencies
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-proto');
const { AWSXRayPropagator } = require("@opentelemetry/propagator-aws-xray");
const { detectResources } = require('@opentelemetry/resources');
const { awsEc2Detector } = require('@opentelemetry/resource-detector-aws');

const resource = detectResources({
    detectors: [awsEc2Detector],
});
 
const _traceExporter = new OTLPTraceExporter({
    url: 'http://localhost:4318/v1/traces'
});

const sdk = new NodeSDK({
    resource: resource,
    textMapPropagator: new AWSXRayPropagator(),
    traceExporter: _traceExporter
});

sdk.start();
```

然后，你可以用你的 OpenTelemetry 设置来运行你的应用程序，比如：

```
node --require ./instrumentation.js app.js
```

您可以使用 OpenTelemetry SDK 库工具自动为 SDK 等库创建跨度。 AWS 启用这些功能将自动为模块（例如 JavaScript v3 版 AWS SDK）创建跨度。 OpenTelemetry 提供了启用所有库乐器或指定要启用哪些库乐器的选项。

要启用所有检测，请安装 `@opentelemetry/auto-instrumentations-node` 软件包：

```
npm install @opentelemetry/auto-instrumentations-node
```

接下来，更新配置以启用所有库检测，如下所示。

```
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');

...

const sdk = new NodeSDK({
    resource: resource,
     instrumentations: [getNodeAutoInstrumentations()],
     textMapPropagator: new AWSXRayPropagator(),
    traceExporter: _traceExporter
});
```

------
#### [ Tracing setup with ADOT auto-instrumentation for Node.js ]

你可以使用适用于 Node.js 的 ADOT 自动检测来自动为你的 Node.js OpenTelemetry 应用程序进行配置。通过使用 ADOT Auto-Instrumention，您无需手动更改代码即可跟踪传入的请求或跟踪 AWS SDK 或 HTTP 客户端等库。有关更多信息，请参阅使用[ OpenTelemetry JavaScript 自动检测 AWS 发行版进行跟踪和指标](https://aws-otel.github.io/docs/getting-started/js-sdk/trace-metric-auto-instr)。

适用于 Node.js 的 ADOT 自动检测支持：
+ 通过环境变量 `export OTEL_TRACES_SAMPLER=xray` 进行 X-Ray 远程采样
+ X-Ray 跟踪上下文传播（默认情况下启用）
+ 资源检测（Amazon EC2、Amazon ECS 和 Amazon EKS 环境的资源检测默认处于启用状态）
+ 对所有支持的 OpenTelemetry 仪器进行自动库插入，可以通过和环境变量来 disabled/enabled 选择性地进行库插入 `OTEL_NODE_ENABLED_INSTRUMENTATIONS` `OTEL_NODE_DISABLED_INSTRUMENTATIONS`
+ 手动创建跨度

------

## 跟踪传入请求
<a name="tracing-incoming-requests"></a>

------
#### [ With X-Ray SDK ]

**Express.js**

使用 X-Ray SDK 来跟踪 *Express.js* 应用程序接收的传入 HTTP 请求时，需要通过两个中间件 `AWSXRay.express.openSegment(<name>)` 和 `AWSXRay.express.closeSegment()` 来封装所有定义的路由，以便跟踪它们。

```
app.use(xrayExpress.openSegment('defaultName'));

...

app.use(xrayExpress.closeSegment());
```

**Restify**

为了跟踪 `Restify` 应用程序接收到的传入 HTTP 请求，我们使用了 X-Ray SDK 中的中间件，方法是在 Restify 服务器上运行 `aws-xray-sdk-restify ` 模块的 enable 命令：

```
var AWSXRay = require('aws-xray-sdk');
var AWSXRayRestify = require('aws-xray-sdk-restify');

var restify = require('restify');
var server = restify.createServer();
AWSXRayRestify.enable(server, 'MyApp'));
```

------
#### [ With OpenTelemetry SDK ]

**Express.js**

[OpenTelemetry HTTP 检测和[OpenTelemetry 快速检测`Express.js`](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-express)](https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-http)为传入的请求提供跟踪支持。使用 `npm` 安装以下依赖项：

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

更新 OpenTelemetry SDK 配置以启用对 express 模块的检测：

```
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');
const { ExpressInstrumentation } = require('@opentelemetry/instrumentation-express');
...

const sdk = new NodeSDK({
  ...
  
  instrumentations: [
    ...
    // Express instrumentation requires HTTP instrumentation
    new HttpInstrumentation(),
    new ExpressInstrumentation(),
  ],
});
```

**Restify**

对于 Restify 应用程序，你需要使用 [OpenTelemetry Restify 工具](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-restify)。安装以下依赖项：

```
npm install --save @opentelemetry/instrumentation-restify
```

更新 OpenTelemetry SDK 配置以启用 restify 模块的检测功能：

```
const { RestifyInstrumentation } = require('@opentelemetry/instrumentation-restify');
...

const sdk = new NodeSDK({
  ...
  
  instrumentations: [
    ...
    new RestifyInstrumentation(),
  ],
});
```

------

## AWS SDK JavaScript V3 插件
<a name="aws-sdk-instrumentation"></a>

------
#### [ With X-Ray SDK ]

要检测来自 AWS SDK 的传出 AWS 请求，您需要对客户端进行检测，如下例所示：

```
import { S3, PutObjectCommand } from '@aws-sdk/client-s3';

const s3 = AWSXRay.captureAWSv3Client(new S3({}));

await s3.send(new PutObjectCommand({
  Bucket: bucketName,
  Key: keyName,
  Body: 'Hello!',
}));
```

------
#### [ With OpenTelemetry SDK ]

对下游 AWS DynamoDB、Amazon S3 和其他软件开发工具包调用的跟踪支持由 OpenTelemetry AWS 软件开发工具包工具包工具提供。使用 `npm` 安装以下依赖项：

```
npm install --save @opentelemetry/instrumentation-aws-sdk
```

使用 S OpenTelemetry DK 工具更新 S AWS DK 配置。

```
import { AwsInstrumentation } from '@opentelemetry/instrumentation-aws-sdk';
...

const sdk = new NodeSDK({
  ...

  instrumentations: [
    ...
    new AwsInstrumentation()
  ],
});
```

------

## 检测传出 HTTP 调用
<a name="http-instrumentation"></a>

------
#### [ With X-Ray SDK ]

要使用 X-Ray 检测传出 HTTP 请求，需要检测客户端。有关示例，请参阅以下内容。

单个 HTTP 客户端

```
var AWSXRay = require('aws-xray-sdk');
var http = AWSXRay.captureHTTPs(require('http'));
```

所有 HTTP 客户端（全局）

```
var AWSXRay = require('aws-xray-sdk');
AWSXRay.captureHTTPsGlobal(require('http'));
var http = require('http');
```

------
#### [ With OpenTelemetry SDK ]

HTTP 工具为 Node.js HTT OpenTelemetry P 客户端提供跟踪支持。使用 `npm` 安装以下依赖项：

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

按如下方式更新 OpenTelemetry SDK 配置：

```
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');
...

const sdk = new NodeSDK({
  ...
  
  instrumentations: [
    ...
    new HttpInstrumentation(),
  ],
});
```

------

## 对其他库的检测支持
<a name="other-libraries"></a>

[您可以在 “支持的仪器” OpenTelemetry JavaScript 下找到支持的库工具的完整列表。](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/metapackages/auto-instrumentations-node#supported-instrumentations)

或者，您可以在 OpenTelemetry 注册表中搜索注册表，以了解是否 OpenTelemetry 支持在[注册](https://opentelemetry.io/ecosystem/registry/)表下为您的库提供工具。

## 手动创建跟踪数据
<a name="manual-trace-creation"></a>

------
#### [ With X-Ray SDK ]

如果使用 X-Ray，则需要通过 `aws-xray-sdk` 软件包代码来手动创建分段及其子分段，以便跟踪应用程序。

```
var AWSXRay = require('aws-xray-sdk');

AWSXRay.enableManualMode();

var segment = new AWSXRay.Segment('myApplication');

captureFunc('1', function(subsegment1) {
  captureFunc('2', function(subsegment2) {

  }, subsegment1);
}, segment);

segment.close();
segment.flush();
```

------
#### [ With OpenTelemetry SDK ]

您可以创建和使用自定义跨度来监控未被检测库捕获的内部活动的性能。请注意，只有服务器类跨度会转换为 X-Ray 分段，所有其他跨度均转换为 X-Ray 子分段。有关更多信息，请参阅[分段](https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-segments)。

在跟踪设置中配置 OpenTelemetry SDK 以创建 Span 之后，您将需要一个 Tracer 实例。您可以根据需要创建任意数量的跟踪器实例，但通常针对整个应用程序创建一个跟踪器。

```
const { trace, SpanKind } = require('@opentelemetry/api');

// Get a tracer instance
const tracer = trace.getTracer('your-tracer-name');

...

  // This span will appear as a segment in X-Ray
  tracer.startActiveSpan('server', { kind: SpanKind.SERVER }, span => {
    // Do work here

    // This span will appear as a subsegment in X-Ray
    tracer.startActiveSpan('operation2', { kind: SpanKind.INTERNAL }, innerSpan => {
      // Do more work here

      innerSpan.end();
    });
    span.end();
  });
```

**使用 OpenTelemetry SDK 向跟踪添加注释和元数据**

您还可以向跨度中添加自定义键值对作为属性。请注意，默认情况下，所有这些跨度属性都将转换为 X-Ray 原始数据中的元数据。为确保将属性转换为注释而不是元数据，请将该属性的键添加到 `aws.xray.annotations` 属性列表中。有关更多信息，请参阅[启用自定义 X-Ray 注释](https://aws-otel.github.io/docs/getting-started/x-ray#enable-the-customized-x-ray-annotations)。

```
  tracer.startActiveSpan('server', { kind: SpanKind.SERVER }, span => {
    span.setAttribute('metadataKey', 'metadataValue');
    span.setAttribute('annotationKey', 'annotationValue');

    // The following ensures that "annotationKey: annotationValue" is an annotation in X-Ray raw data.
    span.setAttribute('aws.xray.annotations', ['annotationKey']);

    // Do work here

    span.end();
  });
```

------

## Lambda 检测
<a name="lambda-instrumentation"></a>

------
#### [ With X-Ray SDK ]

为 Lambda 函数启用*主动跟踪*后，无需额外配置即可使用 X-Ray SDK。Lambda 将创建一个表示 Lambda 处理程序调用的分段，您无需进行任何其他配置即可使用 X-Ray SDK 创建子分段或检测库。

------
#### [ With OpenTelemetry SDK ]

您可以使用已打开的 Lambda 图层自动检测您的 Lambda AWS 。有两种解决方案：
+ （推荐）适用于 AWS Lambda 层 OpenTelemetry
**注意**  
此 Lambda 层默认启用 CloudWatch 应用程序信号，通过收集指标和跟踪来监控您的 Lambda 应用程序的性能和运行状况。如果您只想跟踪，则应设置 Lambda 环境变量 `OTEL_AWS_APPLICATION_SIGNALS_ENABLED=false`。有关更多信息，请参阅[在 Lambda 上启用应用程序](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Application-Signals-Enable-LambdaMain.html)。
+ AWS 适用于 ADOT JS 的托管 Lambda 层。有关更多信息，请参阅适用于 Lamb [AWS d OpenTelemetry a Support 的发行版](https://aws-otel.github.io/docs/getting-started/lambda/lambda-js)。 JavaScript

**使用 Lambda 检测手动创建跨度**

虽然 ADOT Lamb JavaScript da 层为您的 Lambda 函数提供了自动检测，但您可能会发现需要在 Lambda 中执行手动检测，例如，提供自定义数据或在 Lambda 函数本身中检测库工具未涵盖的代码。

要在自动检测的同时执行手动检测，您需要添加 `@opentelemetry/api` 作为依赖项。建议此依赖项的版本与 ADOT JavaScript SDK 使用的相同依赖项的版本相同。您可以使用 OpenTelemetry API 在 Lambda 函数中手动创建跨度。

要使用 NPM 添加 `@opentelemetry/api` 依赖项，请执行以下操作：

```
npm install @opentelemetry/api
```

------