4

我有一个具有多个属性的对象,这些属性与我网站上刚刚发生的事件有关。

我想记录这个事件,并让它的每个属性出现在 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 的影响(也许我的担心是没有根据的?)。

这是实现我想要的(即使用浓缩器)的正确/正确方法还是我错过了什么?

干杯!

4

1 回答 1

6

SerilogForContext()针对这种情况进行了很好的优化,并且不会产生太多垃圾(它会尽可能地避免它)。与开始记录数据的成本相比,创建上下文的成本不会显着。

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()on it 的方法,如Log.Information(...).

于 2016-10-07T05:39:56.673 回答