遷移至 OpenTelemetry .NET - AWS X-Ray

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

遷移至 OpenTelemetry .NET

在 .NET 應用程式中使用 X-Ray 追蹤時,手動檢測會使用 X-Ray .NET 開發套件。

本節提供 使用 SDK 的手動檢測解決方案區段中的程式碼範例,用於從 X-Ray 手動檢測解決方案遷移至適用於 .NET 的 OpenTelemetry 手動檢測解決方案。或者,您可以從 X-Ray 手動檢測遷移到 OpenTelemetry 自動檢測解決方案到檢測 .NET 應用程式,而無需修改 零程式碼自動檢測解決方案區段中的應用程式原始碼。

零程式碼自動檢測解決方案

OpenTelemetry 提供零程式碼自動檢測解決方案。這些解決方案會追蹤請求,而不需要變更您的應用程式程式碼。

OpenTelemetry 型自動檢測選項

  1. 使用適用於 .NET 的 AWS Distro for OpenTelemetry (ADOT) 自動檢測 – 若要自動檢測 .NET 應用程式,請參閱使用適用於 OpenTelemetry 的 AWS Distro .NET Auto-Instrumentation 追蹤和指標

    (選用) AWS 使用 ADOT .NET 自動檢測在 上自動檢測應用程式時啟用 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 Web 應用程式,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 應用程式,請設定 Global TracerProvider 來設定 OpenTelemetry SDK。下列範例組態也會啟用 的檢測ASP.NET Core。若要檢測 ASP.NET,請參閱 追蹤傳入的請求 (ASP.NET 和 ASP.NET 核心檢測)。若要搭配其他架構使用 OpenTelemetry,請參閱 登錄檔以取得更多支援架構的程式庫。

建議您設定下列元件:

  • An OTLP Exporter – 將追蹤匯出至 CloudWatch Agent/OpenTelemetry Collector 時需要

  • AWS X-Ray 傳播器 – 將追蹤內容傳播至AWS 與 X-Ray 整合的服務時需要

  • AWS X-Ray 遠端取樣器 – 如果您需要使用 X-Ray 取樣規則來取樣請求,則為必要項目

  • 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

手動建立追蹤資料

With X-Ray SDK

使用 X-Ray 開發套件,需要 BeginSegmentBeginSubsegment方法來手動建立 X-Ray 區段和子區段。

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 來建立自訂範圍,以監控檢測程式庫未擷取的內部活動效能。請注意,只有種類的伺服器會轉換為 X-Ray 區段,所有其他範圍則會轉換為 X-Ray 子區段。

您可以視需要建立任意數量的ActivitySource執行個體,但建議在整個應用程式/服務中只有一個執行個體。

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 自動檢測解決方案,而且如果您需要在應用程式中執行手動檢測,例如,針對任何自動檢測程式庫未涵蓋的區段,在應用程式本身內檢測程式碼。

由於只能有一個全域 TracerProviderTracerProvider如果與自動檢測一起使用,則手動檢測不應執行個體化自己的 。TracerProvider 使用 時,透過 OpenTelemetry SDK 使用自動檢測或手動檢測時,自訂手動追蹤的運作方式相同。

追蹤傳入的請求 (ASP.NET 和 ASP.NET 核心檢測)

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 核心應用程式提供的請求,會在啟動類別UseXRay方法中的任何其他中介軟體之前呼叫 Configure方法。

app.UseXRay("MyApp");
With OpenTelemetry SDK

OpenTelemetry 也提供檢測程式庫,以收集 ASP.NET 和 ASP.NET 核心傳入 Web 請求的追蹤。下一節列出為您的 OpenTelemetry 組態新增和啟用這些程式庫檢測所需的步驟,包括如何在建立 Tracer Provider 時新增 ASP.NETASP.NET 核心檢測。

如需如何啟用 OpenTelemetry.Instrumentation.AspNet,請參閱啟用 OpenTelemetry.Instrumentation.AspNet 的步驟,以及有關如何啟用 OpenTelemetry.Instrumentation.AspNetCore,請參閱啟用 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 透過擴充功能方法GetResponseTraced()或使用 GetAsyncResponseTraced()System.Net.HttpWebRequest,或使用 HttpClientXRayTracingHandler 處理常式來追蹤傳出的 HTTP 呼叫System.Net.Http.HttpClient

With OpenTelemetry SDK

針對下列程式碼範例,您將需要下列相依性:

dotnet add package OpenTelemetry.Instrumentation.Http

若要檢測 System.Net.Http.HttpClientSystem.Net.HttpWebRequest,請更新設定 Global TracerProvider 的 OpenTelemetry SDK 組態。

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

其他程式庫的檢測支援

您可以搜尋和篩選適用於 .NET 檢測程式庫的 OpenTelemetry 登錄檔,以了解 OpenTelemetry 是否支援您的程式庫檢測。請參閱 登錄檔以開始搜尋。

Lambda 檢測

With X-Ray SDK

使用 X-Ray 開發套件搭配 Lambda 需要下列程序:

  1. 在 Lambda 函數上啟用主動追蹤

  2. Lambda 服務會建立代表處理常式調用的客群

  3. 使用 X-Ray SDK 建立子區段或檢測程式庫

With OpenTelemetry-based solutions

您可以使用 AWS 付費的 Lambda 層自動檢測 Lambda。有兩種解決方案:

適用於 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 取樣器,以及將 Resourceservice.name設定為 Lambda 函數名稱的 。

  2. 呼叫 將 SDK 用戶端檢測新增至 ,以使用 OpenTemetry AWS AWS SDK 檢測來檢測 AddAWSInstrumentation() Amazon S3 用戶端 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 主控台中的追蹤映射