最佳实践
遵循这些最佳实践,以充分利用 OpenTelemetry .NET 进行追踪。
包版本
使用最新稳定版本的 System.Diagnostics.Activity API,来自 System.Diagnostics.DiagnosticSource 包,无论使用的 .NET 运行时版本是什么。
- 如果您使用的是最新稳定版本的 OpenTelemetry .NET SDK,则无需担心
System.Diagnostics.DiagnosticSource包的版本,因为它已通过包依赖项为您处理。 - 即使在主要版本更新期间,.NET 运行时团队也对
System.Diagnostics.DiagnosticSource的向后兼容性保持高标准,因此此处不存在兼容性问题。
追踪 API
ActivitySource
避免过于频繁地创建 System.Diagnostics.ActivitySource。ActivitySource 相当昂贵,旨在供整个应用程序重用。对于大多数应用程序,可以将其建模为静态只读字段或通过依赖项注入进行单例化。
将点分隔的 UpperCamelCase 用作 ActivitySource.Name。在许多情况下,使用完全限定的类名可能是一个不错的选择。例如:
static readonly ActivitySource MyActivitySource = new("MyCompany.MyProduct.MyLibrary");
Activity
在 设置标签 之前,请检查 Activity.IsAllDataRequested 以获得更好的性能。
using (var activity = MyActivitySource.StartActivity("SayHello"))
{
if (activity != null && activity.IsAllDataRequested == true)
{
activity.SetTag("http.url", "http://www.mywebsite.com");
}
}
使用 Activity.SetTag 来 设置属性。
正确完成或停止 Activity。这可以通过 using 语句隐式完成,这是推荐的做法。您也可以显式调用 Activity.Dispose 或 Activity.Stop。
尚未完成/停止的 Activity 将不会被导出。
避免在循环中调用 Activity.AddEvent。Activity 的设计并非用于处理成百上千个事件,更好的模型是使用 相关日志 或 Activity.Links。例如:
以下代码未正确建模 Activity.Events,很可能存在可用性和性能问题。
private static async Task Test()
{
Activity activity = Activity.Current;
while (true)
{
activity.AddEvent(new ActivityEvent("Processing background task."));
await Task.Delay(1000);
}
}
TracerProvider 管理
避免过于频繁地创建 TracerProvider 实例。TracerProvider 相当昂贵,旨在供整个应用程序重用。对于大多数应用程序,每个进程一个 TracerProvider 实例就足够了。
如果您自行创建 TracerProvider 实例,请管理其生命周期。
一般而言:
- 如果您正在使用 依赖项注入 (DI) (例如 ASP.NET Core 和 .NET Worker)构建应用程序,在大多数情况下,您应该创建
TracerProvider实例并让 DI 管理其生命周期。有关更多信息,请参阅 在 5 分钟内开始使用 OpenTelemetry .NET 追踪 ASP.NET Core 应用程序 教程。 - 如果您在没有 DI 的情况下构建应用程序,请创建一个
TracerProvider实例并显式管理其生命周期。有关更多信息,请参阅 在 5 分钟内开始使用 OpenTelemetry .NET 追踪控制台应用程序 教程。 - 如果您忘记在应用程序结束前处置
TracerProvider实例,可能会由于缺少正确的刷新操作而导致 Activity 被丢弃。 - 如果您过早处置
TracerProvider实例,任何后续的 Activity 都将不会被收集。
关联
在 OpenTelemetry 中,追踪会自动 与日志相关联,并通过 exemplars 与指标相关联。
手动创建 Activity
如 入门 指南所示,手动创建 Activity 非常容易。因此,很容易想创建过多的 Activity(例如,为每个方法调用创建一个)。除了昂贵之外,过多的 Activity 还会使追踪可视化更加困难。与其手动创建 Activity,不如检查您是否可以利用 instrumention 库,例如 ASP.NET Core、HttpClient,它们不仅会创建并用标签(attributes)填充 Activity,还会负责跨进程边界传播/恢复上下文。
如果 instrumention 库生成的 Activity 缺少您所需的信息,通常建议用该信息丰富现有 Activity,而不是创建新的 Activity。
将静态标签建模为 Resource
像 MachineName、Environment 等在进程生命周期内是静态的标签,应该建模为 Resource,而不是添加到每个 Activity 中。
导致追踪丢失的常见问题
以下是导致追踪丢失的一些常见问题:
- 用于创建 Activity 的
ActivitySource未添加到TracerProvider。使用AddSource方法启用来自给定ActivitySource的 Activity。 TracerProvider过早处置。您需要确保TracerProvider实例保持活动状态才能收集追踪。在典型的应用程序中,会在应用程序启动时构建一个 TracerProvider,并在应用程序关闭时进行处置。对于 ASP.NET Core 应用程序,请使用OpenTelemetry.Extensions.Hosting包中的AddOpenTelemetry和WithTraces方法来正确设置TracerProvider。