Serilog 日志记录适用于 ASP.NET Core。此包将 ASP.NET Core 的日志消息通过 Serilog 进行路由,使你可以将有关 ASP.NET 内部操作的信息写入与应用程序事件相同的 Serilog 接收器中。

安装并配置了 Serilog.AspNetCore 后,你可以直接通过 Serilog 或ASP.NET 注入的任何 ILogger 接口写入日志消息。所有日志记录器将使用相同的底层实现、级别和目的地。

版本控制:该包跟踪其 Microsoft.Extensions.Hosting 依赖项的版本控制和目标框架支持。大多数用户应该选择与其应用程序目标框架匹配的 Serilog.AspNetCore 版本。例如,如果你的目标是 .NET 7.x,则选择一个 7.x 版本的 Serilog.AspNetCore。如果你的目标是 .NET 8.x,则选择一个 8.x 版本的 Serilog.AspNetCore,依此类推。

使用说明

首先,将 Serilog.AspNetCore NuGet 包安装到你的应用程序中:

dotnet add package Serilog.AspNetCore

接下来,在你的应用程序的 Program.cs 文件中,首先配置 Serilog。使用 try/catch 块可以确保任何配置问题都能得到适当记录:

using Serilog;
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();
try
{
Log.Information("Starting web application");
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSerilog(); // <-- Add this line
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
}
catch (Exception ex)
{
Log.Fatal(ex, "Application terminated unexpectedly");
}
finally
{
Log.CloseAndFlush();
}

调用将会通过你的 Serilog 管道重定向所有日志事件。

最后,通过移除默认记录器的剩余配置进行清理,包括appsettings.*.json 文件中的 “Logging” 部分(如果需要,可以用 Serilog 配置替代,如示例项目所示)。

就这样完成了!通过稍微提高日志级别,你将看到类似于以下内容的日志输出:

[12:01:43 INF] Starting web application
[12:01:44 INF] Now listening on: http://localhost:5000
[12:01:44 INF] Application started. Press Ctrl+C to shut down.
[12:01:44 INF] Hosting environment: Development
[12:01:44 INF] Content root path: serilog-aspnetcore/samples/Sample
[12:01:47 WRN] Failed to determine the https port for redirect.
[12:01:47 INF] Hello, world!
[12:01:47 INF] HTTP GET / responded 200 in 95.0581 ms

提示:要在使用 IIS 运行时在 Visual Studio 输出窗口中查看 Serilog 输出,可以选择 "ASP.NET Core Web Server" 从下拉列表中显示输出,或者在日志配置中将WriteTo.Console()替换为WriteTo.Debug()。

有关更完整的示例,包括 appsettings.json 配置,可以在这里找到示例项目。

请求日志记录

该包包括用于更智能的 HTTP 请求日志记录的中间件。ASP.NET Core 实现的默认请求日志记录非常繁琐,每个请求会发出多个事件。该中间件将这些事件合并为一个单一事件,该事件携带方法、路径、状态码和时间信息。

文本格式如下:

[16:05:54 INF] HTTP GET / responded 200 in 227.3253 ms

或作为 JSON:

{
"@t": "2019-06-26T06:05:54.6881162Z",
"@mt": "HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms",
"@r": ["224.5185"],
"RequestMethod": "GET",
"RequestPath": "/",
"StatusCode": 200,
"Elapsed": 224.5185,
"RequestId": "0HLNPVG1HI42T:00000001",
"CorrelationId": null,
"ConnectionId": "0HLNPVG1HI42T"
}

要启用中间件,首先在日志配置或 appsettings.json 文件中将 ASP.NET Core 日志源的最低级别更改为 Warning:

.MinimumLevel.Override("Microsoft.AspNetCore.Hosting", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.AspNetCore.Mvc", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.AspNetCore.Routing", LogEventLevel.Warning)

提示:在控制台日志记录器的输出模板中添加 {SourceContext},以查看日志记录器的名称;这可以帮助追踪噪声日志事件的来源并进行抑制。

然后,在应用程序的 Program.cs 中,使用 UseSerilogRequestLogging() 添加中间件:

var app = builder.Build();
app.UseSerilogRequestLogging(); // <-- Add this line
// Other app configuration

重要的是 UseSerilogRequestLogging() 调用应出现在处理程序(如 MVC)之前。中间件不会对其在管道中出现之前的组件进行计时或日志记录。(可以利用这一点,通过将 UseSerilogRequestLogging() 放在它们之后来排除噪声处理程序的日志记录,例如 UseStaticFiles()。)

在请求处理期间,可以使用 IDiagnosticContext.Set() 将附加属性附加到完成事件中:

public class HomeController : Controller
{
readonly IDiagnosticContext _diagnosticContext;
public HomeController(IDiagnosticContext diagnosticContext)
{
_diagnosticContext = diagnosticContext ?? throw new ArgumentNullException(nameof(diagnosticContext));
}
public IActionResult Index()
{
// The request completion event will carry this property
_diagnosticContext.Set("CatalogLoadTime", 1423);
return View();
}
}

