我如何接管在 log4net 中编写异常

How can I take over writing an exception in log4net

我们有一个大型 Java 应用程序,我们使用 IKVM 将其转换为 .NET。其中的所有 log4j 调用都调用我们创建的调用 log4net 的 log4j 包装器。大多数情况下效果很好。

但是我们有一个问题 - 日志记录没有提供堆栈跟踪或 InnerException(s)。我认为问题是 .NET Exception.ToString() 提供了所有这些信息,而 Java Throwable.toString() 基本上是 Exception.Message.

因此,在 log4net 调用 Exception.ToString() 的地方,我需要为从 java.lang.Throwable 继承的任何异常替换它以创建字符串。我该怎么做?

在调用 Exception.ToString() 之前,Log4net 查看自定义 IObjectRenderer 是否已为 Exception 注册(因为它也为任何其他类型).

为了获得自定义 Exception 输出,您需要创建并注册自定义 IObjectRenderer.

下面的将输出大写的 Exception
您可以自由构建传递给 writer.Write.

的任何错误消息字符串表示
namespace PFX
{
    public class MyExceptionRenderer : IObjectRenderer
    {
        public void RenderObject(RendererMap rendererMap, object obj, TextWriter writer)
        {
            Exception exception = obj as Exception;
            // Format the error message as pleased here.
            String error = exception.ToString().ToUpper();
            writer.Write(error);
        }
    }
}

您在 Log4net 配置中注册 MyExceptionRenderer,如下所示。

<log4net>
    <appender name="consoleAppender" type="log4net.Appender.ConsoleAppender" >        
        <layout type="log4net.Layout.PatternLayout">            
            <conversionPattern value="%date | %logger | %level | %message | %exception%n" />
        </layout>
    </appender>
    <root>
        <level value="All" />        
        <appender-ref ref="consoleAppender" />
    </root>

    <renderer renderingClass="PFX.MyExceptionRenderer"
              renderedClass="System.Exception" />
</log4net>

下面的代码

var logger = LogManager.GetLogger("AppLog");
var exception = new ApplicationException("Ooops");
logger.Error("An error occured.", exception);

会有如下日志输出。
请注意,异常是全大写的。

2019-05-08 21:52:22,855 | AppLog | ERROR | An error occured. | SYSTEM.APPLICATIONEXCEPTION: OOOPS