Bagaimana mencegah logback dari mengeluarkan statusnya sendiri di awal setiap log?


145

Ini sepertinya kesalahan kelalaian, tetapi sepertinya saya tidak dapat menemukan penyebabnya. Logging dengan logback / slf4j (versi terbaru slf4j-api-1.6.1, logback core / classic 0.9.24). Konfigurasi log paling sederhana untuk pengujian adalah:

<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>

Setiap pengaturan log dimulai dengan jalur status internal 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]

yang, menurut dokumen, format logback digunakan untuk default. Kemudian selesai membaca konfigurasi (yang diatur untuk menghasilkan format yang berbeda) dan melanjutkan dengan output yang diformat dengan benar. Ada parameter konfigurasi <configuration debug="false">yang tidak memengaruhi ini.

Adakah yang tahu cara mematikan ini?


Versi terbaru dari logback jauh lebih cepat dalam menghitung% L.
Thorbjørn Ravn Andersen

@ ThorbjørnRavnAndersen dokumen mengatakan "L / line: Menghasilkan informasi nomor baris tidak terlalu cepat. Dengan demikian, penggunaannya harus dihindari kecuali kecepatan eksekusi tidak menjadi masalah." FWIW: logback.qos.ch/manual/layouts.html (jadi mungkin lebih cepat tapi masih tidak super cepat atau semacamnya ...)
rogerdpack

@rogerdpack ya. Ini ditemukan dengan menganalisis jejak stack pengecualian. Itu menjadi lebih cepat.
Thorbjørn Ravn Andersen

Jawaban:


249

Jika Anda mengatur debugatribut configurationelemen ke true, Anda akan mendapatkan semua informasi status ke konsol. Jika ini masalah Anda, cukup setel ke false atau hapus.

Jika Anda memiliki masalah konfigurasi level WARNatau di atas, Anda juga akan mendapatkan semua informasi status dicatat ke konsol (termasuk pesan level INFO). Solusi terbaik untuk masalah ini adalah memperbaiki masalah (dalam kasus Anda ganti <layout>elemen dengan <encoder>elemen).

Jika Anda karena suatu alasan tidak dapat memperbaiki masalah, tetapi ingin menghapus status-informasi dari konsol, Anda dapat mengkonfigurasi alternatif StatusListener. Gunakan NopStatusListeneruntuk sepenuhnya menghapus informasi status:

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

9
Ini adalah jawaban yang tepat, harus lebih ditingkatkan, terima kasih. (logback 1.0.11)
Jakub Kulhan

3
Ini berhasil. Saya tidak sepenuhnya jelas bahwa INFOpesan-pesan log akan hilang juga, tetapi kenyataannya memang demikian. Saya tahu jawabannya mengatakan ini, tetapi untuk beberapa alasan tidak jelas bagi saya. Agar sangat jelas: perbaiki masalah enkoder / tata letak dan pesan peringatan tidak hanya akan hilang, tetapi pesan info juga akan hilang, meskipun tidak terkait dengan masalah tersebut.
Jason

3
Tidak bekerja dengan atribut debug, tetapi bekerja dengan sempurna dengan pendengar status.
Ameba Spugnosa

Terima kasih - diperlukan pendengar status.
Yehezkiel Victor

2
Hati-hati menggunakan pendekatan ini, tampaknya berhasil tetapi menyembunyikan fakta bahwa Anda memiliki kesalahan konfigurasi dalam file Anda. Masalah sebenarnya adalah PERINGATAN log, masalah ini harus diperbaiki di konfigurasi, maka semua log inc. INFO pergi.
teknopaul

45

Seperti dijelaskan dalam dokumen , jika peringatan atau kesalahan terjadi selama parsing file konfigurasi, logback akan secara otomatis mencetak data status pada konsol.

Mengikuti http://logback.qos.ch/codes.html#layoutInsteadOfEncoder yaitu tautan yang disebutkan oleh logback dalam pesan peringatannya. Setelah Anda mengikuti langkah-langkah yang disebutkan di dalamnya, yaitu, jika Anda mengganti elemen <layout> dengan <encoder>, logback akan berhenti mencetak pesan di konsol.


4
Agak benar, meskipun Anda memang mengarahkan saya ke arah yang benar. Saya telah berubah menjadi sintaks encoder tanpa efek, meskipun ternyata menghapus baris lain di logback.xml yang menyebabkan peringatan melakukan trik. Hal yang menipu tentang hal itu adalah bahwa output tersebut tampaknya menghasilkan keputusan yang dibuat sebelum benar-benar mem-parsing file logback Anda, (1> TIDAK dapat menemukan sumber daya [logback.groovy], 2> Sumber daya yang ditemukan [logback-test.xml]). Ini cukup membingungkan untuk perbaikan dalam tes logback untuk menyembunyikan pesan status untuk apa yang terjadi sebelum diuraikan. Tapi terima kasih untuk penunjuknya.
Steve B.

