在构建新的 ASP.NET Core 项目时,应优先设置日志记录,以确保从一开始就具有强大的监视和调试功能。Serilog 是用于 ASP.NET Core 应用程序的最流行的日志记录库。在本文中,我们将学习使用 Serilog 在 ASP.NET Core 应用程序中掌握结构化日志记录所需的所有知识。我们将了解 Serilog 配置、接收器以及您需要遵循的所有最佳实践。这将是您需要参考 .NET 应用程序的主日志记录的唯一指南。
如前所述,Serilog 是一个流行的第三方日志记录库,它通过其日志记录实现插入到 .NET 应用程序的默认实例中。它使应用程序能够将事件记录到各种目标,如控制台、文件、数据库、CloudWatch Logs 等。Serilog 提供结构化日志记录,可以帮助您以更简洁的方式存储和分析日志。Serilog 还提供了超级灵活的配置,我们将在本文的后面部分看到。Serilog 是我每次开始新的 ASP.NET 核心项目时都会安装的第一个库!ILogger
在性能方面,由于其异步日志记录和日志消息批处理等功能,Serilog 对应用程序性能的影响接近 0。
除此之外,您还需要了解此库的几个方面。让我们开始吧。
在此演示中,我将使用 .NET 8 Web API 项目和 Visual Studio 2022 Community Edition。
首先,通过运行以下命令为 ASP.NET Core 应用程序安装 Serilog 软件包。
Install-Package Serilog.AspNetCore
安装软件包后,让我们配置 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();
}
请注意,默认情况下,我们允许 .NET 应用程序登录到控制台,在第 #11 行。由您来删除它。我使用它是为了将所有日志默认记录在控制台上。在调试过程中有很大帮助。
接下来,打开文件并添加以下内容。如前所述,这里我们跳过了该部分,相反,我们将使用该部分来配置我们的记录器。目前,我们只是坚持基本配置。随着我们的进展,我们将添加更多配置。appsettings.jsonLoggingSerilog
{
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"Microsoft.AspNetCore.Hosting.Diagnostics": "Error",
"Microsoft.Hosting.Lifetime": "Information"
}
}
},
"AllowedHosts": "*"
}
如上所述,我们已将默认值设置为 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。
让我们进入配置!有两种方法可以在 .NET 应用程序中配置 Serilog,这取决于您的要求。您可以使用 Fluent API 以更硬编码的方式配置 Serilog。appsettings.json
在前面的代码中,我们曾经确保记录器可以从 中读取 。这是推荐的方法,因为它允许我们为每个环境定义不同的配置。
logger.ReadFrom.Configuration(context.Configuration);
appsettings.json
如果您想要更硬编码的方法,可以使用 Fluent API 来配置 Serilog。例如,我们已将 appsettings.json 中的最低日志级别定义为信息。如果要通过代码执行此操作,可以在 .Program.cs
builder.Host.UseSerilog((context, logger) =>
{
logger.MinimumLevel.Warning();
logger.WriteTo.Console();
});
我不推荐这种方法,因为它可能会限制配置的可能性。但同样,这取决于您的用例和偏好。
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 是一个超级酷的工具,用于监控和分析应用程序的结构化日志。这与 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": "https://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 的一些最佳实践和建议。
这就是本指南的全部内容。我希望你觉得这很有趣和有帮助。在本文中,我们介绍了您需要了解的有关将 Serilog 集成到 ASP.NET Core 应用程序中的所有信息。我们进一步了解了接收器、扩充器、请求日志记录等。