我有一个对象,其中有几个属性与我网站上刚刚发生的事件有关。
我想记录此事件,并将其每个属性显示在Seq中 - 作为属性。但是,想要从实际的日志消息文本中省略大多数属性 - 所以我不希望它们出现在消息模板中。 v
如果我这样做:
var logInfo= new LogInfo() {Foo = 1, Bar= "Pending"};
logger.Information("{@event}", logInfo);
在Seq中直接点亮日志的唯一属性是@event属性。它实际上看起来像这样:
所以我尝试了这个:
var enricher = new DnnLogInfoEnricher(logInfo);
using (LogContext.PushProperties(enricher))
{
Log.Logger.Information("Event: {logInfo}", logInfo.LogTypeKey, logInfo.Exception);
}
但是我对这种方法的关注是,由于这种方法会发生很多次,我不想每次都要创建一个新的更丰富的对象实例 - 因为我喜欢保持正在创建的对象数量通常尽可能低。仅仅因为我担心GC的影响(也许我的担忧没有根据?)。
这是实现我想要的正确/正确的方式(即使用浓缩器)还是我错过了什么?
干杯!
答案 0 :(得分:4)
Serilog的ForContext()
针对这种情况进行了很好的优化,并且不会创建太多垃圾(它尽可能地避免它)。创建上下文的成本与开始记录数据的成本成比例并不显着。
var log = Log.ForContext("Info", logInfo, destructureObjects: true);
log.Information(logInfo.Exception, "Event happened");
有一种观察结果,您可能最好从捕获的对象中排除异常并将其作为日志记录调用的第一个参数传递。要排除它,您可以在创建记录器时设置自定义策略:
Log.Logger = new LoggerConfiguration()
.Destructure.ByTransforming<LogInfo>(li => new {
li.BypassBuffering, li.LogConfigId, li.LogEventId, li.LogGUID
})
// <snip>
.CreateLogger();
虽然ByTransforming()
似乎在这里增加了更多的开销,但你应该能够通过仅挑选LogInfo
的有趣属性来获得更紧密和更有效的结果。
另一个小问题 - 没有必要在静态类上调用Log.Logger
; Log
直接使用Information()
等方法,如Log.Information(...)
。