我们有一个大型 Java 应用程序,我们使用 IKVM 将其转换为 .NET。其中的所有 log4j 调用都会调用我们创建的调用 log4net 的 log4j 包装器。大多数情况下它效果很好。
但是我们有一个问题 - 日志记录没有给出堆栈跟踪或 InnerException。我相信问题是 .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);
}
}
}
您在
MyExceptionRenderer
配置中注册 Log4net
,如下所示。
<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