Добавить настраиваемые свойства в Serilog

Я использую Serilog с приемником MS SQL Server в своем приложении. Предположим, я определил следующий класс ...

public class Person
{
  public string FirstName { get; set; }
  public string LastName { get; set; }

  public DateTime BirthDate { get; set; }
  // ... more properties
}

... и создал экземпляр:

var person = new Person
{
    FirstName = "John",
    LastName = "Doe",
    BirthDate = DateTime.UtcNow.AddYears(-25)
};

Я разместил в своем коде следующий вызов журнала:

Log.Information("New user: {FirstName:l} {LastName:l}",
    person.FirstName, person.LastName);

Можно ли также регистрировать свойство BirthDate без добавления его в шаблон сообщения, чтобы оно отображалось в столбце Properties XML? Я хотел бы вывести его позже в подробном виде в средстве просмотра журнала моего приложения.

Я в основном ищу поведение, подобное деструктуризации объекта, но без печати плоского объекта как части сообщения журнала.


person Marius Schulz    schedule 11.01.2015    source источник


Ответы (3)


Это очень просто:

Log.ForContext("BirthDate", person.BirthDate)
   .Information("New user: {FirstName:l} {LastName:l}",
                           person.FirstName, person.LastName);
person Nicholas Blumhardt    schedule 11.01.2015
comment
Понятно, это довольно просто. Позволяет ли этот метод также деструктурировать объекты сложного типа (например, свойство Father типа Person)? Меня больше интересуют значения свойств, чем представление ToString(). - person Marius Schulz; 12.01.2015
comment
Совершенно верно - Log.ForContext("Father", father, destructureObjects: true) это делает. - person Nicholas Blumhardt; 12.01.2015
comment
Идеально! Именно то, что я искал. Я читал руководство, но, должно быть, как-то не заметил этого. Спасибо! - person Marius Schulz; 12.01.2015

На самом деле вы можете сделать это несколькими способами. В вашем случае, вероятно, лучше всего будет первый способ:

Log.ForContext("BirthDate", person.BirthDate)
    .Information("New user: {FirstName:l} {LastName:l}",
        person.FirstName, person.LastName);

Но вы также можете использовать LogContext в других сценариях:

Log.Logger = new LoggerConfiguration()
    // Enrich all log entries with properties from LogContext
    .Enrich.FromLogContext();

using (LogContext.PushProperty("BirthDate", person.BirthDate))
{
    Log.Information("New user: {FirstName:l} {LastName:l}",
        person.FirstName, person.LastName);
}

Или, если вы хотите зарегистрировать «постоянное» свойство, вы можете добавить его следующим образом:

Log.Logger = new LoggerConfiguration()
    // Enrich all log entries with property
    .Enrich.WithProperty("Application", "My Application");

См. Контекст и корреляция - концепции структурированного ведения журнала в .NET (5) для получения дополнительной информации.

person Christian Davén    schedule 05.11.2019
comment
.Enrich.FromLogContext() - это вызов, который мне не хватало, чтобы заставить работать фильтрацию на основе свойств! - person Alexis Leclerc; 14.07.2021

Если вы используете общий интерфейс Microsoft ILogger, вы можете использовать BeginScope;

using (_logger.BeginScope(new Dictionary<string, object> { { "LogEventType", logEventType }, { "UserName",  userName } }))
{
    _logger.LogInformation(message, args);
}

Это обсуждается здесь; https://blog.rsuter.com/logging-with-ilogger-recommendations-and-best-practices/

person Josh    schedule 29.09.2020