.net core中的那些常用的日誌框架(Serilog篇)
阿新 • • 發佈:2020-10-15
### 前言
>上文說到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/