Custom ThrowableRenderer ไม่ทำงาน log4j 1.x

Aug 27 2020

ฉันกำลังพยายามรับ throwableRenderer ที่กำหนดเองเพื่อทำงานกับ log4j 1.2.17
โปรดทราบว่าฉันไม่สามารถอัพเกรดเป็น log4j2 ได้ในขั้นตอนนี้ดังนั้นฉันจึงมองหาวิธีแก้ปัญหา 1.x

ดูเช่น
วิธีทำให้ log4j syslog appender เขียน stack trace ในบรรทัดเดียว?

ฉันกำลังพยายามทำแบบนั้น - รับสแต็กแทร็กที่จะพิมพ์ใน 1 บรรทัด ฉันลอง 2 วิธีที่หาได้บนเว็บ - โดยใช้ตัวแสดงผลแบบกำหนดเองและใช้ Enhanced Pattern Layout ยังไม่มีโชค!

แต่คลาสWRThrowableRenderer(ซึ่งเป็นเรนเดอร์ที่ฉันกำหนดเอง)
และเมธอดdoRenderนั้นไม่ได้ถูกเรียก
ทั้งหมดนี้อยู่ในเว็บแอปที่ทำงานภายใน WildFly 8 (Java 8)

ฉันลองอย่างน้อย 10 สิ่งที่แตกต่างกันในขณะที่ทดสอบทั้งสองวิธี แต่ไม่ได้ผล

ผมทำอะไรผิดหรือเปล่า?!

นอกจากนี้เรนเดอร์นี้ควรจะส่งผลกระทบต่อคนตัดไม้ทั้งหมดและเปลี่ยนพฤติกรรมเมื่อมีการบันทึกข้อยกเว้นหรือไม่ ฉันคิดอย่างนั้น ฉันถามสิ่งนี้เนื่องจากฉันมีคนตัดไม้เด็กภายใต้ rootLogger นี้ และพวกเขาทั้งหมดเข้าสู่ระบบผ่าน 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

คำตอบ

bmaupin Nov 20 2020 at 17:42

ฉันกำลังพยายามทำแบบนั้น - รับสแต็กแทร็กที่จะพิมพ์ใน 1 บรรทัด ฉันลอง 2 วิธีที่หาได้บนเว็บ - โดยใช้ตัวแสดงผลแบบกำหนดเองและใช้ Enhanced Pattern Layout

ไม่มี ThrowableRenderer แบบกำหนดเอง

หากคุณต้องการให้สแต็กติดตามทั้งหมดในบรรทัดเดียวโดยไม่ต้องใช้แบบกำหนดเอง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 แบบกำหนดเอง

  1. สร้าง ThrowableRenderer ที่กำหนดเองเช่น

    package org.example;
    
    import org.apache.log4j.DefaultThrowableRenderer;
    import org.apache.log4j.spi.ThrowableRenderer;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    
    public class CustomThrowableRenderer implements ThrowableRenderer {
        private final DefaultThrowableRenderer defaultRenderer = new DefaultThrowableRenderer();
    
        @Override
        public String[] doRender(Throwable throwable) {
            String[] defaultRepresentation = defaultRenderer.doRender(throwable);
            String[] newRepresentation = {String.join("|", Arrays.asList(defaultRepresentation))};
    
            return newRepresentation;
        }
    }
    
  2. กำหนดค่า 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 ที่กำหนดเอง

ฉันสร้างแอปตัวอย่างขนาดเล็กที่คุณสามารถใช้เป็นข้อมูลอ้างอิง: https://github.com/bmaupin/junkpile/tree/master/java/log4j1-custom-throwablerenderer