.Net Core 3.0 使用 Serilog 把日誌記錄到 SqlServer

Serilog簡介

Serilog是.net中的診斷日誌庫,能夠在全部的.net平臺上面運行。Serilog支持結構化日誌記錄,對複雜、分佈式、異步應用程序的支持很是出色。Serilog能夠經過插件的方式把日誌寫入到各類終端,控制檯、文本、Sqlserver、ElasticSearch,Serilog支持終端的列表:https://github.com/serilog/serilog/wiki/Provided-Sinks 。html

Serilog日誌寫入SqlServer

1、Sink LoggerConfiguration

  • connectionString  數據庫鏈接字符串
  • schemaName  數據庫全部者,默認dbo
  • tableName  記錄日誌的表名 
  • autoCreateSqlTable  是否自動建立表,若是設置爲ture,則在Serilog啓動時檢測數據庫是否有對應的表,沒有則建立 
  • columnOptions  日誌表中的列定義
  • restrictedToMinimumLevel  記錄日誌的最小level 
  • batchPostingLimit  單次批量處理中提交的最大日誌數量
  • period  進行批量提交的間隔
  • formatProvider 提供特定的格式化處理,https://github.com/serilog/serilog/wiki/Formatting-Output#format-providers

Serilog爲咱們定義了一套標準列,默認狀況下會生成以下列,固然咱們也能夠自定義列git

  • StandardColumn.Id  自增Id 
  • StandardColumn.Message  日誌內容 
  • StandardColumn.MessageTemplate 日誌模板
  • StandardColumn.Level  等級 
  • StandardColumn.TimeStamp  記錄時間
  • StandardColumn.Exception  異常信息
  • StandardColumn.Properties 日誌事件屬性值

刪除標準列:github

columnOptions.Store.Remove(StandardColumn.MessageTemplate);

添加自定義列:web

columnOptions.AdditionalColumns = new Collection<SqlColumn> { new SqlColumn { DataType = SqlDbType.NVarChar, DataLength = 32, ColumnName = "IP" } };

完整LoggerConfiguration示例以下:數據庫

var columnOptions = new ColumnOptions(); columnOptions.Store.Remove(StandardColumn.MessageTemplate);//刪除標準列
            columnOptions.Properties.ExcludeAdditionalProperties = true;//排除已經自定義列的數據
            columnOptions.AdditionalColumns = new Collection<SqlColumn>//添加自定義列
 { new SqlColumn { DataType = SqlDbType.NVarChar, DataLength = 32, ColumnName = "IP" } }; Log.Logger = new LoggerConfiguration() .WriteTo.MSSqlServer( connectionString: Configuration["Serilog:ConnectionString"], tableName: Configuration["Serilog:TableName"], batchPostingLimit: Configuration.GetValue<int>("Serilog:BatchPostingLimit"),//批量插入數據庫條數
                   period: TimeSpan.FromSeconds(5),//執行時間間隔
                   restrictedToMinimumLevel: Configuration.GetValue<LogEventLevel>("Serilog:MinimumLevel"), columnOptions: columnOptions, autoCreateSqlTable: true ).CreateLogger();

上面的配置也能夠所有從配置文件讀取:服務器

{ "Serilog": { "Using": [ "Serilog.Sinks.MSSqlServer" ], "MinimumLevel": "Debug", "WriteTo": [ { "Name": "MSSqlServer", "Args": { "connectionString": "NamedConnectionString", "schemaName": "EventLogging", "tableName": "Logs", "autoCreateSqlTable": true, "restrictedToMinimumLevel": "Warning", "batchPostingLimit": 100, "period": "0.00:00:30", "columnOptionsSection": { "disableTriggers": true, "clusteredColumnstoreIndex": false, "primaryKeyColumnName": "Id", "addStandardColumns": [ "LogEvent" ], "removeStandardColumns": [ "MessageTemplate"], "additionalColumns": [ { "ColumnName": "IP", "DataType": "varchar", "DataLength": 32 } ], "id": { "nonClusteredIndex": true }, "properties": { "columnName": "Properties", "excludeAdditionalProperties": true, "dictionaryElementName": "dict", "itemElementName": "item", "omitDictionaryContainerElement": false, "omitSequenceContainerElement": false, "omitStructureContainerElement": false, "omitElementIfEmpty": true, "propertyElementName": "prop", "rootElementName": "root", "sequenceElementName": "seq", "structureElementName": "struct", "usePropertyKeyAsElementName": false }, "timeStamp": { "columnName": "Timestamp", "convertToUtc": true }, "logEvent": { "excludeAdditionalProperties": true, "excludeStandardColumns": true }, "message": { "columnName": "message" }, "exception": { "columnName": "exception" } } } } ] } }
Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(Configuration["Serilog"]);//須要引用Microsoft.Extensions.Configuration

2、Logger使用

一、直接使用Serilog提供的靜態類Log

Log.Information(「message」);

二、使用serilog-extensions-logging 替換.net core默認日誌Microsoft.Extensions.Logging,注入Serilog

public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.CaptureStartupErrors(true)//捕捉啓動異常
                              .UseSetting("detailedErrors", "true")//指定程序應用程序會顯示詳細的啓動錯誤信息
                              .UseStartup<Startup>() .ConfigureLogging(builder => { builder.ClearProviders(); builder.AddSerilog(); }); });
