Исключите исключение с помощью пользовательских свойств и войдите с помощью 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
,