1. 程式人生 > >.net core中的那些常用的日誌框架(Serilog篇)

.net core中的那些常用的日誌框架(Serilog篇)

### 前言 >上文說到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(); }).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 _logger; public WeatherForecastController(ILogger 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")); } ``` ### 五、展示效果 **控制檯顯示** ![](https://img2020.cnblogs.com/blog/1400941/202010/1400941-20201014092052857-388318905.png) **檔案顯示** ![](https://img2020.cnblogs.com/blog/1400941/202010/1400941-20201014092147785-1709330383.png) ### 六、擴充套件 #### 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(); ``` **效果如下:** 檔案級別分類: ![](https://img2020.cnblogs.com/blog/1400941/202010/1400941-20201014093034675-1903623090.png) 日誌格式輸出: ![](https://img2020.cnblogs.com/blog/1400941/202010/1400941-20201014093127438-1685482585.png) #### 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(); ``` **效果如下:** ![](https://img2020.cnblogs.com/blog/1400941/202010/1400941-20201015093105399-1335401250.png) ##### 6.2.1資料庫中表欄位 **新增** 第一步:建立列 ``` var options = new ColumnOptions(); options.AdditionalColumns = new Collection { 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(); ``` 第三步:執行即可 ![](https://img2020.cnblogs.com/blog/1400941/202010/1400941-20201015094816897-227026538.png) **移除** 第一步:記錄移除列 **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(); ``` 第三步:執行即可 ![](https://img2020.cnblogs.com/blog/1400941/202010/1400941-20201015095551076-446794013.png) **注意事項:** >當你建立了資料庫的表之後,如果修改新增欄位或修改欄位,資料庫存在的表是不會更新的,只能重新建立 #### 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= "[email protected]",//發件箱 ToEmail="[email protected]",//收件箱 MailServer= "smtp.163.com",//發件箱的郵箱服務 NetworkCredentials = new NetworkCredential("[email protected]", "zc960810"),//發件人的郵箱和密碼 IsBodyHtml =true,//郵件是否是HTML格式 EnableSsl=true//使用啟用SSL埠 }) .CreateLogger(); ``` **效果如下** ![](https://img2020.cnblogs.com/blog/1400941/202010/1400941-20201015103536289-1433705743.png) ### 總結 >Serilog的擴充套件外掛還有很多,我在這只是簡單的介紹Serilog輸出到控制檯、輸出到資料庫、輸出到郵件,其實它還有其他,我就不一一介紹,感興趣的可以自己的去嘗試。到此我已經講了三篇.net core中的日誌框架了,分別是: + [.net core中的那些常用的日誌框架(Logging篇)](https://www.cnblogs.com/2828sea/p/13672481.html) + [.net core中的那些常用的日誌框架(NLog篇)](https://www.cnblogs.com/2828sea/p/13728018.html) + [.net core中的那些常用的日誌框架(Serilog篇)](https://www.cnblogs.com/2828sea/p/13812869.html) 從其中,我學習了很多,瞭解了結構化日誌,瞭解日誌輸出的多種方式,控制檯、檔案、資料庫、郵箱,比以前只會寫txt要進步不少。 [三篇部落格的原始碼地址](https://github.com/zc282840325/