入门 ASP.NET Core 中的日志

了解如何在 ASP.NET Core 应用程序中使用 OpenTelemetry .NET 日志

本指南将向您展示如何在 ASP.NET Core 应用程序中使用 OpenTelemetry .NET 日志。

先决条件

创建 ASP.NET Core 应用程序

创建一个新的 ASP.NET Core Web 应用程序

dotnet new web -o aspnetcoreapp
cd aspnetcoreapp

添加 OpenTelemetry 日志

安装所需的 OpenTelemetry 包

dotnet add package OpenTelemetry.Exporter.Console
dotnet add package OpenTelemetry.Extensions.Hosting

使用以下代码更新 Program.cs 文件

using OpenTelemetry.Logs;
using OpenTelemetry.Resources;

var builder = WebApplication.CreateBuilder(args);

// For instructional purposes only, disable the default .NET logging providers.
// We remove the console logging provider in this demo to use the verbose
// OpenTelemetry console exporter instead. For most development and production
// scenarios the default console provider works well and there is no need to
// clear these providers.
builder.Logging.ClearProviders();

// Add OpenTelemetry logging provider by calling the WithLogging extension.
builder.Services.AddOpenTelemetry()
    .ConfigureResource(r => r.AddService(builder.Environment.ApplicationName))
    .WithLogging(logging => logging
        /* Note: ConsoleExporter is used for demo purpose only. In production
           environment, ConsoleExporter should be replaced with other exporters
           (for example, OTLP Exporter). */
        .AddConsoleExporter());

var app = builder.Build();

app.MapGet("/", (ILogger<Program> logger) =>
{
    logger.FoodPriceChanged("artichoke", 9.99);

    return "Hello from OpenTelemetry Logs!";
});

app.Logger.StartingApp();

app.Run();

internal static partial class LoggerExtensions
{
    [LoggerMessage(LogLevel.Information, "Starting the app...")]
    public static partial void StartingApp(this ILogger logger);

    [LoggerMessage(LogLevel.Information, "Food `{name}` price changed to `{price}`.")]
    public static partial void FoodPriceChanged(this ILogger logger, string name, double price);
}

运行应用程序

运行应用程序

dotnet run

浏览到控制台中显示的 URL(例如,https://:5000)。

您应该会在控制台中看到类似以下内容的日志输出:

LogRecord.Timestamp:               2023-09-06T22:59:17.9787564Z
LogRecord.CategoryName:            getting-started-aspnetcore
LogRecord.Severity:                Info
LogRecord.SeverityText:            Information
LogRecord.Body:                    Starting the app...
LogRecord.Attributes (Key:Value):
    OriginalFormat (a.k.a Body): Starting the app...
LogRecord.EventId:                 225744744
LogRecord.EventName:               StartingApp

...

LogRecord.Timestamp:               2023-09-06T23:00:46.1639248Z
LogRecord.TraceId:                 3507087d60ae4b1d2f10e68f4e40784a
LogRecord.SpanId:                  c51be9f19c598b69
LogRecord.TraceFlags:              None
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

恭喜!您现在正在 ASP.NET Core 应用程序中使用 OpenTelemetry 收集日志。

工作原理

替换默认日志记录提供程序

出于演示目的,示例清除了默认的 .NET 日志记录提供程序,以便更好地展示 OpenTelemetry 控制台输出。

// For instructional purposes only, disable the default .NET logging providers.
// We remove the console logging provider in this demo to use the verbose
// OpenTelemetry console exporter instead. For most development and production
// scenarios the default console provider works well and there is no need to
// clear these providers.
builder.Logging.ClearProviders();

在实际应用程序中,您通常会保留默认提供程序,并将 OpenTelemetry 与它们一起添加。

添加 OpenTelemetry 日志记录

该应用程序使用 AddOpenTelemetry() 扩展方法配置 OpenTelemetry。

builder.Services.AddOpenTelemetry()
    .ConfigureResource(r => r.AddService(builder.Environment.ApplicationName))
    .WithLogging(logging => logging
        .AddConsoleExporter());

此代码

  1. 将 OpenTelemetry 添加到服务集合中
  2. 配置资源信息(例如服务名称)
  3. 使用 WithLogging() 扩展设置日志记录
  4. 添加一个控制台导出器,将日志输出到控制台

使用依赖注入进行日志记录

ASP.NET Core 为日志记录提供了内置的依赖注入。示例使用此功能将日志记录器注入到请求处理程序中。

app.MapGet("/", (ILogger<Program> logger) =>
{
    logger.FoodPriceChanged("artichoke", 9.99);

    return "Hello from OpenTelemetry Logs!";
});

ILogger<Program> 参数由框架自动注入,日志将包含类别名称“Program”。

使用 LoggerMessage 源生成

该示例使用 编译时日志源生成来实现高性能结构化日志记录。

internal static partial class LoggerExtensions
{
    [LoggerMessage(LogLevel.Information, "Starting the app...")]
    public static partial void StartingApp(this ILogger logger);

    [LoggerMessage(LogLevel.Information, "Food `{name}` price changed to `{price}`.")]
    public static partial void FoodPriceChanged(this ILogger logger, string name, double price);
}

这种方法

  • 比字符串插值具有更好的性能。
  • 确保日志参数的类型安全。
  • 生成带有命名参数的结构化日志。
  • 自动在 LogRecord 上生成 EventName

了解更多