วิธีป้องกัน logback ไม่ให้แสดงสถานะของตนเองในตอนเริ่มต้นของทุกบันทึก


145

ดูเหมือนว่าจะเป็นข้อผิดพลาดที่ไม่ระมัดระวัง แต่ฉันไม่สามารถหาสาเหตุได้ การบันทึกด้วย logback / slf4j (เวอร์ชันล่าสุด slf4j-api-1.6.1, logback core / classic 0.9.24) การกำหนดค่าบันทึกที่ง่ายที่สุดสำหรับการทดสอบคือ:

<configuration>
 <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
  <layout class="ch.qos.logback.classic.PatternLayout">
   <!-- DONT USE THIS FORMATTER FOR LIVE LOGGING THE %L LINE NUMBER OUTPUTTER IS SLOW -->
   <pattern>%le %-1r [%c{1}:%L] %m%n</pattern>
  </layout>
 </appender>
 <root level="DEBUG">
  <appender-ref ref="stdout" />
 </root>
</configuration>

ทุกการตั้งค่าการบันทึกเริ่มต้นด้วยบรรทัดสถานะภายในของ logback:

11:21:27,825 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
11:21:27,826 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback-test.xml] at [file:.../logback-test.xml]
11:21:28,116 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
11:21:28,124 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
11:21:28,129 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [stdout]
11:21:28,180 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Pushing component [layout] on top of the object stack.
11:21:28,206 |-WARN in ch.qos.logback.core.ConsoleAppender[stdout] - This appender no longer admits a layout as a sub-component, set an encoder instead.
11:21:28,206 |-WARN in ch.qos.logback.core.ConsoleAppender[stdout] - To ensure compatibility, wrapping your layout in LayoutWrappingEncoder.
11:21:28,206 |-WARN in ch.qos.logback.core.ConsoleAppender[stdout] - See also http://logback.qos.ch/codes.html#layoutInsteadOfEncoder for details
11:21:28,207 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to DEBUG
11:21:28,207 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [stdout] to Logger[ROOT]

ซึ่งเป็นไปตามเอกสารการบันทึกข้อมูลรูปแบบใช้สำหรับการเริ่มต้น จากนั้นอ่านการกำหนดค่าให้เสร็จ (ซึ่งถูกตั้งค่าให้ส่งออกรูปแบบที่แตกต่างกัน) และดำเนินการต่อด้วยเอาต์พุตที่จัดรูปแบบอย่างเหมาะสม มีพารามิเตอร์กำหนดค่า<configuration debug="false">ซึ่งไม่ส่งผลกระทบต่อสิ่งนี้

ใครรู้วิธีปิดนี้


การ logback รุ่นล่าสุดเร็วกว่ามากในการคำนวณ% L
Thorbjørn Ravn Andersen

@ ThorbjørnRavnAndersen docs พูดว่า "L / line: การสร้างข้อมูลหมายเลขบรรทัดนั้นไม่เร็วนักดังนั้นควรหลีกเลี่ยงการใช้งานเว้นแต่ว่าความเร็วในการประมวลผลจะไม่มีปัญหา" FWIW: logback.qos.ch/manual/layouts.html (ดังนั้นอาจจะเร็วกว่า แต่ก็ยังไม่เร็วหรืออะไร ... )
rogerdpack

@rogerdpack ใช่ พบได้โดยการวิเคราะห์การติดตามสแต็กของข้อยกเว้น นั่นกลายเป็นเร็วขึ้น
Thorbjørn Ravn Andersen

คำตอบ:


249

หากคุณตั้งค่าdebugคุณลักษณะของconfigurationองค์ประกอบเป็นtrueคุณจะได้รับข้อมูลสถานะทั้งหมดไปยังคอนโซล หากนี่คือปัญหาของคุณเพียงตั้งเป็นเท็จหรือลบออก

หากคุณมีปัญหาการกำหนดค่าระดับWARNหรือสูงกว่าคุณจะได้รับข้อมูลสถานะทั้งหมดเข้าสู่คอนโซล (รวมถึงข้อความระดับINFO) ทางออกที่ดีที่สุดสำหรับปัญหานี้คือการแก้ไขปัญหา (ในกรณีของคุณแทนที่<layout>องค์ประกอบด้วย<encoder>องค์ประกอบ)

