前言
上文說到Nlog日志框架,感覺它功能已經很強大,今天給大家介紹一個很不錯的日志框架Serilog,根據我的了解,感覺它最大的優勢是,結構化日志,它輸出的日志是Json的格式,如果你使用的是Mongodb進行存儲日志,那就是完美的結合,MongoDB也是文檔式數據庫,存儲的格式很像JSON,也可以它是一個JSON文件,查詢數據庫快。不扯遠了,還是講講Serilog的使用吧!
一、什么是Serilog?
Serilog 是 ASP.NET Core 的一個插件,可以簡化日志記錄。Serilog 有各種可用的接收器,例如,有純文本、SQL 和 ElasticSearch 接收器等等。
二、如何安裝Serilog?
Install-Package Serilog.AspNetCore
三、如何配置Serilog?
3.1Program的配置如下
- Configuration:構建對象,讀取appsettings.json的配置文件
- Log.Logger:讀取Configuration中的日志配置信息,然后設置輸出的級別、內容、位置等。
- UseSerilog(dispose:true):引入Serilog框架,dispose:true=>系統退出時,釋放日志對象
public class Program
{
public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())//設置基礎路徑
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)//添加配置文件
.AddEnvironmentVariables()//添加環境變量
.Build();
public static void Main(string[] args)
{
Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(Configuration)
.MinimumLevel.Debug()
.Enrich.FromLogContext()//使用Serilog.Context.LogContext中的屬性豐富日志事件。
.WriteTo.Console(new RenderedCompactJsonFormatter())//輸出到控制台
.WriteTo.File(formatter:new CompactJsonFormatter(),"logs\\test.txt",rollingInterval:RollingInterval.Day)//輸出到文件
.CreateLogger();//清除內置日志框架
try
{
Log.Information("Starting web host");
CreateHostBuilder(args).Build().Run();
}
catch (Exception ex)
{
Log.Fatal(ex,"Host terminated unexpectedly");
}
finally
{
Log.CloseAndFlush();
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args).
.ConfigureWebHostDefaults(webBuilder =>{
webBuilder.UseStartup<Startup>();
}).UseSerilog(dispose:true);//引入第三方日志框架
3.2 appsettings.json配置
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Information"
}
}
}
}
四、如何使用Serilog?
因為是替換了.net core中的內部日志框架,所有在使用的時候,和Logging日志框架一樣使用,如下圖所示
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet]
public void Get()
{
_logger.LogInformation("LogInformation" + Guid.NewGuid().ToString("N"));
_logger.LogDebug("LogDebug" + Guid.NewGuid().ToString("N"));
_logger.LogWarning("LogWarning" + Guid.NewGuid().ToString("N"));
_logger.LogError("LogError" + Guid.NewGuid().ToString("N"));
}
五、展示效果
控制台顯示
文件顯示
六、擴展
6.1分級別顯示
//存儲日志文件的路徑
string LogFilePath(string LogEvent) => $@"{AppContext.BaseDirectory}00_Logs\{LogEvent}\log.log";
//存儲日志文件的格式
string SerilogOutputTemplate = "{NewLine}{NewLine}Date:{Timestamp:yyyy-MM-dd HH:mm:ss.fff}{NewLine}LogLevel:{Level}{NewLine}Message:{Message}{NewLine}{Exception}" + new string('-', 50);
Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(Configuration)
.MinimumLevel.Debug()
.Enrich.FromLogContext()//使用Serilog.Context.LogContext中的屬性豐富日志事件。
.WriteTo.Console(new RenderedCompactJsonFormatter())
.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Debug).WriteTo.File(LogFilePath("Debug"), rollingInterval: RollingInterval.Day, outputTemplate: SerilogOutputTemplate))
.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Information).WriteTo.File(LogFilePath("Information"), rollingInterval: RollingInterval.Day, outputTemplate: SerilogOutputTemplate))
.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Warning).WriteTo.File(LogFilePath("Warning"), rollingInterval: RollingInterval.Day, outputTemplate: SerilogOutputTemplate))
.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Error).WriteTo.File(LogFilePath("Error"), rollingInterval: RollingInterval.Day, outputTemplate: SerilogOutputTemplate))
.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Fatal).WriteTo.File(LogFilePath("Fatal"), rollingInterval: RollingInterval.Day, outputTemplate: SerilogOutputTemplate))
.CreateLogger();
效果如下:
文件級別分類:
日志格式輸出:
6.2存儲到數據庫
Install-Package Serilog.Sinks.MSSqlServer
修改配置
MSSqlServer(參數一,參數二,參數三,參數四)
- 數據庫的地址
- 數據庫中記錄日志表的名稱
- 是否自動創建表(Nlog是沒有這個功能的)
- 記錄日志最小級別
Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(Configuration)
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.ReadFrom.Configuration(new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build())
.WriteTo.MSSqlServer(connecting, "logs", autoCreateSqlTable: true, restrictedToMinimumLevel: LogEventLevel.Information)
.CreateLogger();
效果如下:
6.2.1數據庫中表字段
新增
第一步:創建列
var options = new ColumnOptions();
options.AdditionalColumns = new Collection<SqlColumn>
{
new SqlColumn { DataType = SqlDbType.NVarChar, DataLength =-1, ColumnName = "IP" },
};
第二步:添加列
Enrich.WithProperty:添加屬性
columnOptions: options:配置數據庫的列
Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(Configuration)
.MinimumLevel.Information()
.Enrich.WithProperty("IP", "2.2.2.2")
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.ReadFrom.Configuration(new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build())
.WriteTo.MSSqlServer(connecting, "logs", autoCreateSqlTable: true, columnOptions: options, restrictedToMinimumLevel: LogEventLevel.Information)
.CreateLogger();
第三步:運行即可
移除
第一步:記錄移除列
StandardColumn:是框架默認提供數據庫默認表,它的屬性就是映射數據庫的字段
var options = new ColumnOptions();
options.Store.Remove(StandardColumn.Properties);
options.Store.Remove(StandardColumn.TimeStamp);
第二步:配置屬性
Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(Configuration)
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.ReadFrom.Configuration(new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build())
.WriteTo.MSSqlServer(connecting, "logs", autoCreateSqlTable: true, columnOptions: options, restrictedToMinimumLevel: LogEventLevel.Information)
.CreateLogger();
第三步:運行即可
注意事項:
當你創建了數據庫的表之后,如果修改添加字段或修改字段,數據庫存在的表是不會更新的,只能重新創建
6.3發送到郵箱
添加安裝包:
Install-Package Serilog.Sinks.Email
配置如下:
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.ReadFrom.Configuration(new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build())
.WriteTo.Email(new EmailConnectionInfo() {
Port= 465,//端口
EmailSubject="郵件日志測試",//郵件主題
FromEmail= "123**@163.com",//發件箱
ToEmail="********@qq.com",//收件箱
MailServer= "smtp.163.com",//發件箱的郵箱服務
NetworkCredentials = new NetworkCredential("123**@163.com", "*****"),//發件人的郵箱和密碼
IsBodyHtml =true,//郵件是否是HTML格式
EnableSsl=true//使用啟用SSL端口
})
.CreateLogger();
效果如下
總結
Serilog的擴展插件還有很多,我在這只是簡單的介紹Serilog輸出到控制台、輸出到數據庫、輸出到郵件,其實它還有其他,我就不一一介紹,感興趣的可以自己的去嘗試。到此我已經講了三篇.net core中的日志框架了,分別是:
- .net core中的那些常用的日志框架(Logging篇)
- .net core中的那些常用的日志框架(NLog篇)
- .net core中的那些常用的日志框架(Serilog篇)
從其中,我學習了很多,了解了結構化日志,了解日志輸出的多種方式,控制台、文件、數據庫、郵箱,比以前只會寫txt要進步不少。
三篇博客的源碼地址