

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# OpenTelemetry .NET への移行
<a name="introduction-dotnet"></a>

.NET アプリケーションで X-Ray トレースを使用する場合、手動作業による X-Ray .NET SDK が計装に使用されます。

このセクションでは、X-Ray 手動計装ソリューションから .NET 用 OpenTelemetry 手動計装ソリューションに移行するために「[SDK を使用した手動計装ソリューション](#manual-instrumentation-dotnet)」セクションのコード例を示します。または、「[ゼロコード自動計装ソリューション](#zero-code-instrumentation-dotnet)」セクションでアプリケーションのソースコードを変更することなく、X-Ray 手動計装から OpenTelemetry 自動計装ソリューションに移行して .NET アプリケーションを計装することもできます。

**Topics**
+ [ゼロコード自動計装ソリューション](#zero-code-instrumentation-dotnet)
+ [SDK を使用した手動計装ソリューション](#manual-instrumentation-dotnet)
+ [トレースデータを手動で作成する](#manual-trace-creation-dotnet)
+ [受信リクエストのトレース (ASP.NET および ASP.NET Core 計装)](#tracing-incoming-requests-dotnet)
+ [AWS SDK 計測](#aws-sdk-instrumentation-dotnet)
+ [送信 HTTP 呼び出しの計測](#http-instrumentation-dotnet)
+ [他のライブラリの計装サポート](#other-libraries-dotnet)
+ [Lambda 計装](#lambda-instrumentation)

## ゼロコード自動計装ソリューション
<a name="zero-code-instrumentation-dotnet"></a>

OpenTelemetry は、ゼロコードの自動計装ソリューションを提供します。これらのソリューションでは、アプリケーションコードを変更することなくリクエストをトレースします。

**OpenTelemetry ベースの自動計装オプション**

1.  AWS Distro for OpenTelemetry (ADOT) auto-Instrumentation for .NET の使用 – .NET アプリケーションを自動的に計測するには、[AWS 「 Distro for OpenTelemetry .NET Auto-Instrumentation](https://aws-otel.github.io/docs/getting-started/dotnet-sdk/auto-instr)」を参照してください。

   (オプション) ADOT .NET 自動計測 AWS を使用して でアプリケーションを自動的に計測する場合、CloudWatch Application Signals を有効にして次の操作を行います。
   + 現在のアプリケーションの状態をモニタリングする
   + ビジネス目標に対する長期的なアプリケーションのパフォーマンスを追跡する
   + アプリケーション、サービス、依存関係をアプリケーション中心の統合ビューで取得する
   + アプリケーションの状態をモニタリングしてトリアージする

   詳細については、「[Application Signals](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Application-Monitoring-Sections.html)」を参照してください。

1. OpenTelemetry .Net ゼロコード自動計測の使用 – OpenTelemetry .Net を使用して自動的に計測するには、[AWS 「 Distro for OpenTelemetry .NET Auto-Instrumentation を使用したトレースとメトリクス](https://aws-otel.github.io/docs/getting-started/dotnet-sdk/auto-instr)」を参照してください。

## SDK を使用した手動計装ソリューション
<a name="manual-instrumentation-dotnet"></a>

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

.NET ウェブアプリケーションの場合、X-Ray SDK は `Web.config` ファイルの appSettings セクションで設定されます。

Web.config の例

```
<configuration>
  <appSettings>
    <add key="AWSXRayPlugins" value="EC2Plugin"/>
  </appSettings>
</configuration>
```

.NET Core では、`XRay` という名前の最上位キーを持つ `appsettings.json` という名前のファイルが使用され、X-Ray レコーダーを初期化するための設定オブジェクトが構築されます。

.NET `appsettings.json` の例

```
{
  "XRay": {
    "AWSXRayPlugins": "EC2Plugin"
  }
}
```

.NET Core Program.cs の例 – レコーダー構成

```
using Amazon.XRay.Recorder.Core;
...
AWSXRayRecorder.InitializeInstance(configuration);
```

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

****

以下の依存関係を追加します。

```
dotnet add package OpenTelemetry
dotnet add package OpenTelemetry.Contrib.Extensions.AWSXRay
dotnet add package OpenTelemetry.Sampler.AWS --prerelease
dotnet add package OpenTelemetry.Resources.AWS
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol
dotnet add package OpenTelemetry.Extensions.Hosting
dotnet add package OpenTelemetry.Instrumentation.AspNetCore
```

.NET アプリケーションの場合は、グローバルな TracerProvider をセットアップして OpenTelemetry SDK を設定します。次の設定例では、`ASP.NET Core` の計装も有効にします。`ASP.NET` を計装するには、「[受信リクエストのトレース (ASP.NET および ASP.NET Core 計装)](#tracing-incoming-requests-dotnet)」を参照してください。他のフレームワークで OpenTelemetry を使用する場合、サポートされているフレームワークのその他のライブラリについては、「[Registry](https://opentelemetry.io/ecosystem/registry/)」を参照してください。

以下のコンポーネントを設定することをお勧めします。
+ `An OTLP Exporter` – CloudWatch エージェント/OpenTelemetry コレクターへのトレースのエクスポートに必要です。
+  AWS X-Ray プロパゲーター – [AWS X-Ray と統合されたサービス](https://docs.aws.amazon.com/xray/latest/devguide/xray-services.html)にトレースコンテキストを伝達するために必要です
+  AWS X-Ray リモートサンプラー – [X-Ray サンプリングルールを使用してリクエストをサンプリング](https://docs.aws.amazon.com/xray/latest/devguide/xray-console-sampling.html)する必要がある場合に必要です
+ `Resource Detectors` (Amazon EC2 Resource Detector など) – アプリケーションを実行しているホストのメタデータを検出します。

```
using OpenTelemetry;
using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace;
using OpenTelemetry.Sampler.AWS;
using OpenTelemetry.Trace;
using OpenTelemetry.Resources;

var builder = WebApplication.CreateBuilder(args);

var serviceName = "MyServiceName";
var serviceVersion = "1.0.0";

var resourceBuilder = ResourceBuilder
    .CreateDefault()
    .AddService(serviceName: serviceName)
    .AddAWSEC2Detector();

builder.Services.AddOpenTelemetry()
    .ConfigureResource(resource => resource
        .AddAWSEC2Detector()
        .AddService(
            serviceName: serviceName,
            serviceVersion: serviceVersion))
    .WithTracing(tracing => tracing
        .AddSource(serviceName)
        .AddAspNetCoreInstrumentation()
        .AddOtlpExporter()
        .SetSampler(AWSXRayRemoteSampler.Builder(resourceBuilder.Build())
            .SetEndpoint("http://localhost:2000")
            .Build()));

Sdk.SetDefaultTextMapPropagator(new AWSXRayPropagator()); // configure  X-Ray propagator
```

コンソールアプリに OpenTelemetry を使用するには、プログラムの起動時に次の OpenTelemetry 設定を追加します。

```
using OpenTelemetry;
using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace;
using OpenTelemetry.Trace;
using OpenTelemetry.Resources;

var serviceName = "MyServiceName";

var resourceBuilder = ResourceBuilder
    .CreateDefault()
    .AddService(serviceName: serviceName)
    .AddAWSEC2Detector();

var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .AddSource(serviceName)
    .ConfigureResource(resource =>
        resource
            .AddAWSEC2Detector()
            .AddService(
                serviceName: serviceName,
                serviceVersion: serviceVersion
            )
        )
    .AddOtlpExporter() // default address localhost:4317
    .SetSampler(new TraceIdRatioBasedSampler(1.00))
    .Build();

Sdk.SetDefaultTextMapPropagator(new AWSXRayPropagator()); // configure  X-Ray propagator
```

------

## トレースデータを手動で作成する
<a name="manual-trace-creation-dotnet"></a>

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

X-Ray SDK では、X-Ray セグメントとサブセグメントを手動で作成するには、`BeginSegment` メソッドと `BeginSubsegment` メソッドが必要でした。

```
using Amazon.XRay.Recorder.Core;

AWSXRayRecorder.Instance.BeginSegment("segment name"); // generates `TraceId` for you
try
{
    // Do something here
    // can create custom subsegments
    AWSXRayRecorder.Instance.BeginSubsegment("subsegment name");
    try
    {
        DoSometing();
    }
    catch (Exception e)
    {
        AWSXRayRecorder.Instance.AddException(e);
    }
    finally
    {
        AWSXRayRecorder.Instance.EndSubsegment();
    }
}
catch (Exception e)
{
    AWSXRayRecorder.Instance.AddException(e);
}
finally
{
    AWSXRayRecorder.Instance.EndSegment();
}
```

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

.NET では、アクティビティ API を使用してカスタムスパンを作成することで、計装ライブラリでキャプチャされない内部アクティビティのパフォーマンスをモニタリングできます。Server タイプのスパンのみが X-Ray セグメントに変換され、他のすべてのスパンは X-Ray サブセグメントに変換されることに注意してください。

必要に応じて `ActivitySource` インスタンスをいくつでも作成できますが、アプリケーション/サービス全体でインスタンスを 1 つだけ作成することをお勧めします。

```
using System.Diagnostics;

ActivitySource activitySource = new ActivitySource("ActivitySourceName", "ActivitySourceVersion");


...


using (var activity = activitySource.StartActivity("ActivityName", ActivityKind.Server)) // this will be translated to a X-Ray Segment
{
    // Do something here

    using (var internalActivity = activitySource.StartActivity("ActivityName", ActivityKind.Internal)) // this will be translated to an X-Ray Subsegment
    {
        // Do something here
    }
}
```

**OpenTelemetry SDK を使用してトレースに注釈とメタデータを追加する**

アクティビティで `SetTag` メソッドを使用して、カスタムのキーと値のペアを属性としてスパンに追加することもできます。デフォルトでは、すべてのスパン属性は X-Ray の未加工データのメタデータに変換されることに注意してください。属性がメタデータではなく注釈に変換されるようにするには、その属性のキーを `aws.xray.annotations` 属性のリストに追加します。

```
using (var activity = activitySource.StartActivity("ActivityName", ActivityKind.Server)) // this will be translated to a X-Ray Segment
{
    activity.SetTag("metadataKey", "metadataValue");
    activity.SetTag("annotationKey", "annotationValue");
    string[] annotationKeys = {"annotationKey"};
    activity.SetTag("aws.xray.annotations", annotationKeys);

    // Do something here

    using (var internalActivity = activitySource.StartActivity("ActivityName", ActivityKind.Internal)) // this will be translated to an X-Ray Subsegment
    {
        // Do something here
    }
}
```

**OpenTelemetry 自動計装を使用する**

.NET 用の OpenTelemetry 自動計装ソリューションを使用している場合、アプリケーションで手動計装を実行する必要がある場合があります。例えば、自動計装ライブラリでカバーされていないセクションのコードをアプリケーション自体で計装する場合などです。

グローバルな `TracerProvider` は 1 つしか存在できないため、自動計装と一緒に使用する場合、手動計装は独自の `TracerProvider` をインスタンス化できません。`TracerProvider` を使用すると、OpenTelemetry SDK で自動計装または手動計装を使用する場合も、カスタムの手動トレースは同じように機能します。

------

## 受信リクエストのトレース (ASP.NET および ASP.NET Core 計装)
<a name="tracing-incoming-requests-dotnet"></a>

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

ASP.NET アプリケーションによって処理されるリクエストを計装する場合、`global.asax` ファイルの `Init` メソッドで `RegisterXRay` を呼び出す方法の詳細については、「[https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-dotnet-messagehandler.html](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-dotnet-messagehandler.html)」を参照してください。

```
AWSXRayASPNET.RegisterXRay(this, "MyApp");
```

ASP.NET Core アプリケーションによって処理されるリクエストを計装する場合は、Startup クラスの `Configure` メソッドの他のミドルウェアの前に `UseXRay` メソッドが呼び出されます。

```
app.UseXRay("MyApp");
```

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

OpenTelemetry には、ASP.NET および ASP.NET Core の受信ウェブリクエストのトレースを収集するための計装ライブラリも用意されています。次のセクションでは、トレーサープロバイダーの作成時に [ASP.NET](https://learn.microsoft.com/en-us/aspnet/overview) または [ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/?view=aspnetcore-9.0) 計装を追加する方法など、OpenTelemetry 設定でこれらのライブラリ計装を追加および有効にするために必要な手順を示します。

OpenTelemetry.Instrumentation.AspNet を有効にする方法については、「[Steps to enable OpenTelemetry.Instrumentation.AspNet](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/src/OpenTelemetry.Instrumentation.AspNet#steps-to-enable-opentelemetryinstrumentationaspnet)」を参照してください。また、OpenTelemetry.Instrumentation.AspNetCore を有効にする方法については、「[Steps to enable OpenTelemetry.Instrumentation.AspNetCore](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/src/OpenTelemetry.Instrumentation.AspNetCore#steps-to-enable-opentelemetryinstrumentationaspnetcore)」を参照してください。

------

## AWS SDK 計測
<a name="aws-sdk-instrumentation-dotnet"></a>

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

を呼び出して、すべての AWS SDK クライアントをインストールします`RegisterXRayForAllServices()`。

```
using Amazon.XRay.Recorder.Handlers.AwsSdk;
AWSSDKHandler.RegisterXRayForAllServices(); //place this before any instantiation of AmazonServiceClient
AmazonDynamoDBClient client = new AmazonDynamoDBClient(RegionEndpoint.USWest2); // AmazonDynamoDBClient is automatically registered with X-Ray
```

特定の AWS サービスクライアントの計測には、次のいずれかの方法を使用します。

```
AWSSDKHandler.RegisterXRay<IAmazonDynamoDB>(); // Registers specific type of AmazonServiceClient : All instances of IAmazonDynamoDB created after this line are registered
AWSSDKHandler.RegisterXRayManifest(String path); // To configure custom AWS Service Manifest file. This is optional, if you have followed "Configuration" section
```

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

次のコード例では、次の依存関係が必要です。

```
dotnet add package OpenTelemetry.Instrumentation.AWS
```

 AWS SDK を計測するには、Global TracerProvider がセットアップされている OpenTelemetry SDK 設定を更新します。

```
builder.Services.AddOpenTelemetry()
    ...
    .WithTracing(tracing => tracing
        .AddAWSInstrumentation()
        ...
```

------

## 送信 HTTP 呼び出しの計測
<a name="http-instrumentation-dotnet"></a>

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

X-Ray .NET SDK は、`System.Net.HttpWebRequest` を使用する場合は拡張機能メソッド `GetResponseTraced()` または `GetAsyncResponseTraced()` を使用して、または `System.Net.Http.HttpClient` を使用する場合は `HttpClientXRayTracingHandler` ハンドラーを使用して、送信 HTTP 呼び出しをトレースします。

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

次のコード例では、次の依存関係が必要です。

```
dotnet add package OpenTelemetry.Instrumentation.Http
```

`System.Net.Http.HttpClient` と `System.Net.HttpWebRequest` を計装するには、グローバルな TracerProvider がセットアップされている OpenTelemetry SDK 設定を更新します。

```
builder.Services.AddOpenTelemetry()
    ...
    .WithTracing(tracing => tracing
        .AddHttpClientInstrumentation()
        ...
```

------

## 他のライブラリの計装サポート
<a name="other-libraries-dotnet"></a>

OpenTelemetry レジストリで .NET 計装ライブラリを検索してフィルタリングし、OpenTelemetry がライブラリの計装をサポートしているかどうかを確認できます。検索を開始するには、「[Registry](https://opentelemetry.io/ecosystem/registry/)」を参照してください。

## Lambda 計装
<a name="lambda-instrumentation"></a>

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

Lambda で X-Ray SDK を使用するには、次の手順が必要でした。

1. Lambda 関数で*アクティブトレース*を有効にする

1. Lambda サービスで、ハンドラーの呼び出しを表すセグメントを作成する

1. X-Ray SDK を使用してサブセグメントまたは計装ライブラリを作成する

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

 AWS 販売された Lambda レイヤーを使用して Lambda を自動的に計測できます。以下の 2 つのソリューションがあります。
+ (推奨) [AWS OpenTelemetry 用の Lambda Layer](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-application-signals.html)
+ パフォーマンスを向上させるには、`OpenTelemetry Manual Instrumentation` を使用して Lambda 関数の OpenTelemetry トレースを生成することを検討してください。

------

** AWS Lambda の OpenTelemetry 手動計測**

以下は、Lambda 関数コード (計装なし) の例です。

```
using System;
using System.Text;
using System.Threading.Tasks;
using Amazon.Lambda.Core;
using Amazon.S3;
using Amazon.S3.Model;

// Assembly attribute to enable Lambda function logging
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace ExampleLambda;

public class ListBucketsHandler
{
    private static readonly AmazonS3Client s3Client = new();

    // new Lambda function handler passed in
    public async Task<string> HandleRequest(object input, ILambdaContext context)
    {
        try
        {
            var DoListBucketsAsyncResponse = await DoListBucketsAsync();
            context.Logger.LogInformation($"Results: {DoListBucketsAsyncResponse.Buckets}");

            context.Logger.LogInformation($"Successfully called ListBucketsAsync");
            return "Success!";
        }
        catch (Exception ex)
        {
            context.Logger.LogError($"Failed to call ListBucketsAsync: {ex.Message}");
            throw;
        }
    }

    private async Task<ListBucketsResponse> DoListBucketsAsync()
    {
        try
        {
            var putRequest = new ListBucketsRequest
            {
            };

            var response = await s3Client.ListBucketsAsync(putRequest);
            return response;
        }
        catch (AmazonS3Exception ex)
        {
            throw new Exception($"Failed to call ListBucketsAsync: {ex.Message}", ex);
        }
    }
}
```

Lambda ハンドラーと Amazon S3 クライアントを手動で計装するには、次の手順を実行します。

1. TracerProvider のインスタンス化 – TracerProvider は、`XrayUdpSpanExporter`、ParentBased Always On サンプラー、および `Resource` で設定し、`service.name` は Lambda 関数名に設定することをお勧めします。

1. を呼び出し`AddAWSInstrumentation()`て SDK クライアント計測を に追加することで、OpenTemetry SDK 計測を使用して Amazon S3 クライアントを計測します。 OpenTemetry AWS AWS `TracerProvider`

1. 元の Lambda 関数と同じ署名を持つラッパー関数を作成します。`AWSLambdaWrapper.Trace()` API を呼び出し、`TracerProvider`、元の Lambda 関数、およびその入力をパラメータとして渡します。ラッパー関数を Lambda ハンドラー入力として設定します。

次のコード例では、次の依存関係が必要です。

```
dotnet add package OpenTelemetry.Instrumentation.AWSLambda
dotnet add package OpenTelemetry.Instrumentation.AWS
dotnet add package OpenTelemetry.Resources.AWS
dotnet add package AWS.Distro.OpenTelemetry.Exporter.Xray.Udp
```

次のコードは、必要な変更が行われた後の Lambda 関数を示しています。追加のカスタムスパンを作成すると、自動的に提供されるスパンを補完できます。

```
using Amazon.Lambda.Core;
using Amazon.S3;
using Amazon.S3.Model;
using OpenTelemetry;
using OpenTelemetry.Instrumentation.AWSLambda;
using OpenTelemetry.Trace;
using AWS.Distro.OpenTelemetry.Exporter.Xray.Udp;
using OpenTelemetry.Resources;

// Assembly attribute to enable Lambda function logging
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace ExampleLambda;

public class ListBucketsHandler
{
    private static readonly AmazonS3Client s3Client = new();

    TracerProvider tracerProvider = Sdk.CreateTracerProviderBuilder()
        .AddAWSLambdaConfigurations()
        .AddProcessor(
            new SimpleActivityExportProcessor(
                // AWS_LAMBDA_FUNCTION_NAME Environment Variable will be defined in AWS Lambda Environment
                new XrayUdpExporter(ResourceBuilder.CreateDefault().AddService(Environment.GetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME")).Build())
            )
        )
        .AddAWSInstrumentation()
        .SetSampler(new ParentBasedSampler(new AlwaysOnSampler()))
        .Build();

    // new Lambda function handler passed in
    public async Task<string> HandleRequest(object input, ILambdaContext context)
    => await AWSLambdaWrapper.Trace(tracerProvider, OriginalHandleRequest, input, context);

    public async Task<string> OriginalHandleRequest(object input, ILambdaContext context)
    {
        try
        {
            var DoListBucketsAsyncResponse = await DoListBucketsAsync();
            context.Logger.LogInformation($"Results: {DoListBucketsAsyncResponse.Buckets}");

            context.Logger.LogInformation($"Successfully called ListBucketsAsync");
            return "Success!";
        }
        catch (Exception ex)
        {
            context.Logger.LogError($"Failed to call ListBucketsAsync: {ex.Message}");
            throw;
        }
    }

    private async Task<ListBucketsResponse> DoListBucketsAsync()
    {
        try
        {
            var putRequest = new ListBucketsRequest
            {
            };

            var response = await s3Client.ListBucketsAsync(putRequest);
            return response;
        }
        catch (AmazonS3Exception ex)
        {
            throw new Exception($"Failed to call ListBucketsAsync: {ex.Message}", ex);
        }
    }
}
```

この Lambda を呼び出すと、CloudWatch コンソールのトレースマップに次のトレースが表示されます。

![\[.Net の CloudWatch コンソールのトレースマップ\]](http://docs.aws.amazon.com/ja_jp/xray/latest/devguide/images/deprecation_dotnet.png)
