serilog.aspnetcore
Serilog记录为ASP.NET核心。此软件包通过Serilog路由ASP.NET核心日志消息,因此您可以获取有关与应用程序事件相同的Serilog接收器写入ASP.NET的内部操作的信息。
使用Serilog.aspnetcore安装和配置,您可以直接通过Serilog或ASP.NET注入的任何ILogger接口编写日志消息。所有登录者将使用相同的基础实现,级别和目的地。
版本控制:此软件包跟踪其Microsoft.extensions.hosting依赖项的版本控制和目标框架支持。大多数用户应选择与其应用程序的目标框架相匹配的serilog.aspnetcore的版本。即,如果您针对.NET 7.X,请选择Serilog.aspnetcore的7.x版本。如果您要定位.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 ( ) ; }
builder.Services.AddSerilog()调用将通过您的Serilog管道重定向所有日志事件。
最后,通过删除默认记录器的剩余配置来清理,包括AppSettings中的\"Logging\"部分。*。JSON文件(如果需要,可以用Serilog配置替换为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输出,请从下拉列表中的Show输出中选择ASP.NET Core Web服务器,或用WriteTo.debug 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 \"
}
要启用中间件,请首先更改嘈杂的ASP.NET核心日志源的最小级别,以在您的logger配置或AppSettings.json文件中Warning :JSON文件:
. MinimumLevel . Override ( \"Microsoft.AspNetCore.Hosting\" , LogEventLevel . Warning ) . MinimumLevel . Override ( \"Microsoft.AspNetCore.Mvc\" , LogEventLevel . Warning ) . MinimumLevel . Override ( \"Microsoft.AspNetCore.Routing\" , LogEventLevel . Warning )
提示:将
{SourceContext}添加到控制台Logger的输出模板中以查看记录器的名称;这可以帮助追踪嘈杂的日志事件的来源。
然后,在您的应用程序的program.cs中,将中间件添加带有UseSerilogRequestLogging() :
var app = builder . Build ( ) ; app . UseSerilogRequestLogging ( ) ; // <-- Add this line // Other app configuration
重要的是, UseSerilogRequestLogging()调用在MVC等处理程序之前出现。中间软件不会在管道中出现的时间或日志组件。 (这可以用来通过将UseStaticFiles() UseSerilogRequestLogging()放在他们之后。
在请求处理过程中,可以使用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()上的options回调():
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核心主机设置期间捕获和报告例外的好处。
首先初始化Serilog的缺点是尚不可用的是ASP.NET Core主机的服务,包括appsettings.json配置和依赖项注入。
为了解决这个问题,Serilog支持两个阶段的初始化。当程序启动时,立即将立即配置一个初始的“ Bootstrap”记录器,一旦主机加载,它将被完全配置的记录器替换。
要使用此技术,请首先用createbootstraplogger 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()通过随附的serilog.formatting.compact软件包将所有支持json-formatted输出置于本机上。
要将newline限制的json写入CompactJsonFormatter或RenderedCompactJsonFormatter ,将其传递给接收器配置方法:
. WriteTo . Console ( new RenderedCompactJsonFormatter ( ) )
写入Azure Diagnostics日志流
Azure诊断日志流从D:\\home\\LogFiles\\文件夹中的任何文件中汇出了事件。要为您的应用程序启用此功能,请在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>中。为了使此代码工作,请确保您已将.Enrich.FromLogContext()添加到.UseSerilog(...)语句中,如上面的示例所示。
// Microsoft.Extensions.Logging ILogger<T> // Yes, it\'s required to use a dictionary. See https://nbl*um*ha*rdt.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中推出属性一样。可以在https://git*h*ub.c*om/serilog/serilog/wiki/wiki/enrichment#the-logcontext中找到更多详细信息。
// Serilog LogContext using ( LogContext . PushProperty ( \"UserId\" , \"svrooij\" ) ) using ( LogContext . PushProperty ( \"OperationType\" , \"update\" ) ) { // UserId and OperationType are set for all logging events in these brackets }
