Java 自定义一次性渲染器不工作log4j 1.x

Java 自定义一次性渲染器不工作log4j 1.x,java,jboss,log4j,wildfly,Java,Jboss,Log4j,Wildfly,我正在尝试使用log4j 1.2.17定制一次性渲染器。 请注意,我无法在此阶段升级到log4j2,因此我正在寻找1.x解决方案 参见例如 我正试图这样做-让堆栈跟踪打印在一行上。我尝试了两种在网上可以找到的方法——使用自定义渲染器和使用增强的模式布局。还是不走运 但是类WRThrowableRenderer(这是我的自定义渲染器) 它的方法doRender根本不被调用。 这都是在WildFly 8(Java 8)内部运行的web应用程序中实现的 在测试这两种方法时,我尝试了至少10种不同的方

我正在尝试使用log4j 1.2.17定制一次性渲染器。
请注意,我无法在此阶段升级到log4j2,因此我正在寻找1.x解决方案

参见例如

我正试图这样做-让堆栈跟踪打印在一行上。我尝试了两种在网上可以找到的方法——使用自定义渲染器和使用增强的模式布局。还是不走运

但是类
WRThrowableRenderer
(这是我的自定义渲染器)
它的方法
doRender
根本不被调用。
这都是在WildFly 8(Java 8)内部运行的web应用程序中实现的

在测试这两种方法时,我尝试了至少10种不同的方法,但都不起作用

我做错了什么

此外,当记录异常时,此渲染器是否应该影响所有记录器并更改其行为?我认为是这样。我问这个问题是因为我在这个rootLogger下有儿童记录器。它们都通过根记录器记录在一个文件中

log4j.rootLogger=INFO, stdout

log4j.throwableRenderer=com.yb.common.logging.WRThrowableRenderer

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.EnhancedPatternLayout
# log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t] ###%c{20}:%L### - [[[%m]]]%n
# log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t] ###%c{20}### [[[%m]]]%n %throwable{separator(|)}
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t] ###%c{20}### [[[%m]]]%n
# log4j.appender.stdout.layout.ConversionPattern=%m%n

log4j.appender.stdout.threshold=INFO
log4j.appender.stdout.immediateFlush=true
我正试图这样做-让堆栈跟踪打印在一行上。我尝试了两种在网上可以找到的方法——使用自定义渲染器和使用增强的模式布局

没有自定义的一次性渲染器 如果希望堆栈跟踪全部在一行上,而不使用自定义的
ThrowableRenderer
,那么最好是获取堆栈跟踪的第一行

例如,使用此配置:

log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.EnhancedPatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%d] %-5p %m %throwable{short}%n
将生成此日志:

