Text logging (本文日誌記錄):
1
[21:49:12 INF] Processed {"Latitude": 25, "Longitude": 134} in 034 ms.
Structured logging (結構化日誌記錄):
1
{"@t":"2023-03-02T13:49:12.7714869Z","@mt":"Processed {@Position} in {Elapsed:000} ms.","@r":["034"],"Position":{"Latitude":25,"Longitude":134},"Elapsed":34}
練習官方提供的範例
1
2
3
4
var position = new { Latitude = 25, Longitude = 134 };
var elapsedMs = 34;
Log.Information("Processed {@Position} in {Elapsed:000} ms.", position, elapsedMs);
- Position 前面的 @ 運算符,是告訴 Serilog 需要將傳入的對象序列化,而不是調用 ToString() 轉換它。
- Elapsed 後面的 :000 是一個標準的 .NET 格式字符串,它會影響屬性的呈現方式(034)。
此範例記錄兩個屬性:Position 和 Elapsed,以及一個日誌事件:
1
2
3
4
5
6
7
8
9
10
{
"@t": "2023-03-02T13:49:12.7714869Z",
"@mt": "Processed {@Position} in {Elapsed:000} ms.",
"@r": ["034"],
"Position": {
"Latitude": 25,
"Longitude": 134
},
"Elapsed": 34
}
- @t:Timestamp 事件時間
- @mt:message template 輸出原始定義的模板
- @r:Renderings 渲染後的效果
Elapsed:000 => 使用 :000 (.NET 格式字符串格式) 後呈現 034
範例中捕獲的 JSON 格式的屬性如下所示:
1
"Position":{"Latitude":25,"Longitude":134},"Elapsed":34}
在Console控制台上顯示如下:
1
[21:49:12 INF] Processed {"Latitude": 25, "Longitude": 134} in 034 ms.
練習一
1
2
var user = new { Id = 1001, Name = "Qoo" };
Log.Information("Created {@User} on {Datetmie}", user, DateTime.Now);
Text logging 顯示:
1
[03:41:57 INF] Created {"Id": 1001, "Name": "Qoo"} on 03/03/2023 03:41:57
Structured logging 顯示:
1
2
3
4
5
6
7
8
9
{
"@t": "2023-03-02T19:41:57.0306949Z",
"@mt": "Created {@User} on {Datetmie}",
"User": {
"Id": 1001,
"Name": "Qoo"
},
"Datetmie": "2023-03-03T03:41:57.0270496+08:00"
}
練習二
1
2
var fruit = new[] { "Apple", "Cherry", "Grape" };
Log.Information("I have {@Fruit}, total count {counts}", fruit, fruit.Count());
Text logging 顯示:
1
[04:03:15 INF] I have ["Apple", "Cherry", "Grape"], total count 3
Structured logging 顯示:
1
2
3
4
5
6
7
8
9
10
{
"@t": "2023-03-02T20:03:15.0121340Z",
"@mt": "I have {@Fruit}, total count {counts}",
"Fruit": [
"Apple",
"Cherry",
"Grape"
],
"counts": 3
}
完整程式碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using Serilog;
using Serilog.Formatting.Compact;
// Create the Serilog logger, and configure the sinks
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console()
.WriteTo.File(new CompactJsonFormatter(), "logs/log-.txt", rollingInterval: RollingInterval.Day)
.CreateLogger();
var count = 99;
var position = new { x = 123, y = 987 };
Log.Information("At {@Position} there are {Count} puppy.", position, count);
Log.CloseAndFlush();
Console 輸出顯示:
1
[04:20:42 INF] At {"x": 123, "y": 987} there are 99 puppy.
Log檔寫入Json格式:
1
2
3
4
5
6
7
8
9
{
"@t": "2023-03-02T20:20:42.7987978Z",
"@mt": "At {@Position} there are {Count} puppy.",
"Position": {
"x": 123,
"y": 987
},
"Count": 99
}
養好習慣將主程式用 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
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(); //程式結束前一定要呼叫它 (非常重要!!!)
}
Reference: