Исключите исключение с помощью пользовательских свойств и войдите с помощью serilog

Я столкнулся с ситуацией, когда я думал, что было бы хорошо перебросить исключение, добавив к нему дополнительную информацию (например, в свойствах в пользовательском исключении), что при дальнейшем поднятии стека будет регистрироваться с дополнительной информацией в форме свойств шаблона сообщения в Serilog - конечной целью является то, чтобы я мог затем фильтровать эти свойства в Seq. Этот сценарий может быть предупреждением о том, что мне нужно переосмыслить обработку исключений, но я решил спросить, было ли это сделано ранее с Serilog? Рекомендуется / обескуражен?

Обновить

Вот пример сценария:

Используя serilog и Seq, мы применяем свойство "Отдел" к журналу, чтобы отдел мог легко увидеть все исключения, которые, вероятно, являются его обязанностью.

Теперь приложение для этого сценария в основном делает две вещи:

  • Шаг 1: Запрос данных.
  • Шаг 2: Если на шаге 1 нет исключений, разместите его где-нибудь еще.

На нескольких уровнях в шаге 1 есть определенное исключение, которое, как я знаю, является ответственностью конкретного отдела. Поэтому я хотел бы применить свойство отдела к этому исключению, когда оно регистрируется, но в то же время оно должно быть перехвачено в стеке, так что исключение предотвращает продолжение всего остального. Кроме того, я хочу зарегистрировать исключение только один раз.

Мой текущий подход заключается в определении пользовательского исключения со словарем, который может содержать свойства для журнала:

public class ExtPropertiesException : Exception
{
    // Constructors here...

    /// <summary>
    /// Properties to log with the error message
    /// </summary>
    public Dictionary<string, object> ExtProperties { get; set; }
}

Поэтому, когда я ловлю исключение, я знаю, что это ответственность конкретного отдела, я перебрасываю его как ExtPropertiesException или как исключение, которое наследует его, присоединяя исходное исключение как внутреннее исключение.

Затем сделайте резервную копию стека, где есть общие шаги, у меня есть подвох:

try
{
    // Step 1
    // Step 2
}
catch (ExtPropertiesException ex)
{
    if (ex.ExtProperties != null)
    {
        foreach (var prop in ex.ExtProperties)
        {
            logger = logger.ForContext(prop.Key, prop.Value);
        }
    }
    logger.Error(ex, ex.Message);
}

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

Первоначально я делал журналы и применял свойство в то время, когда ловил исключение, а затем просто возвращал false или null, чтобы указать на сбой и отказаться от будущих шагов, однако мне было сложно проводить модульное тестирование, так как я не могу определить тип ошибок извне методов.

Спасибо

1 ответ

Решение

Трудно судить о лучшей практике; а не ForContext() Код выше вы можете сделать:

try
{
    // Step 1
    // Step 2
}
catch (ExtPropertiesException ex)
{
    logger.Error(ex, "Exception caught, data is {@ExtProperties}", ex.ExtProperties);
}

Это прикрепит к событию одно свойство "object", переносящее данные из ExtProperties,

Другие вопросы по тегам