[英]Is there a way to provide custom property formatting with Serilog?
我有一個BackgroundTask
類,我將它設置為在事情發生時記錄事件,例如任務完成時。 例如,對於Success
案例,我調用Log.Verbose("{Task} completed successfully", this);
我的默認ToString()
包括進度,但對於已完成的任務,我們知道它是 100%,所以我想忽略它。 我知道對於數字類型,您可以傳入自定義格式說明符字符串(例如"{IntProperty:p5}"
,這會將我的 int 呈現為帶有 5 個小數位的百分比),並且我希望能夠執行相同的操作,例如Log.Information("{Task:Name}", this)
,它會將"Name"
傳遞到我的ToString()
方法中。
我嘗試添加許多不同的方法,例如添加ToString()
的(不接受任何內容、字符串、字符串和IFormatProvider
)、實現IFormattable
、強制字符串化等,但似乎沒有任何效果。 我可以看到 Serilog 正確解析了我的格式字符串:( PropertyBinder.cs
, ConstructNamedProperties()
第 111 行)
這調用了ConstructProperty()
,它只是忽略了令牌的Format
屬性,這解釋了為什么它被忽略了,但我想知道是否有一種我沒有想到的方法可以工作。
PS是的,我知道我可以做幾個選擇,但我寧願不做這些:
Log.Information("{Task}", new {Name = this.Name, Id = this.Id});
ToString()
- 與 (1) 相同,這會破壞原始文件,並意味着它不會與所有信息一起存儲。 例如Log.Information("{Task}", this.ToString("Custom Format"));
ToStringFormat
- 這似乎是不好的做法,只會增加額外的混亂,更不用說並發問題了。 例如this.Format = "Custom FOrmat"; Log.Information("{Task}", this);
this.Format = "Custom FOrmat"; Log.Information("{Task}", this);
這是由於 Serilog 管道中的捕獲和格式化之間的分離。
為了在渲染到接收器時處理像:X
這樣的格式字符串,實現IFormattable
的原始對象需要可用。
但是,因為接收器通常異步處理事件,Serilog 不能確定任何給定的記錄對象是線程安全的,因此在使用ToString()
記錄的時間/站點捕獲任何未知類型。
為了解決這個問題,你需要告訴 Serilog 你的Point
類是一個(基本上不可變的)值類型:
.Destructure.AsScalar(typeof(Point))
當記錄器被配置時。 然后,您可以在Point
上實現IFormattable
並在模板中使用{Point:X}
等。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.