หากคุณด้วยเหตุผลบางอย่างไม่สามารถแก้ไขปัญหา StatusListenerแต่ต้องการลบสถานะข้อมูลจากคอนโซลคุณแทนสามารถกำหนดค่าทางเลือก ใช้NopStatusListenerเพื่อลบข้อมูลสถานะอย่างสมบูรณ์:

<configuration>
  <statusListener class="ch.qos.logback.core.status.NopStatusListener" />
  <!-- etc -->
</configuration>

9
นี่คือคำตอบที่ถูกต้องควรเพิ่มขึ้นอีกขอบคุณ (logback 1.0.11)
Jakub Kulhan

3
สิ่งนี้ใช้ได้ผล ฉันยังไม่ชัดเจนว่าINFOข้อความบันทึกจะหายไปเช่นกัน แต่ในความเป็นจริงพวกเขาทำ ฉันรู้คำตอบว่าสิ่งนี้ แต่ด้วยเหตุผลบางอย่างมันไม่ชัดเจนสำหรับฉัน ชัดเจนแล้ว: แก้ไขปัญหาตัวเข้ารหัส / เลย์เอาต์และไม่เพียง แต่ข้อความเตือนจะหายไป แต่ข้อความข้อมูลก็จะหายไปเช่นกันแม้ว่าจะไม่เกี่ยวข้องกับปัญหาก็ตาม
เจสัน

3
ไม่ได้ทำงานกับแอตทริบิวต์ debug แต่ทำงานได้อย่างไร้ที่ติกับ listener status
อะมีบา Spugnosa

ขอบคุณ - ผู้ฟังสถานะที่จำเป็น
Ezekiel Victor

2
ใช้วิธีการนี้อย่างระมัดระวังดูเหมือนว่าจะใช้งานได้ แต่มันซ่อนข้อเท็จจริงที่ว่าคุณมีข้อผิดพลาดในการกำหนดค่าในไฟล์ของคุณ ปัญหาที่แท้จริงคือบันทึกของ WARN ปัญหาเหล่านี้ควรได้รับการแก้ไขในการกำหนดค่าจากนั้นบันทึกทั้งหมดจะถูกรวมเข้าด้วยกัน INFO หายไป
teknopaul

45

ตามที่อธิบายไว้ในเอกสารหากคำเตือนหรือข้อผิดพลาดเกิดขึ้นระหว่างการวิเคราะห์ไฟล์การกำหนดค่าการบันทึกจะพิมพ์ข้อมูลสถานะบนคอนโซลโดยอัตโนมัติ

ทำตามhttp://logback.qos.ch/codes.html#layoutInsteadOfEncoderเช่นลิงก์ที่กล่าวถึงโดย logback ในข้อความเตือน เมื่อคุณทำตามขั้นตอนที่กล่าวถึงนั่นคือถ้าคุณแทนที่องค์ประกอบ <layout> ด้วย <encoder> การบันทึกจะหยุดการพิมพ์ข้อความบนคอนโซล


4
เรียงลำดับถูกต้องแม้ว่าคุณจะชี้ให้ฉันในทิศทางที่ถูกต้อง ฉันเปลี่ยนไปเป็นซินเดอเรเตอร์ตัวนั้นโดยไม่มีผลกระทบแม้ว่ามันจะปรากฎว่าการลบบรรทัดอื่นใน logback.xml ที่ทำให้เกิดการเตือนก็เป็นการหลอกลวง สิ่งที่หลอกลวงเกี่ยวกับเรื่องนี้ก็คือดูเหมือนว่าเอาต์พุตจะเป็นการตัดสินใจเอาต์พุตก่อนที่จะวิเคราะห์ไฟล์ logback ของคุณ (1> ไม่สามารถหาทรัพยากร [logback.groovy], 2> ทรัพยากรที่พบ [logback-test.xml]) มันค่อนข้างสับสนสำหรับการแก้ไขใน logback-test เพื่อซ่อนข้อความสถานะสำหรับสิ่งที่เกิดขึ้นก่อนที่จะถูกวิเคราะห์คำ แต่ขอบคุณสำหรับตัวชี้
Steve B.

