在 .NET8中使用Serilog进行结构化日志记录

作者:微信公众号:【架构师老卢】
4-27 18:58
29

概述:在构建新的 ASP.NET Core 项目时,应优先设置日志记录,以确保从一开始就具有强大的监视和调试功能。Serilog 是用于 ASP.NET Core 应用程序的最流行的日志记录库。在本文中,我们将学习使用 Serilog 在 ASP.NET Core 应用程序中掌握结构化日志记录所需的所有知识。我们将了解 Serilog 配置、接收器以及您需要遵循的所有最佳实践。这将是您需要参考 .NET 应用程序的主日志记录的唯一指南。为什么选择Serilog?如前所述,Serilog 是一个流行的第三方日志记录库,它通过其日志记录实现插入到 .NET 应用程序的默认实例中。它使应用程序能够将事件记

在构建新的 ASP.NET Core 项目时,应优先设置日志记录,以确保从一开始就具有强大的监视和调试功能。Serilog 是用于 ASP.NET Core 应用程序的最流行的日志记录库。在本文中,我们将学习使用 Serilog 在 ASP.NET Core 应用程序中掌握结构化日志记录所需的所有知识。我们将了解 Serilog 配置、接收器以及您需要遵循的所有最佳实践。这将是您需要参考 .NET 应用程序的主日志记录的唯一指南。

为什么选择Serilog?

如前所述,Serilog 是一个流行的第三方日志记录库,它通过其日志记录实现插入到 .NET 应用程序的默认实例中。它使应用程序能够将事件记录到各种目标,如控制台、文件、数据库、CloudWatch Logs 等。Serilog 提供结构化日志记录,可以帮助您以更简洁的方式存储和分析日志。Serilog 还提供了超级灵活的配置,我们将在本文的后面部分看到。Serilog 是我每次开始新的 ASP.NET 核心项目时都会安装的第一个库!ILogger

在性能方面,由于其异步日志记录和日志消息批处理等功能,Serilog 对应用程序性能的影响接近 0。

除此之外,您还需要了解此库的几个方面。让我们开始吧。

在 ASP.NET Core 中开始使用 Serilog

在此演示中,我将使用 .NET 8 Web API 项目和 Visual Studio 2022 Community Edition。

安装适用于 ASP.NET 核心应用程序的 Serilog 软件包

首先,通过运行以下命令为 ASP.NET Core 应用程序安装 Serilog 软件包。

Install-Package Serilog.AspNetCore

配置 Serilog — 基础知识

安装软件包后,让我们配置 Serilog。为此,请打开并进行以下更改。Program.cs

using Serilog;  
Log.Logger = new LoggerConfiguration()  
    .WriteTo.Console()  
    .CreateLogger();  
try  
{  
    Log.Information("starting server.");  
    var builder = WebApplication.CreateBuilder(args);  
    builder.Host.UseSerilog((context, loggerConfiguration) =>  
    {  
        loggerConfiguration.WriteTo.Console();  
        loggerConfiguration.ReadFrom.Configuration(context.Configuration);  
    });  
    builder.Services.AddEndpointsApiExplorer();  
    builder.Services.AddSwaggerGen();  
    var app = builder.Build();  
    if (app.Environment.IsDevelopment())  
    {  
        app.UseSwagger();  
        app.UseSwaggerUI();  
    }  
    app.UseHttpsRedirection();  
    app.Run();  
}  
catch (Exception ex)  
{  
    Log.Fatal(ex, "server terminated unexpectedly");  
}  
finally  
{  
    Log.CloseAndFlush();  
}
  • 在这里,第 #2 行到 #4 是我们使用 Serilog 创建记录器实例的地方,同时使其能够将日志写入控制台。请注意,这段代码的唯一目的是在 .所以,这只是可选的。Program.cs
  • 从第 #9 行到 #13,我们将 Serilog 添加到我们 ASP.NET 核心应用程序的 DI 容器中。我们在这里定义了 2 个配置,分别写入 Console 和从 读取配置。无论我们在哪里使用界面,这将应用于整个应用程序。此外,这将忽略 appsettings 文件中的配置,而只考虑 .appsettings.jsonILogger<>LoggingSerilogappsettings.json
  • 除此之外,我们还添加了一个 try-catch 块来记录任何类型的应用程序级致命错误。

