使用自定义属性冒泡异常并使用serilog登录

时间:2015-02-06 03:17:04

标签: c# serilog getseq

我遇到了一种情况,我认为重新抛出一个异常,向它添加额外的信息(例如在自定义异常中的属性中),当进一步向上捕获时,将记录其他信息以Serilog中消息模板的属性形式 - 最终目标是,然后我可以在Seq中过滤这些属性。这个场景可能是一个警告,我需要重新考虑我的异常处理,但我想我会问以前是否已经使用Serilog做了这个?推荐/气馁?

更新

以下是一个示例场景:

使用serilog和Seq,我们将“部门”属性应用于日志,以便部门可以轻松查看可能由他们负责的所有异常。

现在这个场景的应用基本上做了两件事:

  • 第1步:查询数据。
  • 步骤2:如果步骤1中没有例外,请将其发布到其他地方。

在第1步中深入了解了一个特殊的例外,我知道这是特定部门的责任。因此,我想在记录时将一个department属性应用于此异常,但同时将它捕获到堆栈的更高位置,以便异常阻止其他所有内容的继续。另外,我只想记录一次异常。

我目前的方法是使用可以保存日志属性的字典定义自定义异常:

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 个答案:

答案 0 :(得分:1)

最佳做法很难判断;而不是上面的ForContext()代码:

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

这将附加一个&#34;对象&#34;该事件的属性,携带ExtProperties的数据。