5
ฉันคิดว่า Steve B. หมายถึงว่ามันขัดกับความสามารถ (หรืออย่างไม่เป็นทางการ) ที่ Logback ควรระงับข้อความสถานะทั้งหมดรวมถึง (และโดยเฉพาะ) ที่นำหน้าการโหลดไฟล์การกำหนดค่าเว้นแต่จะพบข้อผิดพลาดในภายหลังในการกำหนดค่า เมื่อคุณไม่คุ้นเคยกับกฎนี้และเห็นข้อความสถานะเหล่านี้เป็นครั้งแรก (ซึ่งบ่งบอกถึงคำเตือนการกำหนดค่าหรือข้อผิดพลาด) ผู้ใช้ส่วนใหญ่คาดหวังว่าเมื่อแก้ไขข้อผิดพลาดได้แล้ว Logback จะไม่พิมพ์ข้อความแสดงข้อผิดพลาดที่เกี่ยวข้องอีกต่อไป ข้อความสถานะ
Derek Mahar

6
FWIW ฉันยังพบว่าพฤติกรรมนี้ค่อนข้างสับสน ข้อความระดับ INFO ที่ใช้งานได้ค่อนข้างดีในการซ่อนข้อความ ERROR ที่บอกฉันว่าฉันต้องแก้ไขอะไรจริงๆ การขาด DTD หรือข้อกำหนดอื่น ๆ ของไวยากรณ์ของไฟล์การกำหนดค่าทำให้การทดลองดีบั๊กแม้เมื่อฉันเห็นข้อความ
Tom Anderson

4
@Ceki: ในที่สุดผมก็คิดออก: วิธีที่ 2 จะเรียกข้อความเหล่านี้คือการมีdebug="true"แอตทริบิวต์ในองค์ประกอบของconfiguration logback.xmlกรุณาพูดถึงสิ่งนี้เพื่อประโยชน์ของคนอื่นที่ตกลงไปในหลุมนี้!
Carl Smotricz

6
บางทีก่อนคำสั่ง INFO แรกควรจะมี 'ตรวจพบคำเตือนส่งข้อมูลสถานะที่ผ่านมาทั้งหมด เพื่อหยุดข้อความนี้แก้ไขคำเตือน / ข้อผิดพลาด '
David Roussel

7

Cekiคำตอบที่ถูกต้อง:

(... ) หากคำเตือนหรือข้อผิดพลาดเกิดขึ้นระหว่างการวิเคราะห์ไฟล์การกำหนดค่าการบันทึกจะพิมพ์ข้อมูลสถานะบนคอนโซลโดยอัตโนมัติ

เมื่อคุณทำให้ถูกต้องจะไม่มีมลพิษใด ๆ ในบรรทัดแรกของบันทึกของคุณอีกต่อไป

ตั้งแต่มีนาคม 2015 ในLogback 1.1.2คุณต้องใช้<encoder>องค์ประกอบย่อย - <layout>เลิกใช้แล้วและหากใช้จะมีข้อความแสดงข้อผิดพลาดปรากฏขึ้น คุณไม่สามารถควบคุมสิ่งนี้มันเป็นพฤติกรรมเริ่มต้นของLogback

บางคลาสภายในได้ถูกเปลี่ยนชื่อด้วยและแม้แต่ตัวอย่างในหน้าคู่มือของพวกเขาก็ล้าสมัย!

นี่คือข้อมูลโค้ดจากหน้าช่วยเหลือรหัสข้อผิดพลาดซึ่งมีวิธีที่ถูกต้องในการกำหนดค่าตัวบันทึก ปัญหานี้ได้รับการแก้ไขอย่างสมบูรณ์ในโครงการของฉัน http://logback.qos.ch/codes.html#layoutInsteadOfEncoder

<appender name="FILE" class="ch.qos.logback.core.FileAppender">
  <file>testFile.log</file>
  ...
  <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    <pattern>%msg%n</pattern>
  </encoder>
</appender>

4

ฉันรู้ว่า Steve พบวิธีแก้ไข แต่เขาไม่ได้พูดถึงเรื่องนี้ในเธรด ในกรณีที่บุคคลอื่นที่มีปัญหาเดียวกันนี่คือการแก้ไข

แทนที่องค์ประกอบ"<layout>"ด้วย"<encoder> .. </encoder>"

ผู้ร้ายคือ: <layout class = "ch.qos.logback.classic.PatternLayout">


1
หากคุณต้องการลบข้อความเหล่านั้นอย่างสมบูรณ์ให้ใช้ NopStatusListener ตามที่อธิบายไว้ใน Rasmus วิธีการเข้ารหัส vs โครงร่างไม่ได้ระงับข้อความเช่น 'logback.groovy not found' เป็นต้น ฉันใช้ logback-classic 1.1.3 (มีนาคม 2558)
Cristian Botiza