这种模式的优点在于减少了每个 HTTP 请求需要构建、传输和存储的日志事件数量。在同一事件上有许多属性也可以使请求细节和其他数据的关联更容易。

默认情况下,将作为属性添加以下请求信息:

• RequestMethod(请求方法)

• RequestPath(请求路径)

• StatusCode(状态码)

• Elapsed(持续时间)

你可以通过在
UseSerilogRequestLogging() 的选项回调中修改请求完成事件的消息模板、添加额外属性或更改事件级别。

app.UseSerilogRequestLogging(options =>
{
// Customize the message template
options.MessageTemplate = "Handled {RequestPath}";
// Emit debug-level events instead of the defaults
options.GetLevel = (httpContext, elapsed, ex) => LogEventLevel.Debug;
// Attach additional properties to the request completion event
options.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
{
diagnosticContext.Set("RequestHost", httpContext.Request.Host.Value);
diagnosticContext.Set("RequestScheme", httpContext.Request.Scheme);
};
});

两阶段初始化

本页面顶部的示例展示了如何在应用程序启动时立即配置 Serilog。这种方式的好处是可以捕获和报告在设置 ASP.NET Core 主机期间抛出的异常。

然而,首先初始化 Serilog 的缺点是 ASP.NET Core 主机的服务,包括 appsettings.json 配置和依赖注入,还不可用。

为了解决这个问题,Serilog 支持两阶段初始化。程序启动时,首先配置一个初始的“引导”日志记录器,然后在主机加载完成后,用完全配置的日志记录器替换它。

要使用这种技术,首先将初始的 CreateLogger() 调用替换为 CreateBootstrapLogger():

using Serilog;
using Serilog.Events;
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.Enrich.FromLogContext()
.WriteTo.Console()
.CreateBootstrapLogger(); // <-- Change this line!

然后,向 AddSerilog() 传递一个回调函数,该回调用于创建最终的日志记录器:

builder.Services.AddSerilog((services, lc) => lc
.ReadFrom.Configuration(builder.Configuration)
.ReadFrom.Services(services)
.Enrich.FromLogContext()
.WriteTo.Console());

需要注意的是,最终的日志记录器会完全替换引导日志记录器:例如,如果你希望两者都记录到控制台,则需要在两个地方都指定 WriteTo.Console(),如示例所示。

使用 appsettings.json 配置

使用两阶段初始化时,插入上例中显示的 ReadFrom.Configuration(builder.Configuration) 调用。JSON 配置语法的文档可以在 Serilog.Settings.Configuration 的 README 中找到。

将服务注入到增强器和接收器

使用两阶段初始化时,插入上例中显示的 ReadFrom.Services(services) 调用。ReadFrom.Services() 调用会用以下服务的任何注册实现来配置日志记录管道:

• IDestructuringPolicy

• ILogEventEnricher

• ILogEventFilter

• ILogEventSink

• LoggingLevelSwitch

JSON 输出

Console()、Debug() 和 File() 接收器都原生支持 JSON 格式的输出,通过包含的 Serilog.Formatting.Compact 包来实现。

要写入以换行符分隔的 JSON,请将 CompactJsonFormatter 或 RenderedCompactJsonFormatter 传递给接收器配置方法:

.WriteTo.Console(new RenderedCompactJsonFormatter())

写入 Azure 诊断日志流

Azure 诊断日志流会将来自 D:\home\LogFiles\ 文件夹中的事件传送到 Azure。为了你的应用启用此功能,请向 LoggerConfiguration 添加一个文件 接收器,并注意设置 shared 和 flushToDiskInterval 参数:

Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.Enrich.FromLogContext()
.WriteTo.Console()
// Add this line:
.WriteTo.File(
System.IO.Path.Combine(Environment.GetEnvironmentVariable("HOME"), "LogFiles", "Application", "diagnostics.txt"),
rollingInterval: RollingInterval.Day,
fileSizeLimitBytes: 10 * 1024 * 1024,
retainedFileCountLimit: 2,
rollOnFileSizeLimit: true,
shared: true,
flushToDiskInterval: TimeSpan.FromSeconds(1))
.CreateLogger();

将属性推送到 ILogger<T>

如果你希望在代码的特定部分向所有日志事件添加额外的属性,可以使用以下代码将它们添加到 Microsoft.Extensions.Logging 的 ILogger<T> 中。为了使这段代码生效,请确保在 .UseSerilog(...) 语句中添加了 .Enrich.FromLogContext(),如上例所示。

// Microsoft.Extensions.Logging ILogger<T>
// Yes, it's required to use a dictionary. See https://nblumhardt.com/2016/11/ilogger-beginscope/
using (logger.BeginScope(new Dictionary<string, object>
{
["UserId"] = "svrooij",
["OperationType"] = "update",
}))
{
// UserId and OperationType are set for all logging events in these brackets
}

上面的代码产生的结果与在 Serilog 的 LogContext 中推送属性是相同的。更多详细信息可以在 Serilog 官方文档 中找到。

