

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 遷移至 OpenTelemetry Java
<a name="xray-migration-opentelemetry"></a>

本節提供從 X-Ray 開發套件遷移至適用於 Java 的 OpenTelemetry 開發套件應用程式的指引。

**Topics**
+ [

## 零程式碼自動檢測解決方案
](#xray-migration-zero-code)
+ [

## 使用 SDK 的手動檢測解決方案
](#xray-migration-sdk)
+ [

## 追蹤傳入請求 （彈簧架構檢測）
](#xray-migration-tracing-setup-otel)
+ [

## AWS SDK v2 檢測
](#xray-migration-sdkv2)
+ [

## 檢測傳出的 HTTP 呼叫
](#xray-migration-http)
+ [

## 其他程式庫的檢測支援
](#xray-migration-libraries)
+ [

## 手動建立追蹤資料
](#xray-migration-tracedata)
+ [

## Lambda 檢測
](#xray-migration-lambda)

## 零程式碼自動檢測解決方案
<a name="xray-migration-zero-code"></a>

------
#### [ With X-Ray Java agent ]

若要啟用 X-Ray Java 代理程式，需要修改應用程式的 JVM 引數。

```
-javaagent:/path-to-disco/disco-java-agent.jar=pluginPath=/path-to-disco/disco-plugins
```

------
#### [ With OpenTelemetry-based Java agent ]

使用 OpenTelemetry 型 Java 代理程式。
+ 使用 AWS Distro for OpenTelemetry (ADOT) Auto-Instrumentation Java 代理程式搭配 ADOT Java 代理程式進行自動檢測。如需詳細資訊，請參閱[使用 Java 代理程式自動檢測追蹤和指標](https://aws-otel.github.io/docs/getting-started/java-sdk/auto-instr)。如果您只想要追蹤，請停用 `OTEL_METRICS_EXPORTER=none ` 環境變數。 從 Java 代理程式匯出指標。

  （選用） 您也可以 AWS 在使用 ADOT Java 自動檢測功能自動檢測應用程式時啟用 CloudWatch Application Signals，以監控目前的應用程式運作狀態並追蹤長期應用程式效能。Application Signals 為您的應用程式、服務和相依性提供統一、以應用程式為中心的檢視，並協助監控和分類應用程式運作狀態。如需詳細資訊，請參閱 [Application Signals](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Application-Monitoring-Sections.html)。
+ 使用 OpenTelemetry Java 代理程式進行自動檢測。如需詳細資訊，請參閱[使用 Java Agent 進行零碼檢測](https://opentelemetry.io/docs/zero-code/java/agent/)。

------

## 使用 SDK 的手動檢測解決方案
<a name="xray-migration-sdk"></a>

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

若要使用適用於 Java 的 X-Ray 開發套件檢測您的程式碼，首先需要使用服務外掛程式和本機取樣規則來設定 `AWSXRay`類別，然後使用提供的記錄器。

```
static { AWS XRayRecorderBuilder builder = AWS XRayRecorderBuilder.standard().withPlugin(new EC2Plugin()).withPlugin(new ECSPlugin()); AWS XRay.setGlobalRecorder(builder.build());
}
```

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

以下是必要的相依性。

```
<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.opentelemetry</groupId>
                <artifactId>opentelemetry-bom</artifactId>
                <version>1.49.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>io.opentelemetry.instrumentation</groupId>
                <artifactId>opentelemetry-instrumentation-bom</artifactId>
                <version>2.15.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-sdk</artifactId>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-api</artifactId>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry.semconv</groupId>
            <artifactId>opentelemetry-semconv</artifactId>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-exporter-otlp</artifactId>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry.contrib</groupId>
            <artifactId>opentelemetry-aws-xray</artifactId>
            <version>1.46.0</version>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry.contrib</groupId>
            <artifactId>opentelemetry-aws-xray-propagator</artifactId>
            <version>1.46.0-alpha</version>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry.contrib</groupId>
            <artifactId>opentelemetry-aws-resources</artifactId>
            <version>1.46.0-alpha</version>
        </dependency>
    </dependencies>
```

透過執行個體化 `TracerProvider`和全域註冊`OpenTelemetrySdk`物件來設定 OpenTelemetry SDK。設定這些元件：
+ OTLP Span Exporter （例如 OtlpGrpcSpanExporter) - 將追蹤匯出至 CloudWatch 代理程式或 OpenTelemetry Collector 時需要
+  AWS X-Ray 傳播器 – 將追蹤內容傳播至與 X-Ray 整合 AWS 的服務時需要
+  AWS X-Ray 遠端取樣器 – 如果您需要使用 X-Ray 取樣規則來取樣請求，則為必要項目
+ 資源偵測器 （例如 EcsResource 或 Ec2Resource) – 偵測執行您應用程式的主機中繼資料

  ```
  import io.opentelemetry.api.common.Attributes;
  import io.opentelemetry.context.propagation.ContextPropagators;
  import io.opentelemetry.contrib.aws.resource.Ec2Resource;
  import io.opentelemetry.contrib.aws.resource.EcsResource;
  import io.opentelemetry.contrib.awsxray.AwsXrayRemoteSampler;
  import io.opentelemetry.contrib.awsxray.propagator.AwsXrayPropagator;
  import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
  import io.opentelemetry.sdk.OpenTelemetrySdk;
  import io.opentelemetry.sdk.resources.Resource;
  import io.opentelemetry.sdk.trace.SdkTracerProvider;
  import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
  import io.opentelemetry.sdk.trace.samplers.Sampler;
  import static io.opentelemetry.semconv.ServiceAttributes.SERVICE_NAME;
  
  // ...
  
      private static final Resource otelResource =
          Resource.create(Attributes.of(SERVICE_NAME, "YOUR_SERVICE_NAME"))
              .merge(EcsResource.get())
              .merge(Ec2Resource.get());
      private static final SdkTracerProvider sdkTracerProvider =
          SdkTracerProvider.builder()
              .addSpanProcessor(BatchSpanProcessor.create(
                  OtlpGrpcSpanExporter.getDefault()
              ))
              .addResource(otelResource)
              .setSampler(Sampler.parentBased(
                  AwsXrayRemoteSampler.newBuilder(otelResource).build()
              ))
              .build();
      // Globally registering a TracerProvider makes it available throughout the application to create as many Tracers as needed.
      private static final OpenTelemetrySdk openTelemetry =
          OpenTelemetrySdk.builder()
              .setTracerProvider(sdkTracerProvider)
              .setPropagators(ContextPropagators.create(AwsXrayPropagator.getInstance()))
              .buildAndRegisterGlobal();
  ```

------

## 追蹤傳入請求 （彈簧架構檢測）
<a name="xray-migration-tracing-setup-otel"></a>

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

如需有關如何使用 X-Ray 開發套件搭配彈簧架構來檢測應用程式的資訊，請參閱 [AOP with Spring 和適用於 Java 的 X-Ray 開發套件](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java-aop-spring.html)。若要在 Spring 中啟用 AOP，請完成以下步驟。

1. [設定 Spring](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java-aop-spring.html#xray-sdk-java-aop-spring-configuration)

1. [將追蹤篩選條件新增至您的應用程式 ](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java-aop-spring.html#xray-sdk-java-aop-filters-spring)

1. [註釋您的程式碼或實作 界面 ](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java-aop-spring.html#xray-sdk-java-aop-annotate-or-implement)

1. [啟用應用程式中的 X-Ray](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java-aop-spring.html#xray-sdk-java-aop-activate-xray)

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

OpenTelemetry 提供檢測程式庫，可收集 Spring Boot 應用程式傳入請求的追蹤。若要以最少的組態啟用 Spring Boot 檢測，請包含下列相依性。

```
<dependency>
           <groupId>io.opentelemetry.instrumentation</groupId>
            <artifactId>opentelemetry-spring-boot-starter</artifactId>
        </dependency>
```

如需如何為 OpenTelemetry 設定啟用和設定 Spring Boot 檢測的詳細資訊，請參閱 OpenTelemetry [入門](https://opentelemetry.io/docs/zero-code/java/spring-boot-starter/getting-started/)。

------
#### [ Using OpenTelemetry-based Java agents ]

檢測 Spring Boot 應用程式的預設建議方法是使用 [OpenTelemetry Java 代理](https://opentelemetry.io/docs/zero-code/java/agent/)程式搭配*位元組碼*檢測，與直接使用 SDK 相比，它還提供更多out-of-the-box檢測和組態。如需入門，請參閱 [零程式碼自動檢測解決方案](#xray-migration-zero-code)。

------

## AWS SDK v2 檢測
<a name="xray-migration-sdkv2"></a>

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

當您在建置中新增`aws-xray-recorder-sdk-aws-sdk-v2-instrumentor`子模組時，適用於 Java 的 X-Ray 開發套件可以自動檢測所有 AWS SDK v2 用戶端。

若要使用適用於 Java 的 AWS SDK 2.2 和更新版本來檢測個別用戶端下游用戶端對 AWS 服務的呼叫，已排除建置組態中的`aws-xray-recorder-sdk-aws-sdk-v2-instrumentor `模組，並包含`aws-xray-recorder-sdk-aws-sdk-v2`模組。透過使用 設定個別用戶端來進行檢測`TracingInterceptor`。

```
import com.amazonaws.xray.interceptors.TracingInterceptor;
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
//...

public class MyModel {
  private DynamoDbClient client = DynamoDbClient.builder()
    .region(Region.US_WEST_2)
    .overrideConfiguration(
      ClientOverrideConfiguration.builder()
        .addExecutionInterceptor(new TracingInterceptor())
        .build()
      )
    .build();
//...
```

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

若要自動檢測所有 AWS SDK 用戶端，請新增 `opentelemetry-aws-sdk-2.2-autoconfigure`子模組。

```
<dependency>
            <groupId>io.opentelemetry.instrumentation</groupId>
            <artifactId>opentelemetry-aws-sdk-2.2-autoconfigure</artifactId>
            <version>2.15.0-alpha</version>
            <scope>runtime</scope>
        </dependency>
```

若要檢測個別 AWS SDK 用戶端，請新增 `opentelemetry-aws-sdk-2.2`子模組。

```
<dependency>
            <groupId>io.opentelemetry.instrumentation</groupId>
            <artifactId>opentelemetry-aws-sdk-2.2</artifactId>
            <version>2.15.0-alpha</version>
            <scope>compile</scope>
        </dependency>
```

然後，在建立 AWS SDK 用戶端時註冊攔截器。

```
import io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkTelemetry;

// ...

    AwsSdkTelemetry telemetry = AwsSdkTelemetry.create(openTelemetry);
    private final S3Client S3_CLIENT = S3Client.builder()
      .overrideConfiguration(ClientOverrideConfiguration.builder()
        .addExecutionInterceptor(telemetry.newExecutionInterceptor())
        .build())
      .build();
```

------

## 檢測傳出的 HTTP 呼叫
<a name="xray-migration-http"></a>

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

若要使用 X-Ray 檢測傳出的 HTTP 請求，需要適用於 Java 的 X-Ray 開發套件的 Apache HttpClient 版本。

```
import com.amazonaws.xray.proxies.apache.http.HttpClientBuilder;
...
  public String randomName() throws IOException {
    CloseableHttpClient httpclient = HttpClientBuilder.create().build();
```

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

與 X-Ray Java 開發套件類似，OpenTelemetry 提供的 `ApacheHttpClientTelemetry`類別具有建置器方法，允許建立 的執行個體`HttpClientBuilder`，為 Apache HttpClient 提供 OpenTelemetry 型跨度和內容傳播。

```
<dependency>
            <groupId>io.opentelemetry.instrumentation</groupId>
            <artifactId>opentelemetry-apache-httpclient-5.2</artifactId>
            <version>2.15.0-alpha</version>
            <scope>compile</scope>
        </dependency>
```

以下是 [opentelemetry-java-instrumentation ](https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/apache-httpclient/apache-httpclient-5.2/library)的程式碼範例。newHttpClient() 提供的 HTTP 用戶端將為執行的請求產生追蹤。

```
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.apachehttpclient.v5_2.ApacheHttpClientTelemetry;
import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;

public class ApacheHttpClientConfiguration {

  private OpenTelemetry openTelemetry;

  public ApacheHttpClientConfiguration(OpenTelemetry openTelemetry) {
    this.openTelemetry = openTelemetry;
  }

  // creates a new http client builder for constructing http clients with open telemetry instrumentation
  public HttpClientBuilder createBuilder() {
    return ApacheHttpClientTelemetry.builder(openTelemetry).build().newHttpClientBuilder();
  }

  // creates a new http client with open telemetry instrumentation
  public HttpClient newHttpClient() {
    return ApacheHttpClientTelemetry.builder(openTelemetry).build().newHttpClient();
  }
}
```

------

## 其他程式庫的檢測支援
<a name="xray-migration-libraries"></a>

在支援的程式庫、架構、應用程式伺服器和 JVM 下，在其個別的檢測 GitHub 儲存庫 中尋找 OpenTelemetry Java 支援的程式庫檢測的完整清單。 [ JVMs ](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/docs/supported-libraries.md)

或者，您可以搜尋 OpenTelemetry 登錄檔，了解 OpenTelemetry 是否支援檢測。若要開始搜尋，請參閱 [登錄](https://opentelemetry.io/ecosystem/registry/)檔。

## 手動建立追蹤資料
<a name="xray-migration-tracedata"></a>

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

使用 X-Ray SDK，需要 `beginSegment`和 `beginSubsegment`方法來手動建立 X-Ray 區段和子區段。

```
  Segment segment = xrayRecorder.beginSegment("ManualSegment");
        segment.putAnnotation("annotationKey", "annotationValue");
        segment.putMetadata("metadataKey", "metadataValue");

        try {
            Subsegment subsegment = xrayRecorder.beginSubsegment("ManualSubsegment");
            subsegment.putAnnotation("key", "value");

            // Do something here

        } catch (Exception e) {
            subsegment.addException(e);
        } finally {
            xrayRecorder.endSegment();
        }
```

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

您可以使用自訂跨度來監控檢測程式庫未擷取的內部活動效能。請注意，只有跨類型伺服器會轉換為 X-Ray 區段，所有其他跨度則會轉換為 X-Ray 子區段。

首先，您需要建立*追蹤器*以產生跨度，您可以透過 `openTelemetry.getTracer`方法取得。這將提供來自 的 Tracer 執行個體`TracerProvider`，該執行個體已在 [使用 SDK 的手動檢測解決方案](#xray-migration-sdk)範例中全域註冊。您可以視需要建立任意數量的 Tracer 執行個體，但整個應用程式通常會有一個 Tracer。

```
Tracer tracer = openTelemetry.getTracer("my-app");
```

您可以使用 Tracer 來建立跨度。

```
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope;

...

// SERVER span will become an X-Ray segment
Span span = tracer.spanBuilder("get-token")
  .setKind(SpanKind.SERVER)
  .setAttribute("key", "value")
  .startSpan();
try (Scope ignored = span.makeCurrent()) {

  span.setAttribute("metadataKey", "metadataValue");
  span.setAttribute("annotationKey", "annotationValue");
  
  // The following ensures that "annotationKey: annotationValue" is an annotation in X-Ray raw data.
  span.setAttribute(AttributeKey.stringArrayKey("aws.xray.annotations"), List.of("annotationKey"));

  // Do something here
}

span.end();
```

跨度的預設類型為 *INTERNAL*。

```
// Default span of type INTERNAL will become an X-Ray subsegment
Span span = tracer.spanBuilder("process-header")
  .startSpan();
try (Scope ignored = span.makeCurrent()) {
  doProcessHeader();
}
```

**使用 OpenTelemetry SDK 將註釋和中繼資料新增至追蹤**

在上述範例中， `setAttribute`方法用於將屬性新增至每個跨度。根據預設，所有跨度屬性都會轉換為 X-Ray 原始資料中的中繼資料。為了確保屬性轉換為註釋而非中繼資料，上述範例會將該屬性的索引鍵新增至`aws.xray.annotations`屬性清單。如需詳細資訊，請參閱[啟用自訂 X-Ray 註釋](https://aws-otel.github.io/docs/getting-started/x-ray#enable-the-customized-x-ray-annotations)和[註釋和中繼資料](https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-annotations)。

**使用 OpenTelemetry 型 Java 代理程式**

如果您使用 Java 代理程式自動檢測應用程式，則需要在應用程式中執行手動檢測。例如，針對任何自動檢測程式庫未涵蓋的區段，在應用程式中檢測程式碼。

若要使用代理程式執行手動檢測，您需要使用`opentelemetry-api `成品。成品版本不能比代理程式版本更新。

```
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Span;

// ...
  
        Span parentSpan = Span.current();
        Tracer tracer = GlobalOpenTelemetry.getTracer("my-app");
        Span span = tracer.spanBuilder("my-span-name")
            .setParent(io.opentelemetry.context.Context.current().with(parentSpan))
            .startSpan();
        span.end();
```

------

## Lambda 檢測
<a name="xray-migration-lambda"></a>

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

使用 X-Ray 開發套件，在 Lambda *啟用主動追蹤*之後，使用 X-Ray 開發套件不需要額外的組態。Lambda 將建立代表 Lambda 處理常式調用的區段，而且您可以使用 X-Ray SDK 建立子區段或檢測程式庫，而不需要任何額外的組態。

------
#### [ With OpenTelemetry-based solutions ]

自動檢測 Lambda 圖層 – 您可以使用下列解決方案，自動檢測 Lambda 與已 AWS 佈建的 Lambda 圖層：
+ AWS 適用於 OpenTelemetry 的 Lambda Layer （建議）
**注意**  
此 Lambda 層預設會啟用 CloudWatch Application Signals，透過收集指標和追蹤來啟用 Lambda 應用程式的效能和運作狀態監控。若只要追蹤，請設定 Lambda 環境變數 ` OTEL_AWS_APPLICATION_SIGNALS_ENABLED=false`。
  + 啟用 Lambda 應用程式的效能和運作狀態監控
  + 預設會同時收集指標和追蹤
+ AWS ADOT Java 的 受管 Lambda 層。如需詳細資訊，請參閱 [AWS Distro for OpenTelemetry Lambda Support for Java](https://aws-otel.github.io/docs/getting-started/lambda/lambda-java)。

若要搭配自動檢測層使用手動檢測，請參閱 [使用 SDK 的手動檢測解決方案](#xray-migration-sdk)。為了減少冷啟動，請考慮使用 OpenTelemetry 手動檢測為您的 Lambda 函數產生 OpenTelemetry 追蹤。

------

**適用於 AWS Lambda 的 OpenTelemetry 手動檢測**

請考慮下列進行 Amazon S3 ListBuckets 呼叫的 Lambda 函數程式碼。

```
package example;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.ListBucketsRequest;
import software.amazon.awssdk.services.s3.model.ListBucketsResponse;
import software.amazon.awssdk.services.s3.model.S3Exception;

public class ListBucketsLambda implements RequestHandler<String, String> {

    private final S3Client S3_CLIENT = S3Client.builder()
        .build();

    @Override
    public String handleRequest(String input, Context context) {
        try {
            ListBucketsResponse response = makeListBucketsCall();
            context.getLogger().log("response: " + response.toString());
            return "Success";
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private ListBucketsResponse makeListBucketsCall() {
        try {
            ListBucketsRequest listBucketsRequest = ListBucketsRequest.builder()
                .build();
            ListBucketsResponse response = S3_CLIENT.listBuckets(listBucketsRequest);
            return response;
        } catch (S3Exception e) {
            throw new RuntimeException("Failed to call S3 listBuckets" + e.awsErrorDetails().errorMessage(), e);
        }
    }
}
```

以下是相依性。

```
dependencies {
    implementation('com.amazonaws:aws-lambda-java-core:1.2.3')
    implementation('software.amazon.awssdk:s3:2.28.29')
    implementation('org.slf4j:slf4j-nop:2.0.16')
}
```

若要手動檢測 Lambda 處理常式和 Amazon S3 用戶端，請執行下列動作。

1. 將實作 `RequestHandler`（或 RequestStreamHandler) 的函數類別取代為延伸 `TracingRequestHandler`（或 TracingRequestStreamHandler) 的函數類別。

1. 執行個體化 TracerProvider 並全域註冊 OpenTelemetrySdk 物件。建議將 TracerProvider 設定為：

   1. 具有 X-Ray UDP 跨度匯出程式的簡易跨度處理器，可將追蹤傳送至 Lambda 的 UDP X-Ray 端點

   1. ParentBased always on sampler （若未設定，則預設為預設值）

   1. 將 service.name 設定為 Lambda 函數名稱的資源

   1. X-Ray Lambda 傳播器

1. 將 `handleRequest` 方法變更為 ，`doHandleRequest`並將`OpenTelemetrySdk`物件傳遞至 基礎類別。

1. 透過在建置用戶端時註冊攔截器，使用 OpenTemetry AWS SDK 檢測來檢測 Amazon S3 用戶端。

您需要下列 OpenTelemetry 相關相依性。

```
dependencies {
    ...

    implementation("software.amazon.distro.opentelemetry:aws-distro-opentelemetry-xray-udp-span-exporter:0.1.0")

    implementation(platform('io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom:2.14.0'))
    implementation(platform('io.opentelemetry:opentelemetry-bom:1.48.0'))
    
    implementation('io.opentelemetry:opentelemetry-sdk')
    implementation('io.opentelemetry:opentelemetry-api')
    implementation('io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.45.0-alpha')
    implementation('io.opentelemetry.contrib:opentelemetry-aws-resources:1.45.0-alpha')
    implementation('io.opentelemetry.instrumentation:opentelemetry-aws-lambda-core-1.0:2.14.0-alpha')
    implementation('io.opentelemetry.instrumentation:opentelemetry-aws-sdk-2.2:2.14.0-alpha')
}
```

下列程式碼示範必要的變更之後的 Lambda 函數。您可以建立額外的自訂範圍，以補充自動提供的範圍。

```
package example;

import java.time.Duration;

import com.amazonaws.services.lambda.runtime.Context;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.contrib.aws.resource.LambdaResource;
import io.opentelemetry.contrib.awsxray.propagator.AwsXrayLambdaPropagator;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.TracingRequestHandler;
import io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkTelemetry;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import static io.opentelemetry.semconv.ServiceAttributes.SERVICE_NAME;
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.ListBucketsRequest;
import software.amazon.awssdk.services.s3.model.ListBucketsResponse;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.distro.opentelemetry.exporter.xray.udp.trace.AwsXrayUdpSpanExporterBuilder;

public class ListBucketsLambda extends TracingRequestHandler<String, String> {
    private static final Resource lambdaResource = LambdaResource.get();
    private static final SdkTracerProvider sdkTracerProvider =
        SdkTracerProvider.builder()
            .addSpanProcessor(SimpleSpanProcessor.create(
                new AwsXrayUdpSpanExporterBuilder().build()
            ))
            .addResource(
                lambdaResource
                .merge(Resource.create(Attributes.of(SERVICE_NAME, System.getenv("AWS_LAMBDA_FUNCTION_NAME"))))
            )
            .setSampler(Sampler.parentBased(Sampler.alwaysOn()))
            .build();
    private static final OpenTelemetrySdk openTelemetry =
        OpenTelemetrySdk.builder()
            .setTracerProvider(sdkTracerProvider)
            .setPropagators(ContextPropagators.create(AwsXrayLambdaPropagator.getInstance()))
            .buildAndRegisterGlobal();
    private static final AwsSdkTelemetry telemetry = AwsSdkTelemetry.create(openTelemetry);
    private final S3Client S3_CLIENT = S3Client.builder()
        .overrideConfiguration(ClientOverrideConfiguration.builder()
            .addExecutionInterceptor(telemetry.newExecutionInterceptor())
            .build())
        .build();

    public ListBucketsLambda() {
        super(openTelemetry, Duration.ofMillis(0));
    }

    @Override
    public String doHandleRequest(String input, Context context) {
        try {
            ListBucketsResponse response = makeListBucketsCall();
            context.getLogger().log("response: " + response.toString());
            return "Success";
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private ListBucketsResponse makeListBucketsCall() {
        try {
            ListBucketsRequest listBucketsRequest = ListBucketsRequest.builder()
                .build();
            ListBucketsResponse response = S3_CLIENT.listBuckets(listBucketsRequest);
            return response;
        } catch (S3Exception e) {
            throw new RuntimeException("Failed to call S3 listBuckets" + e.awsErrorDetails().errorMessage(), e);
        }
    }
}
```

叫用 Lambda 函數時，您會在 CloudWatch 主控台的*追蹤地圖*下看到下列追蹤。

![\[CloudWatch 主控台中的追蹤映射。\]](http://docs.aws.amazon.com/zh_tw/xray/latest/devguide/images/SDKDeprecation_Java.png)