3

ดิ้นรนกับปัญหาเดียวกันกับตัวเองนั่นคือมีหลายบรรทัดที่ถูกบันทึกไว้ตั้งแต่ต้นซึ่งไม่เกี่ยวข้องกับรหัสของฉัน นี่คือวิธีที่ฉันแก้ไขมัน

<configuration debug="false">

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level 
        %logger{36} - %msg%n</pattern> </encoder> -->
    <encoder>
        <pattern>%d{HH:mm:ss.SSS} %-5level %logger{10} - %msg%n</pattern>
    </encoder>
</appender>

<root level="error">
    <appender-ref ref="STDOUT" />
</root>

<logger name="fun.n.games" level="DEBUG" />

สิ่งนี้กำลังรันด้วยรายการต่อไปนี้ใน pom.xml

        <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>

2

ดูเหมือนว่าจะได้รับการแก้ไขใน 0.9.29 เพิ่งทำการทดสอบหลายครั้ง ไม่มีข้อมูล Joran อีกต่อไป ฉันเดาว่านี่เป็นความมุ่งมั่นที่แก้ไข


2

ฉันมีปัญหาเดียวกันฉันเพิ่มบรรทัดนี้

        <!-- Stop output INFO at start -->
        <statusListener class="ch.qos.logback.core.status.NopStatusListener" />

ในการเข้าสู่ระบบและมันก็ทำงานได้สำเร็จ


วิธีนี้ใช้ได้ผล แต่ก็ป้องกันข้อความ ERROR ด้วยเช่นกัน - จะไม่มีการสร้างเอาต์พุตเมื่อเกิดปัญหาการกำหนดค่าการบันทึกย้อนกลับที่ร้ายแรง
Honza

0

ฉันลองทุกอย่างแล้วก็ไม่มีอะไรทำงานให้ฉันเลย ปัญหาของฉันเกิดจากไฟล์ logback.xml หลายไฟล์ใน classpath ของฉัน นี่เป็นกรณีทั่วไปในโครงการโมดูลาร์หลายตัว เมื่อมีไฟล์ logback.xml เพียงไฟล์เดียวใน classpath จะไม่มีความคลุมเครือและปัญหาจะได้รับการแก้ไข


มันให้อะไรกับคุณ
rogerdpack

0

ใช้logback.groovy:statusListener(NopStatusListener) (ในsrc/test/resources/logback.groovy ) งาน

(กรณีการใช้งานที่ถูกต้องคือหากทำงานกับ ANT ใน Eclipse โดยใช้การบันทึกการทำงานแบบย้อนกลับชั้นเรียน Groovy และการทดสอบหน่วยที่การทดสอบหน่วยใช้src/test/resources/logback.groovyแต่จะเห็นsrc/main/resources/logback.groovy(หรือคล้ายกัน) ที่คุณไม่สามารถแยกออกได้ คลาสพา ธ โครงการ))


0

ฉันชอบที่จะใช้ฟังสถานะเพื่อปิดบันทึก logback ของตัวเอง:

<configuration>
  <statusListener class="ch.qos.logback.core.status.NopStatusListener" />
  ...
</configuration>

แต่ดังที่ได้กล่าวไว้NopStatusListenerยังป้องกันการแสดงคำเตือนและข้อผิดพลาด ดังนั้นคุณสามารถเขียนผู้ฟังสถานะที่กำหนดเองและเปลี่ยนระดับบันทึกได้ด้วยตนเอง:

package com.your.package;

import ch.qos.logback.core.status.OnConsoleStatusListener;
import ch.qos.logback.core.status.Status;

import java.util.List;

public class PrintOnlyWarningLogbackStatusListener extends OnConsoleStatusListener {

    private static final int LOG_LEVEL = Status.WARN;

    @Override
    public void addStatusEvent(Status status) {
        if (status.getLevel() == LOG_LEVEL) {
            super.addStatusEvent(status);
        }
    }

    @Override
    public void start() {
        final List<Status> statuses = context.getStatusManager().getCopyOfStatusList();
        for (Status status : statuses) {
            if (status.getLevel() == LOG_LEVEL) {
                super.start();
            }
        }
    }

}    

จากนั้นใช้ในไฟล์ logback.xml ของคุณ:

<configuration>
  <statusListener class="com.your.package.PrintOnlyWarningLogbackStatusListener" />
  ...
</configuration>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.