【问题标题】:Serilog: Can I add a property without adding to the message?Serilog:我可以在不添加消息的情况下添加属性吗?
【发布时间】:2019-03-20 05:05:33
【问题描述】:

我有一个 WIndows .NET 应用程序,并开始使用 Serilog。 我这样初始化:

Log.Logger = new LoggerConfiguration()
  .MinimumLevel.Verbose()
.Enrich.With(new ThreadIdEnricher())
.Enrich.WithProperty("BuildId", Guid.NewGuid()) // One Guid per run.
.Enrich.FromLogContext()
.WriteTo.RollingFile(@"C:\QRT\Logs\QRT-LOG.txt", LogEventLevel.Verbose)
.WriteTo.Seq("http://localhost:5341" )
.WriteTo.Console(outputTemplate:"{Source} BLAHBLAH {Message:lj}")
.WriteTo.File(new CompactJsonFormatter(), "C:/QRT/Logs/log.json")
.CreateLogger();

我是这样使用它的:

_log = Log.ForContext<GameBase>()
.ForContext("InstrumentID", InstrumentId);
_log.Verbose("This is an order: {orderID} / {order}", order.OrderID, order);

我希望我的 OrderID 显示在消息中,并且我希望将订单对象作为属性包含(以便在我在 Seq 中深入研究此事件时可以访问它),但我不希望消息本身包含对象(太大)。有没有办法做到这一点?

所以我需要这样的东西:

using (var __log = _log.PushProperty("order", order)
{
  __log.Verbose ("Hit {orderID}", orderID);
}

好像有很多代码...

【问题讨论】:

    标签: serilog


    【解决方案1】:

    您可以像添加 InstrumentID 一样将花药 ForContext 添加到 order 对象的记录器中,它将作为属性包含在内

    _log = Log.ForContext<GameBase>()
        .ForContext("InstrumentID", InstrumentId)
        .ForContext("Order", order, true);
    
    _log.Verbose("This is an order: {orderID}", order.OrderID);
    

    【讨论】:

      【解决方案2】:
      _log.ForContext("order", order, true).Verbose("Hit {orderID}", orderID);
      

      这里的true 告诉 Serilog 序列化(“解构”)order,而不是调用它的 ToString() 方法。

      【讨论】:

        【解决方案3】:

        是的,但是there are weird tricks involved


        eta 示例:

        class ScalarValueEnricher : ILogEventEnricher
        {
            readonly LogEventProperty _prop;
        
            public ScalarValueEnricher(string name, object value)
            {
                _prop = new LogEventProperty(name, new ScalarValue(value));
            }
        
            public void Enrich(LogEvent evt, ILogEventPropertyFactory _)
            {
                 evt.AddPropertyIfAbsent(_prop);
            }
        }
        

        这样消费:

        var _log = Log.ForContext<GameBase>()
            .ForContext("InstrumentID", InstrumentId);
        
        _log.ForContext(new ScalarEnricher("order",order)).Verbose("Hit: {orderID}", order.OrderID);
        

        您当然也可以从_log.ForContext(new ScalarEnricher("order",order)) 制作临时文件,这样更干净/更清晰/更高效。

        【讨论】:

        • 谢谢,但您的代码似乎建议使用“使用”...但简单地转换为标量。所以我想答案是否定的......如果我不想在消息中使用它,我必须使用“使用”来推送属性。我希望我能找到关于 Enrichers 的文档...
        • 有一个 ForContext 的重载需要一个丰富器,让我添加示例......
        猜你喜欢
        • 2017-03-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多