请注意,默认情况下,我们允许 .NET 应用程序登录到控制台,在第 #11 行。由您来删除它。我使用它是为了将所有日志默认记录在控制台上。在调试过程中有很大帮助。

接下来,打开文件并添加以下内容。如前所述,这里我们跳过了该部分,相反,我们将使用该部分来配置我们的记录器。目前,我们只是坚持基本配置。随着我们的进展,我们将添加更多配置。appsettings.jsonLoggingSerilog

{  
  "Serilog": {  
    "MinimumLevel": {  
      "Default": "Information",  
      "Override": {  
        "Microsoft": "Warning",  
        "Microsoft.AspNetCore.Hosting.Diagnostics": "Error",  
        "Microsoft.Hosting.Lifetime": "Information"  
      }  
    }  
  },  
  "AllowedHosts": "*"  
}

日志记录最低级别 — 了解 Serilog 中的日志级别

如上所述,我们已将默认值设置为 Information,这意味着只会记录高于 Information Level 优先级的日志。要了解这一点,您必须了解 Serilog 中的日志级别和优先级。MinimumLevel

在 Serilog 中,您可以使用 6 个日志级别。在前面的代码片段中,我们使用了 和 。这些是一些常用的日志级别。这有助于确定我们尝试记录的消息的严重性。Log.Information()Log.Fatal()

因此,在我们的应用程序中,将记录信息以上的所有级别,包括信息级别日志。在我们的应用程序设置中,我们为各种上下文定义了自定义的最低级别。例如,仅记录来自库的警告及以上消息。同样,只会记录来自 的错误/致命消息。这样可以超级精确地控制您要登录到 ASP.NET Core 应用程序的内容。MicrosoftMicrosoft.AspNetCore.Hosting.Diagnostics

通过这些更改,如果生成并运行 .NET 应用程序,你将在控制台上看到以下日志。

伊洛格

现在,我们将了解如何使用 ILogger 接口记录消息。为此,我们将创建一个虚拟服务和一个接口,并将其与最小端点连接起来。为此,请创建一个名为 Services 的新文件夹,并添加以下类/接口。

public interface IDummyService  
{  
    void DoSomething();  
}

public class DummyService(ILogger<DummyService> logger) : IDummyService  
{  
    public void DoSomething()  
    {  
        logger.LogInformation("something is done");  
        logger.LogCritical("oops");  
        logger.LogDebug("nothing much");  
    }  
}

因此,我们有一个简单的接口,它有一个名为 的函数,其实现只是记录不同日志级别的消息。DoSomething

接下来,我们必须注册 ,并创建一个使用此服务的最小 API 端点。打开您的文件并添加以下内容。DummyServiceProgram.cs

builder.Services.AddTransient<IDummyService, DummyService>();

这可确保将其注册到应用程序的 DI 容器中。IDummyService

app.MapGet("/", (IDummyService svc) => svc.DoSomething());

而且,上面是在应用程序根目录“/”注册 (GET) API 端点的代码,它反过来调用 Dummy 接口的方法。DoSomething

这就是一切!让我们构建应用程序并运行它。

您将能够在 Swagger 上看到我们的新 API 端点。我已向此端点发送了 GET 请求。

请注意,只有“信息”和“致命”日志可见。这仅仅是因为我们已将“最低日志级别”设置为“信息”,因此将跳过“调试日志”。现在,如果您还想显示调试日志,只需转到您的并将值设置为 Debug。appsettings.jsonSerilog > MinimumLevel > Default

如您所见,只需进行最少的更改,我们就已经将 ASP.NET Core 应用程序完全切换到 Serilog Logging。

配置 Serilog

让我们进入配置!有两种方法可以在 .NET 应用程序中配置 Serilog,这取决于您的要求。您可以使用 Fluent API 以更硬编码的方式配置 Serilog。appsettings.json