private readonly ILogger logger; public TestController(ILogger<TestController> logger) { this.logger = logger; } logger.Information("Message")

 

3、怎麼把數據寫入自定義列

Serilog並無提供 Log.Debug(Message,IP)方法,在咱們平常開發中可能會有以下幾種需求:異步

一、設置全局Property

例如我須要記錄當前程序服務器的ip,或者我須要記錄當前服務的名稱,須要一個共用的字段。那麼咱們能夠在LoggerConfiguration的時候設置一個全局的Property,即在相同的LoggerConfiguration下面每條日誌均可以共用,咱們能夠這樣配置分佈式

Log.Logger = new LoggerConfiguration() .Enrich.FromLogContext() .Enrich.WithProperty("IP", GetIP()) .WriteTo.MSSqlServer( connectionString: Configuration["Serilog:ConnectionString"], tableName: Configuration["Serilog:TableName"], batchPostingLimit: Configuration.GetValue<int>("Serilog:BatchPostingLimit"),//批量插入數據庫條數
                   period: TimeSpan.FromSeconds(5),//執行時間間隔
                   restrictedToMinimumLevel: Configuration.GetValue<LogEventLevel>("Serilog:MinimumLevel"), columnOptions: columnOptions, autoCreateSqlTable: true ).CreateLogger();

二、設置ForContext寫入Property

例如我須要記錄當前類,須要在記錄日誌的時候設置ForContextide

Log.ForContext("Calss", GetType().FullName).Information("message");

這裏只是一個例子,其實serilog已經自動幫咱們記錄了Calss的信息,在Properties中能夠找到SourceContext節點,裏面就記錄了相關的命名空間和類ui

4、對日誌進行過濾

若是系統日誌太多,咱們很難快速找到有用的信息,因此不少時候咱們會對日誌進行過濾

一、經過MinimumLevel進行過濾

設置MinimumLevel的等級進行過濾,Serilog中Level有Verbose,Debug,Information,Warning,Error,Fatal幾個等級,Serilog只記錄當前等級及比當前等級高的日誌。

二、經過Override進行過濾

原理是serilog會記錄SourceContext,裏面包含了命名空間和類的信息,這裏咱們把SourceContext包含「Microsoft」的信息過濾掉,只記錄Error及Error級別以上的信息,配置以下:

Log.Logger = new LoggerConfiguration() .Enrich.FromLogContext() .Enrich.WithProperty("IP", GetIP()) .MinimumLevel.Override("Microsoft", LogEventLevel.Error) .WriteTo.MSSqlServer( connectionString: Configuration["Serilog:ConnectionString"], tableName: Configuration["Serilog:TableName"], batchPostingLimit: Configuration.GetValue<int>("Serilog:BatchPostingLimit"),//批量插入數據庫條數
                   period: TimeSpan.FromSeconds(5),//執行時間間隔
                   restrictedToMinimumLevel: Configuration.GetValue<LogEventLevel>("Serilog:MinimumLevel"), columnOptions: columnOptions, autoCreateSqlTable: true ).CreateLogger();

三、經過Filter進行過濾

經過Filter能夠過濾Properties中的值,好比通常咱們會對數據庫的錯誤比較重視,但願把數據庫錯誤單獨放在一個表中,這時須要用到Filter,咱們把SourceContext中包含數據訪問層命名空間的信息提取出來

string namespace = "DAL";//數據訪問層命名空間
 Log.Logger = new LoggerConfiguration() .Enrich.FromLogContext() .Enrich.WithProperty("IP", GetIP()) .MinimumLevel.Override("Microsoft", LogEventLevel.Error) .WriteTo.Logger(lc => lc.Filter.ByIncludingOnly(Matching.WithProperty(namespace)) .WriteTo.MSSqlServer( connectionString: Configuration["Serilog:ConnectionString"], tableName: Configuration["Serilog:DBErrorTableName"], batchPostingLimit: Configuration.GetValue<int>("Serilog:BatchPostingLimit"),//批量插入數據庫條數
                                               period: TimeSpan.FromSeconds(5),//執行時間間隔
 columnOptions: columnOptions, autoCreateSqlTable: true)) .WriteTo.Logger(lc => lc.Filter.ByExcluding(Matching.WithProperty(namespace)) .WriteTo.MSSqlServer( connectionString: Configuration["Serilog:ConnectionString"], tableName: Configuration["Serilog:DefaultTableName"], batchPostingLimit: Configuration.GetValue<int>("Serilog:BatchPostingLimit"),//批量插入數據庫條數
                                               period: TimeSpan.FromSeconds(5),//執行時間間隔
 columnOptions: columnOptions, autoCreateSqlTable: true)) .CreateLogger(); 

5、Enricher 

Enricher 的做用主要是增長記錄的信息,好比Enrich.WithThreadId(),能夠記錄線程信息,Enrich.WithProperty()能夠增長屬性信息

自定義Enricher 能夠參數這篇文章:https://www.cnblogs.com/weihanli/p/custom-serilog-enricher-to-record-more-info.html

 

參考資料

https://github.com/serilog/serilog

https://www.cnblogs.com/Leo_wl/p/7643400.html

https://www.cnblogs.com/Leo_wl/p/10943285.html

相關文章
相關標籤/搜索