日志关联

了解如何在 OpenTelemetry .NET 中将日志与跟踪进行关联

本指南解释了在 OpenTelemetry .NET 中如何将日志与跟踪进行关联。

日志数据模型对关联的支持

The OpenTelemetry Logging Data Model defines fields which allow a log to be correlated with a span (Activity in .NET). The fields TraceId and SpanId allow a log to be correlated to the corresponding Activity

OpenTelemetry .NET 中的自动关联

在 OpenTelemetry .NET SDK 中,无需用户操作即可启用关联。如果存在活动(即 Activity.Current),SDK 会通过填充 TraceIdSpanIdTraceFlags 字段,自动启用日志与 Activity 的关联。

示例

下面是一个简单的示例,展示了如何在活动 Activity 的上下文中发出日志

using System;
using System.Diagnostics;
using Microsoft.Extensions.Logging;
using OpenTelemetry;
using OpenTelemetry.Logs;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;

// Create a logger factory with OpenTelemetry
using var loggerFactory = LoggerFactory.Create(builder =>
{
    builder.AddOpenTelemetry(options =>
    {
        options.AddConsoleExporter();
    });
});

// Create a tracer provider
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .AddSource("MyCompany.MyProduct.MyLibrary")
    .AddConsoleExporter()
    .Build();

// Get a logger instance
var logger = loggerFactory.CreateLogger<Program>();

// Create an activity source
var activitySource = new ActivitySource("MyCompany.MyProduct.MyLibrary");

// Start an activity
using (var activity = activitySource.StartActivity("SayHello"))
{
    // Log within the activity context
    logger.FoodPriceChanged("artichoke", 9.99);
}

// Define extension methods for structured logging
internal static partial class LoggerExtensions
{
    [LoggerMessage(LogLevel.Information, "Food `{name}` price changed to `{price}`.")]
    public static partial void FoodPriceChanged(this ILogger logger, string name, double price);
}

运行应用程序将在控制台上显示以下输出

LogRecord.Timestamp:               2024-01-26T17:55:39.2273475Z
LogRecord.TraceId:                 aed89c3b250fb9d8e16ccab1a4a9bbb5
LogRecord.SpanId:                  bd44308753200c58
LogRecord.TraceFlags:              Recorded
LogRecord.CategoryName:            Program
LogRecord.Severity:                Info
LogRecord.SeverityText:            Information
LogRecord.Body:                    Food `{name}` price changed to `{price}`.
LogRecord.Attributes (Key:Value):
    name: artichoke
    price: 9.99
    OriginalFormat (a.k.a Body): Food `{name}` price changed to `{price}`.
LogRecord.EventId:                 344095174
LogRecord.EventName:               FoodPriceChanged

...

Activity.TraceId:            aed89c3b250fb9d8e16ccab1a4a9bbb5
Activity.SpanId:             bd44308753200c58
Activity.TraceFlags:         Recorded
Activity.ActivitySourceName: MyCompany.MyProduct.MyLibrary
Activity.DisplayName:        SayHello
Activity.Kind:               Internal
Activity.StartTime:          2024-01-26T17:55:39.2223849Z
Activity.Duration:           00:00:00.0361682
...

如您所见,LogRecord 自动具有 TraceIdSpanId 字段,这些字段与 Activity 中的匹配。这是因为日志是在活动 Activity 的上下文中创建的。

Getting Started with Console 指南中,日志记录是在 Activity 上下文之外进行的,因此 LogRecord 中的这些关联字段未被填充。

Web 应用程序

在 ASP.NET Core 等 Web 应用程序中,请求上下文中进行的所有日志记录都会自动与表示传入请求的 Activity 相关联,从而可以轻松找到与特定请求相关的所有日志。

日志关联的好处

日志关联提供了多项好处

  1. 统一视图:您可以在可观察性工具中以统一视图查看日志和跟踪。
  2. 上下文丰富:日志会通过跟踪上下文得到丰富,使其更具信息量。
  3. 故障排除:在调试问题时,可以快速找到与特定跟踪相关的所有日志。
  4. 性能分析:了解影响应用程序性能的因素。

了解更多