Bagaimana cara menonaktifkan penangan konsol default, saat menggunakan java logging API?

93

Hai Saya mencoba menerapkan java logging di aplikasi saya. Saya ingin menggunakan dua penangan. Seorang penangan file dan pengendali konsol saya sendiri. Kedua penangan saya bekerja dengan baik. Logging saya dikirim ke file dan ke konsol. Logging saya juga dikirim ke penangan konsol default, yang tidak saya inginkan. Jika Anda menjalankan kode saya, Anda akan melihat dua baris tambahan dikirim ke konsol. Saya tidak ingin menggunakan penangan konsol default. Apakah ada yang tahu cara menonaktifkan pengendali konsol default. Saya hanya ingin menggunakan dua penangan yang telah saya buat.

Handler fh = new FileHandler("test.txt");
fh.setFormatter(formatter);
logger.addHandler(fh);

Handler ch = new ConsoleHandler();
ch.setFormatter(formatter);
logger.addHandler(ch);

import java.util.Date;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

public class LoggingExample {
    private static Logger logger = Logger.getLogger("test");

    static {
        try {
            logger.setLevel(Level.INFO);

            Formatter formatter = new Formatter() {

                @Override
                public String format(LogRecord arg0) {
                    StringBuilder b = new StringBuilder();
                    b.append(new Date());
                    b.append(" ");
                    b.append(arg0.getSourceClassName());
                    b.append(" ");
                    b.append(arg0.getSourceMethodName());
                    b.append(" ");
                    b.append(arg0.getLevel());
                    b.append(" ");
                    b.append(arg0.getMessage());
                    b.append(System.getProperty("line.separator"));
                    return b.toString();
                }

            };

            Handler fh = new FileHandler("test.txt");
            fh.setFormatter(formatter);
            logger.addHandler(fh);

            Handler ch = new ConsoleHandler();
            ch.setFormatter(formatter);
            logger.addHandler(ch);

            LogManager lm = LogManager.getLogManager();
            lm.addLogger(logger);
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        logger.info("why does my test application use the standard console logger ?\n" + " I want only my console handler (Handler ch)\n " + "how can i turn the standard logger to the console off. ??");
    }
}
loudiyimo
sumber
1
Dapatkah saya dengan lembut menyarankan untuk menggunakan b.append(formatMessage(arg0))sebagai pengganti b.append(arg0.getMessage()). Dengan formatMessagemetode Anda membuat formatter Anda kompatibel dengan penggunaan public void log(Level level, String msg, Object param1)dan metode serupa.
Victor

Jawaban:

102

Penangan konsol default dipasang ke root logger, yang merupakan induk dari semua logger lain termasuk milik Anda. Jadi saya melihat dua cara untuk menyelesaikan masalah Anda:

Jika ini hanya memengaruhi kelas khusus Anda ini, solusi paling sederhana adalah menonaktifkan meneruskan log ke logger induk:

logger.setUseParentHandlers(false);

Jika Anda ingin mengubah perilaku ini untuk seluruh aplikasi Anda, Anda dapat menghapus penangan konsol default dari pencatat akar sama sekali sebelum menambahkan penangan Anda sendiri:

Logger globalLogger = Logger.getLogger("global");
Handler[] handlers = globalLogger.getHandlers();
for(Handler handler : handlers) {
    globalLogger.removeHandler(handler);
}

Catatan: jika Anda juga ingin menggunakan penangan log yang sama di kelas lain, cara terbaik adalah dengan memindahkan konfigurasi log ke file konfigurasi dalam jangka panjang.

Péter Török
sumber
2
Metode setUseParentHandlers berfungsi, terima kasih. bagaimana cara menghapus pengendali konsol default dari logger root?
loudiyimo
10
Anda juga dapat menggunakan Logger.getLogger ("") - ini berfungsi untuk saya di mana "global" tidak (mungkin hasil dari SLF4J dalam campuran?)
sehugg
2
Jika Anda ingin slf4j saya sarankan Anda menggunakan ini LogManager.getLogManager().reset(); SLF4JBridgeHandler.install();
Somatik
8
"" adalah pengenal dari logger root. "global" adalah logger bernama (
turunan
1
Jawaban ini tidak berhasil untuk saya tetapi yang oleh Dominique berhasil
BullyWiiPlaza
109

Lakukan saja

LogManager.getLogManager().reset();
Dominique
sumber
1
Terima kasih, ini jawaban yang benar. Jawaban yang ditandai sebagai benar, tidak berfungsi.
Andreas L.
1
Ini harus menunjukkan bahwa ini akan berdampak pada setiap penangan untuk setiap nama Loggersehingga ini bisa menjadi masalah untuk sistem Log yang lebih kompleks. Ini harus dipanggil satu kali pada awal proses untuk memastikan logger masa depan tidak akan terpengaruh. Dan tentu saja, orang yang membutuhkan konsol harus menerima ConsoleHandlerseperti yang diharapkan.
AxelH
20

Ini aneh tetapi Logger.getLogger("global") tidak berfungsi di pengaturan saya (jugaLogger.getLogger(Logger.GLOBAL_LOGGER_NAME) ).

Namun Logger.getLogger("") melakukan pekerjaan dengan baik.

Semoga info ini juga membantu seseorang ...

Ketip
sumber
3
dapatkah seseorang memberi tahu kami mengapa getLogger (Logger.GLOBAL_LOGGER_NAME) tidak berfungsi tetapi getLogger ("") berfungsi?
deinocheirus
2
@deinocheirus lihat komentar saya untuk jawaban
Paolo Fulgoni
9

Lakukan reset konfigurasi dan setel level root ke OFF

LogManager.getLogManager().reset();
Logger globalLogger = Logger.getLogger(java.util.logging.Logger.GLOBAL_LOGGER_NAME);
globalLogger.setLevel(java.util.logging.Level.OFF);
Manuel
sumber
5

Anda harus menginstruksikan logger Anda untuk tidak mengirim pesannya ke logger induknya:

...
import java.util.logging.*;
...
Logger logger = Logger.getLogger(this.getClass().getName());
logger.setUseParentHandlers(false);
...

Namun, ini harus dilakukan sebelum menambahkan handler lagi ke logger.

JustSayin
sumber
Ini berhasil dalam kasus saya, meskipun saya harus menambahkan handler secara manual untuk logger ini.
Sachin Gorade