通过 appsettings.json 进行配置(推荐)

在前面的代码中,我们曾经确保记录器可以从 中读取 。这是推荐的方法,因为它允许我们为每个环境定义不同的配置。

logger.ReadFrom.Configuration(context.Configuration);

appsettings.json

通过 Fluent API 进行配置

如果您想要更硬编码的方法,可以使用 Fluent API 来配置 Serilog。例如,我们已将 appsettings.json 中的最低日志级别定义为信息。如果要通过代码执行此操作,可以在 .Program.cs

builder.Host.UseSerilog((context, logger) =>  
{  
    logger.MinimumLevel.Warning();  
    logger.WriteTo.Console();  
});

我不推荐这种方法,因为它可能会限制配置的可能性。但同样,这取决于您的用例和偏好。

Serilog 水槽

Serilog 支持将日志写入多个目标,如控制台、文件、Amazon CloudWatch、DynamoDB、SEQ、SQL Server、MongoDB 和大量其他提供商。在此处阅读整个列表。简单来说,Serilog Sinks 与记录数据的目标有关。

我们将探索几个 Serilog 接收器,并在我们的 .appsettings.json

文件

默认情况下,Serilog 附带文件接收器和控制台接收器。这意味着您无需安装任何其他软件包即可登录控制台或文件。我们已经测试了基于控制台的日志记录。若要将日志记录数据启用到文件,请打开并添加突出显示的代码。appsettings.json

{  
  "Serilog": {  
    "MinimumLevel": {  
      "Default": "Information",  
      "Override": {  
        "Microsoft": "Warning",  
        "Microsoft.AspNetCore.Hosting.Diagnostics": "Error",  
        "Microsoft.Hosting.Lifetime": "Information"  
      }  
    },  
    "WriteTo": [  
      {  
        "Name": "File",  
        "Args": {  
          "path": "D:\\Logs\\log.txt",  
          "rollingInterval": "Day"  
        }  
      }  
    \]  
  },  
  "AllowedHosts": "*"  
}

在这里,我们添加了一个 Section,并将接收器声明为 。在参数中,我们传递了文本文件的路径,并将滚动间隔定义为 Day。这可确保每天创建一个新的日志文件,以控制文件大小。WriteToFile

您可以看到文件名已附加了时间信息。

如果要清理较旧的日志文件,也可以在参数中设置该属性。默认情况下,将保留 31 个文件,并将删除较旧的文件。retainedFileCountLimit

同样,您也可以根据文件大小创建日志文件。为此,您需要将该属性设置为 true。默认值设置为 1 GB。因此,一旦您的日志文件大小超过 1 GB 大关,就会推出一个新文件,其名称如下:fileSizeLimitBytesrollOnFileSizeLimitFileSizeLimitBytes


log.txt  
log\_001.txt  
log\_002.txt

这是记录到文本文件中的数据。就这么简单!

自定义输出消息格式

此外,如果要配置输出/消息格式,只需将该属性添加到接收器的参数中即可。例如,我给出了以下配置。outputTemplate

"outputTemplate": "{Message}{NewLine:1}{Exception:1}"

如果运行应用程序,则可以在文本文件中看到以下日志,这次没有任何时间戳数据。

在此处阅读有关支持的输出模板的更多信息。

结构化日志记录

要使用 File Sink 启用结构化日志记录,我们需要将 JSON 格式化程序作为参数添加到设置中。让我们按如下方式更改配置。

{  
  "Name": "File",  
  "Args": {  
    "path": "D:\\Logs\\log.json",  
    "rollingInterval": "Day",  
    "rollOnFileSizeLimit": true,  
    "formatter": "Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact"  
  }  
}

让我们重新启动我们的应用程序。

正如你所看到的,我们现在有一个结构精美的日志。现在,如果我们想向结构化日志添加其他元数据,让我们回到我们的日志并进行以下更改,以便我们容纳更多的属性。DummyService

