与许多其他 .NET 库一样,Serilog 为文件、控制台等提供基本的诊断日志记录。它易于设置,具有干净的API,并且可以在最近的.NET平台之间移植。今天花了点时间好好研究了下,记录下心得。
核心日志记录包是 Serilog。支持的平台是.NET/.NET Core,.NET Framework 4.5 +,Windows(8 / WinRT / Universal +)和Windows Phone 8 +。
github位置:serilog/serilog: Simple .NET logging with fully-structured events (github.com)
消息输出模板:Message Templates
创建记录器:
Log.Logger = new LoggerConfiguration().CreateLogger();
Log.Information("No one listens to me!");
// Finally, once just before the application exits...
Log.CloseAndFlush();
上面的示例将创建一个不记录任何位置的事件的记录器。若要查看日志事件,必须配置接收器。
添加接收器:
$ dotnet add package Serilog.Sinks.Console
$ dotnet add package Serilog.Sinks.File
using var log = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.File("log-.txt", rollingInterval: RollingInterval.Day)
.CreateLogger();
Log.Information("Ah, there you are!");
上面的示例,添加了控制台和文件的接收器,这样日志就可以显示在控制台和文件中了。
日志级别:
配置最低记录级别:
serilog默认处理的日志最低级别为information,如果需要可以自行配置,
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console()
.CreateLogger();
上面的示例修改日志最低级别为Debug模式,否则使用Log.Debug("xxx"),不会有任何显示,因为默认处理的最低级别为information。
日志记录级别检测:
readonly bool _isDebug = Log.IsEnabled(LogEventLevel.Debug);
if (_isDebug) Log.Debug("Someone is stuck debugging...");
日志记录级别动态切换:
var levelSwitch = new LoggingLevelSwitch();
levelSwitch.MinimumLevel = LogEventLevel.Warning;
var log = new LoggerConfiguration()
.MinimumLevel.ControlledBy(levelSwitch)
.WriteTo.ColoredConsole()
.CreateLogger();
现在,写入记录器的事件将根据交换机的属性进行筛选。MinimumLevel
若要在运行时调高或调低级别(可能是为了响应通过网络发送的命令),请更改以下属性:
levelSwitch.MinimumLevel = LogEventLevel.Verbose;
log.Verbose("This will now be logged");
使用Serilogs.Enrichers.Thread记录当前执行线程的ID和Name
Install-Package Serilog.Enrichers.Thread
Log.Logger = new LoggerConfiguration()
.Enrich.WithThreadId()
.Enrich.WithThreadName()
.WriteTo.Console()
.WriteTo.File("logs\log.txt")
.CreateLogger();
许多接收器包含所有属性,无需进一步操作,因此将自动记录线程 ID。但是,某些接收器(如文件和控制台接收器)使用输出模板,所以一些新的属性可能不会自动输出到接收器中。在这种情况下,为了让我们需要的线程ID和Name显示在日志记录中,我们需要创建或修改输出模板。可以验证上面的例子,看是否有ID和Name显示。
配置输出模板:
Thread.CurrentThread.Name = "MyWorker";
var logger = Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console(restrictedToMinimumLevel:Serilog.Events.LogEventLevel.Information)
.WriteTo.Async(w=>w.File("..\\..\\..\\..\\logs\\SerilogLogFile.json", rollingInterval: RollingInterval.Day, outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj} <{ThreadId}><{ThreadName}>{NewLine}{Exception}"))
.Enrich.WithThreadId()
.CreateLogger();
上面我们使用Serilogs.Sinks.Async异步输出日志到文件中了,大概输出如下:
2018-04-06 13:12:45.684 +02:00 [ERR] The file file_name.svg does not exist <4><MyWorker>
<4> 线程ID,<MyWorker>线程名称
注意:如果线程名称为null,则会自动忽略name属性。如果想一直显示,则可以如下配置:
using Serilog.Enrichers;
Log.Logger = new LoggerConfiguration()
.Enrich.WithThreadName() //这里顺序很重要,如果属性写在前,则一直输出MyDefault
.Enrich.WithProperty(ThreadNameEnricher.ThreadNamePropertyName, "MyDefault")
.CreateLogger();
使用Serilogs.Sinks.Debug显示日志信息到Visual Studio的调试输出窗口。
Install-Package Serilog.Sinks.Debug
Log.Logger = new LoggerConfiguration()
.WriteTo.Debug()
.CreateLogger();
Log.Information("Hello, world!");
使用Serilog.Settings.AppSettings读取.config文件配置信息
Install-Package Serilog.Settings.AppSettings
var log = new LoggerConfiguration()
.ReadFrom.AppSettings()
.CreateLogger();
节点配置App.config, Web.config配置console输出
<configuration>
<appSettings>
<add key="serilog:using:Debug" value="Serilog.Sinks.Debug" />
<add key="serilog:write-to:Debug" />
若要将控制台接收器与 Microsoft.Extensions.Configuration(例如,ASP.NET Core 或 .NET Core)配合使用,请使用 Serilog.Settings.Configuration 程序包。如果尚未安装该软件包,请先安装该软件包
Install-Package Serilog.Settings.Configuration
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.CreateLogger();
在文件中的节点下,:appsettings.json
Serilog
{
"Serilog": {
"WriteTo": ["Debug"]
}
}
使用Serilog.Sinks.File写文件的一些配置问题:
Serilog.Sinks.RllingFile已经弃用,合入到了Serilog.Sinks.File中。
默认情况下,单个文件最大为1GB.
取消限制: .WriteTo.File("log.txt", fileSizeLimitBytes: null)
同样,默认仅保留31个文件。
取消限制: .WriteTo.File("log.txt", rollingInterval: RollingInterval.Day, retainedFileCountLimit: null)