Serilog: Могу ли я добавить свойство, не добавляя к сообщению?

#serilog

#serilog

Вопрос:

У меня есть приложение для 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:QRTLogsQRT-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 отображался в сообщении, и я бы хотел, чтобы объект order был включен в качестве свойства (чтобы я мог получить к нему доступ, когда я углублюсь в это событие в Seq), но я не хочу, чтобы само сообщение содержало объект (слишком большой). Есть ли способ сделать это?

Или поэтому мне нужно что-то вроде этого:

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

Кажется, слишком много кода…

Ответ №1:

Вы можете добавить anther ForContext в свой регистратор для order объекта таким же образом, как вы добавляете InstrumentID , и он будет включен в качестве свойства

 _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:

Да, но здесь задействованы странные приемы


пример 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)) , где это чище / понятнее / эффективнее.

Комментарии:

1. Спасибо, но, похоже, ваш код предлагает использовать «Using»… но простое преобразование в скалярный. Итак, я предполагаю, что ответ отрицательный… Я должен использовать для ввода свойства «Using», если я не хочу, чтобы оно было в сообщении. Хотел бы я найти документацию по обогатителям…

2. Существует перегрузка ForContext, которая требует расширения, позвольте мне добавить и примеры…