public class DummyService(ILogger<DummyService> logger) : IDummyService  
{  
    public void DoSomething()  
    {  
        logger.LogInformation("something is done");  
        logger.LogCritical("oops");  
        logger.LogDebug("nothing much");  
        logger.LogInformation("Invoking {@Event} with ID as {@Id}", "SomeEvent", Guid.NewGuid());  
    }  
}

如您所见,我们添加了一个单独的日志消息,其中包含 2 个参数,即 Event 和 Id。让我们运行应用程序。

因此,其他参数现在也是结构化日志消息的一部分。这是结构化日志记录的一个强大功能,在跟踪错误时将有很大帮助。

SEQ — 推荐用于本地开发

接下来,我们将探索将应用程序日志写入外部服务 SEQ

SEQ 是一个超级酷的工具,用于监控和分析应用程序的结构化日志。这与 Serilog 和 ASP.NET Core 无缝协作。

这是一个简单的 Docker 命令,用于在本地启动 SEQ 容器。请注意,这仅用于演示目的。理想情况下,您需要为此创建一个 docker-compose 文件,并将 SEQ 容器附加到卷,以便可以保留日志数据。

docker run --name seq -d -e ACCEPT\_EULA=Y -p 80:80 -p 5341:5341 datalust/seq

容器启动后,导航到 .您可以看到您的 SEQ 仪表板现在可以访问。让我们向这个实例写入一些日志。localhost:80

但首先,让我们为 serilog 安装所需的 sink 包。

Install-Package Serilog.Sinks.Seq

接下来,让我们在配置中添加一个新的接收器。appsettings.json

{  
  "Name": "Seq",  
  "Args": { "serverUrl": "http://localhost:5341" }  
}

就是这样!只需重新启动应用程序,即可看到以下日志消息。

丰富日志

为了释放 Serilog 的全部潜力,我们使用浓缩剂。这些扩充程序在日志事件发生时为您提供了其他详细信息,例如 、,以便更好地进行诊断。它使开发人员的生活变得更加简单。MachineNameProcessIdThreadId

Install-Package Serilog.Enrichers.Environment  
Install-Package Serilog.Enrichers.Process  
Install-Package Serilog.Enrichers.Thread

安装软件包后,打开并添加扩充器。appsettings.json

"Enrich": [  
  "WithMachineName",  
  "WithProcessId",  
  "WithThreadId"  
]

只需重新启动应用程序,然后检查新生成的日志即可。您将能够看到其他属性,如计算机名称、进程 ID 和线程 ID。

请求日志记录

您可以使用 Serilog 将 ASP.NET 核心 HTTP 请求记录到接收器。您只需将以下代码行添加到您的文件中即可。Program.cs

app.UseSerilogRequestLogging();

从现在开始,每当有新请求到达 HTTP 管道时,Serilog 都会登录到您的接收器。

您可以看到记录的 HTTP 请求。

最佳实践

以下是在 ASP.NET 核心应用程序中使用 Serilog 的一些最佳实践和建议。

  • 不要依赖生产中的文件和控制台日志记录
  • 在生产环境中谨慎使用控制台日志记录,因为这有时可能是一个阻塞调用。如果需要,仅对错误执行控制台日志记录。否则,请始终坚持在生产环境中使用外部日志记录。
  • 首选 appsettings.json 而不是流畅的 API 配置,因为 appsettings 使用起来更可靠、更灵活。
  • 首选 SEQ For Local Development,因为它很容易根据传入的日志诊断问题。
  • 使用异步日志记录可确保 ASP.NET Core 应用程序的最佳性能。
  • 对于较大的系统,请尝试将相关 ID 添加到结构化日志中,以便可以识别单个请求的日志。这可以通过引入中间件并将 GUID 推送为相关 ID 来完成。

这就是本指南的全部内容。我希望你觉得这很有趣和有帮助。在本文中,我们介绍了您需要了解的有关将 Serilog 集成到 ASP.NET Core 应用程序中的所有信息。我们进一步了解了接收器、扩充器、请求日志记录等。

相关留言评论
昵称:
邮箱:
阅读排行