[2020-11-20 10:54:53,454] ERROR Test error message, with stack trace java.lang.IllegalArgumentException: Test exception message
使用自定义的一次性渲染器 如果希望将整个堆栈跟踪打印在一行上,则需要使用自定义的ThrowableRenderer

  • 创建自定义的ThrowableRenderer,例如

    package org.example;
    导入org.apache.log4j.DefaultThrowableRenderer;
    导入org.apache.log4j.spi.ThrowableRenderer;
    导入java.util.ArrayList;
    导入java.util.array;
    公共类CustomThrowableRenderer实现ThrowableRenderer{
    private final DefaultThrowableRenderer defaultRenderer=新的DefaultThrowableRenderer();
    @凌驾
    公共字符串[]doRender(可丢弃可丢弃){
    字符串[]defaultRepresentation=defaultRenderer.doRender(可丢弃);
    String[]newRepresentation={String.join(“|”),Arrays.asList(defaultRepresentation))};
    返回新的代表;
    }
    }
    
  • 配置log4j1以使用自定义ThrowableRenderer

    log4j.throwableRenderer=org.example.CustomThrowableRenderer
    
  • 此时,日志的堆栈跟踪部分将全部位于一行上,尽管它可能与日志的其余部分位于单独的一行上

    例如,您从上面的配置:

    log4j.rootLogger=INFO, stdout
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.EnhancedPatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t] ###%c{20}### [[[%m]]]%n
    log4j.throwableRenderer=org.example.CustomThrowableRenderer
    
    将生成两行,因为默认情况下堆栈跟踪放在自己的行上:

    2020-11-20 11:45:04.706 ERROR [main] ###org.example.App### [[[Test error message, with stack trace]]]
    java.lang.IllegalArgumentException: Test exception message|     at org.example.App.logErrorWithStackTrace(App.java:31)| at org.example.App.okayThatsEnough(App.java:25)|        at org.example.App.notLongEnough(App.java:21)|  at org.example.App.makeStackTraceLonger(App.java:17)|   at org.example.App.testLoggingWithStackTraces(App.java:13)|     at org.example.App.main(App.java:9)
    
    您可以在模式中使用
    %throwable
    在一行上获取错误消息和堆栈跟踪:

    log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t] ###%c{20}### [[[%m]]] %throwable%n
    
    但是,在以下情况下将生成一个空行:

    2020-11-20 11:46:46.897 ERROR [main] ###org.example.App### [[[Test error message, with stack trace]]] java.lang.IllegalArgumentException: Test exception message|       at org.example.App.logErrorWithStackTrace(App.java:31)| at org.example.App.okayThatsEnough(App.java:25)|        at org.example.App.notLongEnough(App.java:21)|  at org.example.App.makeStackTraceLonger(App.java:17)|   at org.example.App.testLoggingWithStackTraces(App.java:13)|     at org.example.App.main(App.java:9)
    
    
    这可能也会被修复,但它可能需要一个自定义的appender

    我制作了一个小样本应用程序,可供参考:

    我正试图这样做-让堆栈跟踪打印在一行上。我尝试了两种在网上可以找到的方法——使用自定义渲染器和使用增强的模式布局

    没有自定义的一次性渲染器 如果希望堆栈跟踪全部在一行上,而不使用自定义的
    ThrowableRenderer
    ,那么最好是获取堆栈跟踪的第一行

    例如,使用此配置:

    log4j.rootLogger=INFO, stdout
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.EnhancedPatternLayout
    log4j.appender.stdout.layout.ConversionPattern=[%d] %-5p %m %throwable{short}%n
    
    将生成此日志:

    [2020-11-20 10:54:53,454] ERROR Test error message, with stack trace java.lang.IllegalArgumentException: Test exception message
    
    使用自定义的一次性渲染器 如果希望将整个堆栈跟踪打印在一行上,则需要使用自定义的ThrowableRenderer

  • 创建自定义的ThrowableRenderer,例如

    package org.example;
    导入org.apache.log4j.DefaultThrowableRenderer;
    导入org.apache.log4j.spi.ThrowableRenderer;
    导入java.util.ArrayList;
    导入java.util.array;
    公共类CustomThrowableRenderer实现ThrowableRenderer{
    private final DefaultThrowableRenderer defaultRenderer=新的DefaultThrowableRenderer();
    @凌驾
    公共字符串[]doRender(可丢弃可丢弃){
    字符串[]defaultRepresentation=defaultRenderer.doRender(可丢弃);
    String[]newRepresentation={String.join(“|”),Arrays.asList(defaultRepresentation))};
    返回新的代表;
    }
    }
    
  • 配置log4j1以使用自定义ThrowableRenderer

    log4j.throwableRenderer=org.example.CustomThrowableRenderer
    
  • 此时,日志的堆栈跟踪部分将全部位于一行上,尽管它可能与日志的其余部分位于单独的一行上

    例如,您从上面的配置:

    log4j.rootLogger=INFO, stdout
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.EnhancedPatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t] ###%c{20}### [[[%m]]]%n
    log4j.throwableRenderer=org.example.CustomThrowableRenderer
    
    将生成两行,因为默认情况下堆栈跟踪放在自己的行上:

    2020-11-20 11:45:04.706 ERROR [main] ###org.example.App### [[[Test error message, with stack trace]]]
    java.lang.IllegalArgumentException: Test exception message|     at org.example.App.logErrorWithStackTrace(App.java:31)| at org.example.App.okayThatsEnough(App.java:25)|        at org.example.App.notLongEnough(App.java:21)|  at org.example.App.makeStackTraceLonger(App.java:17)|   at org.example.App.testLoggingWithStackTraces(App.java:13)|     at org.example.App.main(App.java:9)
    
    您可以在模式中使用
    %throwable
    在一行上获取错误消息和堆栈跟踪:

    log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t] ###%c{20}### [[[%m]]] %throwable%n
    
    但是,在以下情况下将生成一个空行:

    2020-11-20 11:46:46.897 ERROR [main] ###org.example.App### [[[Test error message, with stack trace]]] java.lang.IllegalArgumentException: Test exception message|       at org.example.App.logErrorWithStackTrace(App.java:31)| at org.example.App.okayThatsEnough(App.java:25)|        at org.example.App.notLongEnough(App.java:21)|  at org.example.App.makeStackTraceLonger(App.java:17)|   at org.example.App.testLoggingWithStackTraces(App.java:13)|     at org.example.App.main(App.java:9)
    
    
    这可能也会被修复,但它可能需要一个自定义的appender


    我制作了一个小样本应用程序,您可以作为参考:

    谢谢。。。我在log4j中做了一个hack/patch,现在我的东西可以正常工作了。但也许你在这里提出的解决方案更好。我得调查一下。谢谢。。。我在log4j中做了一个hack/patch,现在我的东西可以正常工作了。但也许你在这里提出的解决方案更好。我得调查一下。