迁移到 OpenTelemetry .NET - Amazon X-Ray
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

迁移到 OpenTelemetry .NET

在.NET 应用程序中使用 X-Ray Tracing 时,使用带有手动操作的 X-Ray .NET SDK 进行检测。

本节在使用 SDK 的手动仪器解决方案部分中提供了从 X-Ray 手动检测解决方案迁移到.NET 的 OpenTelemetry 手动检测解决方案的代码示例。或者,您可以从 X-Ray 手动检测迁移到 OpenTelemetry 自动检测解决方案,以检验.NET 应用程序,而不必零代码自动检测解决方案在本节中修改应用程序源代码。

零代码自动检测解决方案

OpenTelemetry 提供零代码自动检测解决方案。这些解决方案无需更改应用程序代码即可跟踪请求。

OpenTelemetry基于自动仪表选项

  1. 使用适用于.NET 的 OpenTelemetry (ADOT) 自动检测 Amazon 发行版 — 要自动检测.NET 应用程序,请参阅使用适用于.NET 自动检测的Amazon 发行版进行跟踪和衡量指标。 OpenTelemetry

    (可选)在 CloudWatch 使用 ADOT .NET 自动检测应用程序时启用应用程序信号, Amazon 以:

    • 监控当前应用程序的运行状况

    • 根据业务目标跟踪长期应用程序性能

    • 获得以应用程序为中心的统一视图,了解您的应用程序、服务和依赖关系

    • 监控和分类应用程序运行状况

    有关更多信息,请参阅 Application Signals

  2. 使用 OpenTelemetry .Net 零代码自动检测 — 要自动使用 OpenTelemetry .NET 进行检测,请参阅使用.NE OpenTelemetry T 自动检测 Amazon 发行版进行跟踪和衡量指标

使用 SDK 的手动仪器解决方案

Tracing configuration with X-Ray SDK

对于.NET Web 应用程序,X-Ray SDK 是在Web.config文件的 AppSettings 部分配置的。

网页配置示例

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

对于.NET Core,使用名appsettings.jsonXRay为的顶级密钥命名的文件,然后构建一个配置对象来初始化 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 应用程序,请通过设置全局来配置 OpenTelemetry SDK TracerProvider。以下示例配置还为启用了检测功能ASP.NET Core。要进行仪器ASP.NET,请参阅跟踪传入的请求(ASP.NET 和 ASP.NET 核心工具)。要与其他框架 OpenTelemetry 一起使用,请参阅 Regist ry 以获取更多支持的框架的库。

建议您配置以下组件:

  • An OTLP Exporter— 将跟踪导出到 CloudWatch Agent/Collecto OpenTelemetry r 时需要此选项

  • Amazon X-Ray 传播器 — 将跟踪上下文传播到与 X-Ray 集成的Amazon 服务所必需的

  • Amazon X-Ray-Remote 采样器 — 如果您需要使用 X-Ray 采样规则对请求进行采样,则为必填项

  • Resource Detectors(例如,Amazon EC2 资源检测器)-检测运行您的应用程序的主机的元数据

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,需要使用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方法将自定义键值对作为属性添加到跨度上。请注意,默认情况下,所有 span 属性都将转换为 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,因此TracerProvider如果与自动检测一起使用,则手动插桩不应自行实例化。使用TracerProvider时,自定义手动跟踪的工作方式与通过 OpenTelemetry SDK 使用自动检测或手动检测的方式相同。

跟踪传入的请求(ASP.NET 和 ASP.NET 核心工具)

With X-Ray SDK

要检测 ASP.NET 应用程序提供的请求,https://docs.amazonaws.cn/xray/latest/devguide/xray-sdk-dotnet-messagehandler.html请参阅,了解有关如何调用RegisterXRayglobal.asax文件Init方法的信息。

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 .Instrumention 的信息。 AspNet,请参阅启用 OpenTelemetry .Instrumention 的步骤。 AspNet以及有关如何启用 OpenTelemetry .Instrumention 的信息。 AspNetCore,请参阅启用 OpenTelemetry .Instrumention 的步骤。 AspNetCore

Amazon 软件开发工具包工具

With X-Ray SDK

通过调用安装所有 Amazon 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

使用以下方法之一进行特定的 Amazon 服务客户端检测。

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 Amazon Service Manifest file. This is optional, if you have followed "Configuration" section
With OpenTelemetry SDK

对于以下代码示例,您将需要以下依赖关系:

dotnet add package OpenTelemetry.Instrumentation.AWS

要对 S Amazon DK 进行检测,请更新设置全局 TracerProvider 的 OpenTelemetry SDK 配置。

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

检测传出 HTTP 调用

With X-Ray SDK

X-Ray .NET SDK 通过扩展方法GetResponseTraced()或在使用时跟踪传出的 HTTP 调用System.Net.HttpWebRequest,或者GetAsyncResponseTraced()在使用时使用HttpClientXRayTracingHandler处理程序来跟踪传出的 HTTP 调用System.Net.Http.HttpClient

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 支持插入。请查看注册表开始搜索。

Lambda 仪器

With X-Ray SDK

要将 X-Ray 软件开发工具包与 Lambda 一起使用,需要执行以下步骤:

  1. 在 Lambda 函数上启用主动跟踪

  2. Lambda 服务会创建一个表示处理程序调用的分段

  3. 使用 X-Ray SDK 创建子分段或仪器库

With OpenTelemetry-based solutions

您可以使用已打开的 Lambda 图层自动检测您的 Lambda Amazon 。有两种解决方案:

OpenTelemetry 针对 Amazon Lambda 的手动检测

以下是 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. 实例化 a TracerProvider — 建议配置 TracerProvider 为 Always On Sampler,service.name设置为 Lambda 函数名称。XrayUdpSpanExporter ParentBased Resource

  2. 通过调用将 S OpenTemetry Amazon DK 客户端插桩添加到 Amazon S3 客户端,使用软件开发工具 Amazon 包插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 控制台中的追踪地图