5
Saya pikir apa yang dimaksud Steve B. adalah bahwa itu berlawanan dengan intuisi (atau setidaknya tidak konvensional) bahwa Logback harus menekan semua pesan status, termasuk (dan khususnya) yang mendahului pemuatan file konfigurasi, kecuali jika ia menemukan kesalahan kemudian dalam konfigurasi. Ketika Anda tidak terbiasa dengan aturan ini dan pertama kali melihat pesan status ini (yang menyiratkan peringatan konfigurasi atau kesalahan), sebagian besar pengguna akan berharap bahwa setelah kesalahan diselesaikan, Logback tidak lagi akan mencetak pesan kesalahan terkait, tetapi terus cetak yang lain pesan status.
Derek Mahar

6
FWIW, saya juga menemukan perilaku yang cukup membingungkan ini. Tumpukan pesan tingkat INFO melakukan pekerjaan yang cukup baik menyembunyikan pesan ERROR yang memberi tahu saya apa yang sebenarnya perlu saya perbaiki. Kurangnya DTD, atau spesifikasi lain dari sintaks dari file konfigurasi, membuatnya cukup percobaan untuk debug bahkan setelah saya melihat pesan.
Tom Anderson

4
@ Ceki: Saya akhirnya menemukan jawabannya: Cara ke-2 untuk memicu pesan-pesan ini adalah dengan memiliki debug="true"atribut dalam configurationelemen logback.xml. Tolong sebutkan ini untuk kepentingan orang lain yang jatuh ke dalam lubang ini!
Carl Smotricz

6
Mungkin sebelum pernyataan INFO pertama harus ada 'Peringatan terdeteksi, mengeluarkan semua info status masa lalu. Untuk menghentikan pesan ini, perbaiki peringatan / kesalahan Anda '
David Roussel

7

Jawaban ceki benar:

(...) jika peringatan atau kesalahan terjadi selama parsing file konfigurasi, logback akan secara otomatis mencetak data status pada konsol.

Setelah Anda melakukannya dengan benar, tidak akan ada lagi polusi di baris pertama log Anda.

Pada Maret 2015, di Logback 1.1.2 , Anda perlu menggunakan <encoder>sub-komponen - <layout>sekarang tidak digunakan lagi dan jika menggunakannya, pesan kesalahan akan muncul. Anda tidak dapat mengontrol ini, itu perilaku default Logback .

Beberapa kelas internal telah diganti namanya juga, dan bahkan contoh-contoh di halaman manualnya sudah usang!

Berikut ini cuplikan kode dari halaman Bantuan Kode Kesalahan mereka , yang memiliki cara yang benar untuk mengonfigurasi logger. Ini memperbaiki masalah sepenuhnya dalam proyek saya. 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

Saya menyadari Steve menemukan perbaikannya tetapi dia tidak menyebutkannya di utasnya. Jika ada orang lain yang mengalami masalah yang sama di sini adalah perbaikannya.

Ganti elemen "<layout>" dengan "<encoder> .. </encoder>"

Penyebabnya adalah: <layout class = "ch.qos.logback.classic.PatternLayout">


1
Jika Anda ingin menghapus semua pesan itu, gunakan NopStatusListener seperti yang dijelaskan Rasmus. Pendekatan encoder vs tata letak tidak menekan pesan seperti 'logback.groovy not found' misalnya. Saya menggunakan logback-classic 1.1.3 (Maret 2015)
Cristian Botiza

3

Berjuang dengan masalah yang sama sendiri yaitu ada banyak baris login tepat di awal yang tidak terkait dengan kode saya. Inilah cara saya memperbaikinya.

<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" />

Ini berjalan dengan entri berikut di pom.xml

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

2

Ini sepertinya diperbaiki di 0.9.29. Baru saja membuat beberapa tes. Tidak ada INFO Joran lagi. Saya kira ini adalah komitmen perbaikan.


2

Saya memiliki masalah yang sama saya menambahkan baris ini

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

di logback dan berhasil


Ini berfungsi, namun itu mencegah output pesan ERROR juga - tidak ada output yang dihasilkan ketika masalah konfigurasi logback serius terjadi.
Honza

0

Saya sudah mencoba segalanya dan tidak ada yang berhasil untuk saya. Masalah saya adalah karena beberapa file logback.xml di classpath saya. Ini adalah kasus umum dalam proyek multi modular. Ketika hanya ada satu file logback.xml di classpath, tidak ada ambiguitas dan masalahnya terpecahkan.


apa hasil yang Anda berikan?
rogerdpack

0

Menggunakan logback.groovy:statusListener(NopStatusListener) (disrc/test/resources/logback.groovy ) berfungsi.

(Kasus penggunaan yang valid adalah misalnya jika bekerja dengan ANT di Eclipse, menggunakan logback logging, kelas groovy dan tes unit di mana tes unit mengambil src/test/resources/logback.groovy, tetapi juga akan melihat src/main/resources/logback.groovy(atau serupa) Anda tidak dapat mengecualikan (jika classpath ANT dikatakan menggunakan proyek classpath).)


0

Saya lebih suka menggunakan pendengar status untuk mematikan log logback sendiri:

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

Tetapi seperti yang disebutkan NopStatusListener juga mencegah menampilkan peringatan dan kesalahan. Jadi Anda dapat menulis pendengar status khusus Anda dan mengubah level log untuk itu secara manual:

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();
            }
        }
    }

}    

Kemudian gunakan dalam file logback.xml Anda:

<configuration>
  <statusListener class="com.your.package.PrintOnlyWarningLogbackStatusListener" />
  ...
</configuration>
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.