// Serilog LogContext
using (LogContext.PushProperty("UserId", "svrooij"))
using (LogContext.PushProperty("OperationType", "update"))
{
// UserId and OperationType are set for all logging events in these brackets
}

Serilog文档翻译系列(二) - 设置AspNetCore应用程序的更多相关文章

  1. Maven入门系列(二)--设置中央仓库的方法

    原文地址:http://www.codeweblog.com/maven入门系列-二-设置中央仓库的方法/ Maven仓库放在我的文档里好吗?当然不好,重装一次电脑,意味着一切jar都要重新下载和发布 ...

  2. 微信小程序开发系列二:微信小程序的视图设计

    大家如果跟着我第一篇文章 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 一起动手,那么微信小程序的开发环境一定搭好了.效果就是能把该小程序的体验版以二维码的方式发送给其他朋友使用. 这个系列 ...

  3. 微信小程序开发系列五:微信小程序中如何响应用户输入事件

    微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 微信小程序开发系列三:微信小程序的调试方法 微信小程序开发系列四:微信小程序 ...

  4. 微信小程序开发系列七:微信小程序的页面跳转

    微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 微信小程序开发系列三:微信小程序的调试方法 微信小程序开发系列四:微信小程序 ...

  5. 微信小程序开发系列四:微信小程序之控制器的初始化逻辑

    微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 微信小程序开发系列三:微信小程序的调试方法 这个教程的前两篇文章,介绍了如何 ...

  6. 学习ASP.NET Core Blazor编程系列二——第一个Blazor应用程序(中)

    学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 四.创建一个Blazor应用程序 1. 第一种创 ...

  7. 学习ASP.NET Core Blazor编程系列二——第一个Blazor应用程序(下)

    学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 学习ASP.NET Core Blazor编程系 ...

  8. 学习ASP.NET Core Blazor编程系列二——第一个Blazor应用程序(完)

    学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 学习ASP.NET Core Blazor编程系 ...

  9. MyBatis系列二 之 数据库列名于程序实体类中字段名称不一致

    MyBatis系列二  之   数据库列名于程序实体类中字段名称不一致 情景:当数据库中的列名与我们程序实体类中的字段名称不一致         使用ResultMap节点配置信息  在映射文件中  ...

  10. React文档翻译系列(二)Hello World

    这是React文档翻译系列的第二篇,前一篇介绍了如何安装react,本篇主要介绍react的知识体系,掌握了基本的知识体系,才能更好的学习React. Hello World 开始React最简单的方 ...

随机推荐

  1. v-if 和 v-show 有什么区别?

    v-if 是真正的条件渲染,会控制这个 DOM 节点的存在与否.因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建:也是惰性的:如果在初始渲染时条件为假,则什么也不做--直到条件第 ...

  2. position的值, relative和absolute分别是相对于谁进行定位的?

    relative:  相对定位,相对于自己本身在正常文档流中的位置进行定位 相对它原来的位置,在走100px.原来在标准流中的位置继续占有. absolute: 生成绝对定位,相对于最近一级定位不为s ...

  3. Mac Eclipse 常用快捷键汇总

    寻找类:shift+command+t 删除当前行:command+d 上移当前行代码:option+↑ 下移当前行代码:option+↓ 复制当前行至下一行:option+command+↓ 复制当 ...

  4. xampp+vscode 安装PHP断点调试xdebug

    官网下载地址:https://xdebug.org/download.php 这里需要特别注意,有TS(thread safe)和NTS 区别,我建议不要下载最新的,我一开始使用最新的发现插件没有匹配 ...

  5. MYSQL DQL in 到底会不会走索引&in 范围查询引发的思考。

    前情引子 in 会不会走索引?很多人肯定会回答.废话.如果命中了索引.那肯定会走. 其实我和大多数人一样.一开始也是这么想的.直至有一个血淋淋的案子让我有所改观.有所思考. 背景介绍 业务的工单表.我 ...

  6. R语言基于表格文件的数据绘制具有多个系列的柱状图与直方图

      本文介绍基于R语言中的readxl包与ggplot2包,读取Excel表格文件数据,并绘制具有多个系列的柱状图.条形图的方法.   首先,我们配置一下所需用到的R语言readxl包与ggplot2 ...

  7. python os.path 模块详解

    python os.path 模块详解 os.path.basename() 返回最后一项,通常是文件名os.path.dirname() 返回的是目录,不包含文件名os.path.split() 返 ...

  8. 中国超级计算机为什么不能为AI提供算力?

    网上看到这样的帖子: https://www.zhihu.com/question/609008408/answer/3130831897 ============================== ...

  9. 为wsl ubuntu设置固定IP

    参考: https://www.cnblogs.com/lidabo/p/16855858.html https://zhuanlan.zhihu.com/p/515068209 ========== ...

  10. 常用的php方法

    /* * http 封装网络请求方法 */ /* * get method */ function get($url, $param=array()){ if(!is_array($param)){ ...