记录exception属性

是否可以使用NLog记录exception的属性?

例如,SocketException具有ErrorCode,HResult,NativeErrorCode等属性,这些属性仅特定于此类exception。 可以在没有显式记录(即不使用Log(e.ErrorCode) )的情况下Log(e.ErrorCode)它们并使用代码中的ErrorException吗? 默认的Exception布局渲染器只是在exception上调用ToString。

我不知道这是不是一个好主意,但你可以编写自己的LayoutRenderer。 为了简单起见,我刚刚编写了一个inheritance自ExceptionLayoutRenderer并覆盖Append方法的方法。

 [LayoutRenderer("ExtendedException")] public class ExtendedExceptionLayoutRenderer : ExceptionLayoutRenderer { protected override void Append(System.Text.StringBuilder builder, LogEventInfo logEvent) { base.Append(builder, logEvent); var exception = logEvent.Exception; if (exception is SocketException) { var sockException = (SocketException) exception; builder.Append(sockException.ErrorCode).Append(" ").Append(sockException.SocketErrorCode); } } } 

SocketException的处理不是很复杂。 我确信有更好的方法,但它显示了你如何做到这一点。

要激活您必须调整您的配置,如下所示:

            

编辑

好的,我不知道你想要每个具有它自己的属性的exception的function。 如果你感兴趣的只有其他几个,你可以添加更多if(exception是YourExceptionType)并调整你感兴趣的属性。更通用的方法是使用reflection来记录定义的所有属性例外。

 [LayoutRenderer("ExtendedException")] public class ExtendedExceptionLayoutRenderer : ExceptionLayoutRenderer { protected override void Append(System.Text.StringBuilder builder, LogEventInfo logEvent) { var exception = logEvent.Exception; var type = exception.GetType(); var properties = type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public); var logEntries = new SortedDictionary(); foreach (var property in properties) { var name = property.Name; var value = property.GetValue(exception, null).ToString(); logEntries.Add(name, value); } foreach (var entry in logEntries) { builder.AppendFormat("{0}: {1} ", entry.Key, entry.Value); } base.Append(builder, logEvent); } } 

这会将按字母顺序在exception类型上声明的每个属性添加到日志输出中。

我不熟悉NLog,但是有可能在try / catch块中捕获exception,然后抛出自己类型的新exception,覆盖ToString以输出您在新exception类型中关注的数据吗?

这会在某种程度上破坏跟踪,因此您可能必须在ToString输出中包含原始exception的跟踪信息,但可能很容易解决。

我的另一个想法是扩展和覆盖SocketException的ToString,但我不相信这在C#中是可行的。

序列化exception并记录结果流?