Home [C# 筆記] Serilog 初識
Post
Cancel

[C# 筆記] Serilog 初識

使用 Serilog 紀錄 Log (不用設定檔)

1
2
3
4
5
6
7
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .WriteTo.Console()
    .WriteTo.File(new CompactJsonFormatter(),"logs/log-.txt", rollingInterval: RollingInterval.Day)
    .CreateLogger();
Log.Information("Hi, serilog.");
Log.CloseAndFlush();
  1. 初始化 Serilog 設定 Log.Logger = new LoggerConfiguration()...CreateLogger();
  2. 記錄 Log Log.Debug("xxx"); ...
  3. 程式結束前關閉它 Log.CloseAndFlush(); (非常重要!!!)

※ 在初始化 Serilog 設定時,可以自行配置添加接收器(Sinks):例如 Console, File, Email…。


一、安裝 Serilog 套件

使用 NuGet 安裝 Serilog 套件:

  • Serilog
  • Serilog.Sinks.Console (在控制台中顯示)
  • Serilog.Sinks.File (寫入檔案)

或是 Nuget Package Console 輸入指令:

1
2
3
Install-Package Serilog
Install-Package Serilog.Sinks.Console 
Install-Package Serilog.Sinks.File

二、使用

使用 Serilog 內置的靜態 Log (Log.Logger)

1
2
3
Log.Logger = new LoggerConfiguration().CreateLogger(); //初始化 Serilog 設定
Log.Debug("Hello, Serilog"); //記錄Log
Log.CloseAndFlush(); //程式結束前關閉(很重要!!!)

上面寫法是看不到任何輸出內容,因為還缺少輸出方式Sinks(還沒配置Sinks接收器)

Sinks (接收器)

常用的Sinks有Console、File 和 Email,可以在 Nuget 中分別下載:

  • Serilog.Sinks.Console
  • Serilog.Sinks.File
  • Serilog.Sinks.Email

加入 Console 和 File 接收器(Sinks):

1
2
3
4
5
Log.Logger = new LoggerConfiguration()
    .WriteTo.Console()
    .WriteTo.File("log.txt")
    .CreateLogger();
Log.Information("Hello, Serilog");

上面加入了 Console 和 File 的接收器,這樣 Log 就可以顯示在控制台中和寫入檔案了。

上面運行結果後,在控制台和 log.txt 文件中的Log內容為本文格式:

1
2023-02-28 00:00:54.568 +08:00 [INF] Hello, Serilog.

Formatting JSON (JSON 格式)

如果想要把整個 Log記錄成 Json 格式,可以引用Serilog.Formatting.Compact,加上new CompactJsonFormatter()

Log文件輸出為JSON 格式:

1
2
3
Log.Logger = new LoggerConfiguration()  
    .WriteTo.File(new CompactJsonFormatter(), "log.txt")
    .CreateLogger();

範例練習:控制台、Log檔(整個Log記錄)輸出為Json 格式,log檔名以當天日期命名

1
2
3
4
5
6
7
8
9
10
11
12
using Serilog;
using Serilog.Formatting.Compact;

Log.Logger = new LoggerConfiguration()
    .WriteTo.Console(new CompactJsonFormatter()) //控制台輸出Json格式
    .WriteTo.File(new CompactJsonFormatter(), //Log儲存Json格式
        "logs/log-.txt", //log存放位置。logs/log-20230228.txt
        rollingInterval: RollingInterval.Day) //log檔以日期命名
    .CreateLogger();

Log.Information("Hello, Serilog!");
Log.CloseAndFlush();

運行結果後,可以看到輸出為JSON 格式:

1
{"@t":"2023-02-28T00:35:49.0976672Z","@mt":"Hello, Serilog."}

MinimumLevel 属性 (Log Event Level)

  • Serlog 默認處理的日誌級別為 Information。
  • 如果要使用 Log.Debug(“xxx”),一定要修改為最低級別為Debug模式,不然不會有任何顯示,因為Serlog默認處理的最低級別為 Information。

Log Event Level (日誌級別)

Serilog 的日誌級別(LogEventLevel)有 6 個層級,從 0 到 5 數字(由低到高)依序為:

Verbose (0) => Debug (1) => Information (2) => Warning (3) => Error (4) => Fatal (5)

所以在 Serilog 默認情況下,會輸出 Information 及該以上等級的日誌 (輸出2~5的級別)。

也就是說,如果 Serilog 設定最低級別為 Debug .MinimumLevel.Debug(),那麼 Debug, Information, Warning, Error, Fatal 等級的 Log 都會被記錄下來。

1
2
3
4
5
6
7
8
9
10
11
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .WriteTo.Console()
    .CreateLogger();

Log.Verbose("Hey Serilog");
Log.Debug("Hey Serilog");
Log.Information("Hey Serilog");
Log.Warning("Hey Serilog");
Log.Error("Hey Serilog");
Log.Fatal("Hey Serilog");

輸出結果可以看到:

1
2
3
4
5
[02:11:16 DBG] Hey Serilog
[02:11:18 INF] Hey Serilog
[02:11:18 WRN] Hey Serilog
[02:11:18 ERR] Hey Serilog
[02:11:18 FTL] Hey Serilog

若要記錄 Verbose 等級的 Log (記錄所有的級別),就是將 MinimumLevel 属性設為 Verbose .MinimumLevel.Verbose()

三、將主程式用 try/catch/finally 包起來

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//初始化Serilog設定(配置Sinks接收器)
Log.Logger = new LoggerConfiguration()...CreateLogger();

try 
{
    //主程式的所有程式碼放這裡(正常流程的程式碼)
    Log.Verbose("Hey");
    Log.Debug("Hey");
    Log.Information("Hey");
    Log.Warning("Hey");
    Log.Error("Hey");
    Log.Fatal("Hey");
    
} catch (Exception ex) 
{
    //記錄捕捉的例外 (Unhandled Exception)
    //程式發生錯誤時會執行的區塊
    Log.Error(ex, "Something went wrong");
} finally 
{
    //不論程式是否發生錯誤都一定會執行的區塊
    //程式結束前一定要呼叫它 (非常重要!!!)
    Log.CloseAndFlush();
}

四、範例程式碼

練習除法運算: 10/0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using Serilog;

// Create the Serilog logger, and configure the sinks
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .WriteTo.Console()
    .WriteTo.File("logs/log-.txt", rollingInterval: RollingInterval.Day)
    .CreateLogger();

Log.Information("Hey serilog, let's debgug division.");

int a = 10, b = 0;
// Wrap creating and running the host in a try-catch block
try 
{
    Log.Debug("Dividing {A} by {B}", a, b);
    Console.WriteLine(a / b);
} 
catch (Exception ex)
{
    Log.Error(ex, "Something went wrong");
} 
finally
{   // Finally, once just before the application exits…
    Log.CloseAndFlush(); //程式結束前一定要呼叫它 (非常重要!!!)
}

輸出結果可以看到:

1
2
3
4
5
[00:03:08 INF] Hey serilog, let's debgug division.
[00:04:51 DBG] Dividing 10 by 0
[00:04:51 ERR] Something went wrong
System.DivideByZeroException: Attempted to divide by zero.
   at Program.<Main>$(String[] args) in C:\Users\rivalin\source\repos\vs workspace\logDemo\SerilogConsoleDemo\Program.cs:line 1

Reference:

This post is licensed under CC BY 4.0 by the author.