OpenTelemetry .NET への移行 - AWS X-Ray

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

OpenTelemetry .NET への移行

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

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

ゼロコード自動計装ソリューション

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

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

  1. AWS Distro for OpenTelemetry (ADOT) auto-Instrumentation for .NET の使用 – .NET アプリケーションを自動的に計測するには、AWS 「 Distro for OpenTelemetry .NET Auto-Instrumentation」を参照してください。

    (オプション) ADOT .NET 自動計測 AWS を使用して でアプリケーションを自動的に計測する場合、CloudWatch Application Signals を有効にして次の操作を行います。

    • 現在のアプリケーションの状態をモニタリングする

    • ビジネス目標に対する長期的なアプリケーションのパフォーマンスを追跡する

    • アプリケーション、サービス、依存関係をアプリケーション中心の統合ビューで取得する

    • アプリケーションの状態をモニタリングしてトリアージする

    詳細については、「Application Signals」を参照してください。

  2. OpenTelemetry .Net ゼロコード自動計測の使用 – OpenTelemetry .Net を使用して自動的に計測するには、AWS 「 Distro for OpenTelemetry .NET Auto-Instrumentation を使用したトレースとメトリクス」を参照してください。

SDK を使用した手動計装ソリューション

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 計装)」を参照してください。他のフレームワークで OpenTelemetry を使用する場合、サポートされているフレームワークのその他のライブラリについては、「Registry」を参照してください。

以下のコンポーネントを設定することをお勧めします。

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

トレースデータを手動で作成する

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 計装)

With X-Ray SDK

ASP.NET アプリケーションによって処理されるリクエストを計装する場合、global.asax ファイルの Init メソッドで RegisterXRay を呼び出す方法の詳細については、「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 または ASP.NET Core 計装を追加する方法など、OpenTelemetry 設定でこれらのライブラリ計装を追加および有効にするために必要な手順を示します。

OpenTelemetry.Instrumentation.AspNet を有効にする方法については、「Steps to enable OpenTelemetry.Instrumentation.AspNet」を参照してください。また、OpenTelemetry.Instrumentation.AspNetCore を有効にする方法については、「Steps to enable OpenTelemetry.Instrumentation.AspNetCore」を参照してください。

AWS SDK 計測

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 呼び出しの計測

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.HttpClientSystem.Net.HttpWebRequest を計装するには、グローバルな TracerProvider がセットアップされている OpenTelemetry SDK 設定を更新します。

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

他のライブラリの計装サポート

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

Lambda 計装

With X-Ray SDK

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

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

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

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

With OpenTelemetry-based solutions

AWS 販売された Lambda レイヤーを使用して Lambda を自動的に計測できます。以下の 2 つのソリューションがあります。

  • (推奨) CloudWatch Application Signals Lambda レイヤー

  • パフォーマンスを向上させるには、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 関数名に設定することをお勧めします。

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

  3. 元の 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 コンソールのトレースマップ