

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

# 迁移到 OpenTelemetry Ruby
<a name="migrate-xray-to-opentelemetry-ruby"></a>

要将 Ruby 应用程序从 X-Ray SDK 迁移到 OpenTelemetry 检测中，请使用以下代码示例和手动检测指南。

**Topics**
+ [使用 SDK 手动检测解决方案](#manual-instrumentation-ruby)
+ [跟踪传入请求（Rails 检测）](#tracing-incoming-requests-ruby)
+ [Amazon 软件开发工具包工具](#aws-sdk-instrumentation-ruby)
+ [检测传出 HTTP 调用](#http-instrumentation-ruby)
+ [对其他库的检测支持](#xray-migration-libraries-ruby)
+ [手动创建跟踪数据](#manual-trace-creation-ruby)
+ [Lambda 手动检测](#lambda-instrumentation-ruby)

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

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

要使用 X-Ray SDK for Ruby，则需要通过服务插件配置代码。

```
require 'aws-xray-sdk'

XRay.recorder.configure(plugins: [:ec2, :elastic_beanstalk])
```

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

**注意**  
 目前无法为 OpenTelemetry Ruby 配置 X-Ray 远程采样。

对于 Ruby on Rails 应用程序，请将配置代码放置在 Rails 初始化程序中。有关更多信息，请参阅 [ 入门](https://opentelemetry.io/docs/languages/ruby/getting-started/#initialization)。对于所有手动检测的 Ruby 程序，必须使用该`OpenTelemetry::SDK.configure`方法来配置 OpenTelemetry Ruby SDK。

首先，安装以下软件包：

```
bundle add opentelemetry-sdk opentelemetry-exporter-otlp opentelemetry-propagator-xray
```

接下来，通过程序初始化时运行的配置代码配置 OpenTelemetry SDK。建议您配置以下组件：
+ `OTLP Exporter`— 将轨迹导出到 CloudWatch 代理和 OpenTelemetry 采集器时必需的
+ `An Amazon X-Ray Propagator`— 需要将跟踪上下文传播到与 X-Ray 集成的 Amazon 服务

```
require 'opentelemetry-sdk'
require 'opentelemetry-exporter-otlp'

# Import the gem containing the AWS X-Ray for OTel Ruby ID Generator and propagator
require 'opentelemetry-propagator-xray'

OpenTelemetry::SDK.configure do |c|
  c.service_name = 'my-service-name'

  c.add_span_processor(
    # Use the BatchSpanProcessor to send traces in groups instead of one at a time
    OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
      # Use the default OLTP Exporter to send traces to the ADOT Collector
      OpenTelemetry::Exporter::OTLP::Exporter.new(
        # The OpenTelemetry Collector is running as a sidecar and listening on port 4318
        endpoint:"http://127.0.0.1:4318/v1/traces"
      )
    )
  )
  
  # The X-Ray Propagator injects the X-Ray Tracing Header into downstream calls
  c.propagators = [OpenTelemetry::Propagator::XRay::TextMapPropagator.new]
end
```

OpenTelemetry SDKs 也有图书馆仪器的概念。启用这些功能将自动为 Amazon SDK 等库创建跨度。 OpenTelemetry 提供了启用所有库乐器或指定要启用哪些库乐器的选项。

要启用所有检测，请先安装 `opentelemetry-instrumentation-all` 软件包：

```
bundle add opentelemetry-instrumentation-all
```

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

```
require 'opentelemetry/instrumentation/all'
...

OpenTelemetry::SDK.configure do |c|
   ...

  c.use_all() # Enable all instrumentations
end
```

OpenTelemetry SDKs 也有图书馆仪器的概念。启用这些功能将自动为 Amazon SDK 等库创建跨度。 OpenTelemetry 提供了启用所有库乐器或指定要启用哪些库乐器的选项。

要启用所有检测，请先安装 `opentelemetry-instrumentation-all` 软件包：

```
bundle add opentelemetry-instrumentation-all
```

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

```
require 'opentelemetry/instrumentation/all'
...

OpenTelemetry::SDK.configure do |c|
   ...

  c.use_all() # Enable all instrumentations
end
```

------

## 跟踪传入请求（Rails 检测）
<a name="tracing-incoming-requests-ruby"></a>

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

使用 X-Ray SDK 时，可以在初始化时为 Rails 框架配置 X-Ray 跟踪。

**示例** — config/initializers/aws \$1xray.rb

```
Rails.application.config.xray = {
  name: 'my app',
  patch: %I[net_http aws_sdk],
  active_record: true
}
```

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

首先，安装以下软件包：

```
bundle add opentelemetry-instrumentation-rack opentelemetry-instrumentation-rails opentelemetry-instrumentation-action_pack opentelemetry-instrumentation-active_record opentelemetry-instrumentation-action_view
```

接下来，更新配置以为 Rails 应用程序启用检测，如下所示：

```
# During SDK configuration
OpenTelemetry::SDK.configure do |c|

  ...

  c.use 'OpenTelemetry::Instrumentation::Rails'
  c.use 'OpenTelemetry::Instrumentation::Rack'
  c.use 'OpenTelemetry::Instrumentation::ActionPack'
  c.use 'OpenTelemetry::Instrumentation::ActiveSupport'
  c.use 'OpenTelemetry::Instrumentation::ActionView'
  
  ...
  
end
```

------

## Amazon 软件开发工具包工具
<a name="aws-sdk-instrumentation-ruby"></a>

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

为了检测来自 Amazon SDK 的传出 Amazon 请求，使用 X-Ray 修补了 Amazon SDK 客户端，如下例所示：

```
require 'aws-xray-sdk'
require 'aws-sdk-s3'

# Patch Amazon SDK clients
XRay.recorder.configure(plugins: [:aws_sdk])

# Use the instrumented client
s3 = Aws::S3::Client.new
s3.list_buckets
```

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

Amazon 适用于 Ruby V3 的 SDK 支持记录和发射 OpenTelemetry 轨迹。有关如何为服务客户端 OpenTelemetry 进行配置的信息，请参阅在 [Amazon SDK for Ruby 中配置可观察性功能](sdk-for-ruby/v3/developer-guide/observability.html)。

------

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

在对外部服务进行 HTTP 调用时，如果自动检测不可用或无法提供足够的详细信息，则可能需要手动检测调用。

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

要检测下游调用，请使用 X-Ray SDK for Ruby 修补应用程序使用的 `net/http` 库。

```
require 'aws-xray-sdk'

config = {
  name: 'my app',
  patch: %I[net_http]
}

XRay.recorder.configure(config)
```

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

要使用启用`net/http`工具 OpenTelemetry，请先安装`opentelemetry-instrumentation-net_http`软件包：

```
bundle add opentelemetry-instrumentation-net_http
```

接下来，更新配置以启用 `net/http` 检测，如下所示：

```
OpenTelemetry::SDK.configure do |c|
   ...

  c.use 'OpenTelemetry::Instrumentation::Net::HTTP'
  ...

end
```

------

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

你可以在下面找到 OpenTelemetry Ruby 支持的库工具的完整列表。[opentelemetry-ruby-contrib](https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/main/instrumentation)

或者，您可以搜索 OpenTelemetry 注册表以了解是否 OpenTelemetry 支持检测。有关更多信息，请参阅[注册表](https://opentelemetry.io/ecosystem/registry/)。

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

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

如果使用 X-Ray，则需要通过 `aws-xray-sdk` 软件包来手动创建分段及其子分段，以便跟踪应用程序。您可能还为分段或子分段添加了 X-Ray 注释和元数据：

```
require 'aws-xray-sdk'
...

# Start a segment
segment = XRay.recorder.begin_segment('my-service')

# Add annotations (indexed key-value pairs)
segment.annotations[:user_id] = 'user-123'
segment.annotations[:payment_status] = 'completed'

# Add metadata (non-indexed data)
segment.metadata[:order] = {
  id: 'order-456',
  items: [
    { product_id: 'prod-1', quantity: 2 },
    { product_id: 'prod-2', quantity: 1 }
  ],
  total: 67.99
}

# Add metadata to a specific namespace
segment.metadata(namespace: 'payment') do |metadata|
  metadata[:transaction_id] = 'tx-789'
  metadata[:payment_method] = 'credit_card'
end

# Create a subsegment with annotations and metadata
segment.subsegment('payment-processing') do |subsegment1|
  subsegment1.annotations[:payment_id] = 'pay-123'
  subsegment1.metadata[:details] = { amount: 67.99, currency: 'USD' }
  
  # Create a nested subsegment
  subsegment1.subsegment('operation-2') do |subsegment2|
    # Do more work...
  end
end

# Close the segment
segment.close
```

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

您可以使用自定义跨度来监控未被检测库捕获的内部活动的性能。请注意，只有服务器类跨度会转换为 X-Ray 分段，所有其他跨度均转换为 X-Ray 子分段。跨度默认为 `INTERNAL`。

首先，创建一个跟踪器来生成跨度，您可以通过 `OpenTelemetry.tracer_provider.tracer('<YOUR_TRACER_NAME>')` 方法来获得该跨度。这将提供一个在您的应用程序 OpenTelemetry 配置中全局注册的 Tracer 实例。整个应用程序通常只有一个跟踪器。创建一个 OpenTelemetry 示踪器并用它来创建跨度：

```
require 'opentelemetry-sdk'

...

# Get a tracer
tracer = OpenTelemetry.tracer_provider.tracer('my-application')

# Create a server span (equivalent to X-Ray segment)
tracer.in_span('my-application', kind: OpenTelemetry::Trace::SpanKind::SERVER) do |span|
  # Do work...
  
  # Create nested spans of default kind INTERNAL will become an X-Ray subsegment
  tracer.in_span('operation-1') do |child_span1|
    # Set attributes (equivalent to X-Ray annotations and metadata)
    child_span1.set_attribute('key', 'value')
    
    # Do more work...
    tracer.in_span('operation-2') do |child_span2|
      # Do more work...
    end
  end
end
```

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

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

```
# SERVER span will become an X-Ray segment
tracer.in_span('my-server-operation', kind: OpenTelemetry::Trace::SpanKind::SERVER) do |span|
    # Your server logic here
    span.set_attribute('attribute.key', 'attribute.value')
    span.set_attribute("metadataKey", "metadataValue")
    span.set_attribute("annotationKey1", "annotationValue")
    
    # Create X-Ray annotations
    span.set_attribute("aws.xray.annotations", ["annotationKey1"])
end
```

------

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

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

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

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

考虑以下 Lambda 函数代码示例（不带检测）：

```
require 'json'
def lambda_handler(event:, context:)
    # TODO implement
    { statusCode: 200, body: JSON.generate('Hello from Lambda!') }
end
```

要手动检测 Lambda，您需要：

1. 为 Lambda 添加以下 Gem

   ```
   gem 'opentelemetry-sdk'
   gem 'opentelemetry-exporter-otlp'
   gem 'opentelemetry-propagator-xray'
   gem 'aws-distro-opentelemetry-exporter-xray-udp'
   gem 'opentelemetry-instrumentation-aws_lambda'
   gem 'opentelemetry-propagator-xray', '~> 0.24.0' # Requires version v0.24.0 or higher
   ```

1. 在 Lambda 处理程序之外初始化 OpenTelemetry 开发工具包。建议将 S OpenTelemetry DK 配置为：

   1. 带有 X-Ray UDP 跨度导出程序的简单跨度处理器，用于向 Lambda 的 UDP X-Ray 端点发送跟踪数据

   1. X-Ray Lambda 传播器

   1. 将 `service_name` 配置设置为 Lambda 函数名称

1. 在 Lambda 处理程序类中，添加以下几行来检测 Lambda 处理程序：

   ```
     class Handler
           extend OpenTelemetry::Instrumentation::AwsLambda::Wrap
           ...
   
           instrument_handler :process
       end
   ```

以下代码演示了进行必要更改后的 Lambda 函数。您可以创建其他自定义跨度来补充自动提供的跨度。

```
require 'json'
require 'opentelemetry-sdk'
require 'aws/distro/opentelemetry/exporter/xray/udp'
require 'opentelemetry/propagator/xray'
require 'opentelemetry/instrumentation/aws_lambda'

# Initialize OpenTelemetry SDK outside handler
OpenTelemetry::SDK.configure do |c|
  # Configure the AWS Distro for OpenTelemetry X-Ray Lambda exporter
  c.add_span_processor(
    OpenTelemetry::SDK::Trace::Export::SimpleSpanProcessor.new(
      AWS::Distro::OpenTelemetry::Exporter::XRay::UDP::AWSXRayUDPSpanExporter.new
    )
  )
  
  # Configure X-Ray Lambda propagator
  c.propagators = [OpenTelemetry::Propagator::XRay.lambda_text_map_propagator]
  
  # Set minimal resource information
  c.resource = OpenTelemetry::SDK::Resources::Resource.create({
    OpenTelemetry::SemanticConventions::Resource::SERVICE_NAME => ENV['AWS_LAMBDA_FUNCTION_NAME']
  })
  c.use 'OpenTelemetry::Instrumentation::AwsLambda'
end

module LambdaFunctions
  class Handler
    extend OpenTelemetry::Instrumentation::AwsLambda::Wrap
    def self.process(event:, context:)
      "Hello!"
    end
    instrument_handler :process
  end
end
```

------

以下是用 Ruby 编写的经过检测的 Lambda 函数的示例跟踪地图。

![\[Ruby CloudWatch 控制台中的跟踪地图。\]](http://docs.amazonaws.cn/xray/latest/devguide/images/deprecation_ruby.png)


您也可以使用 Lambda 层为您的 Lambda OpenTelemetry 进行配置。有关更多信息，请参阅 [OpenTelemetry AWS-Lambda 工具](https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/main/instrumentation/aws_lambda#usage)。