Як я можу вимкнути обробник консолі за замовчуванням, використовуючи API реєстрації Java?


92

Привіт, я намагаюся реалізувати реєстрацію Java у своєму додатку. Я хочу використовувати два обробники. Обробник файлів та мій власний обробник консолі. Обидва мої обробники працюють нормально. Моя реєстрація надсилається у файл та на консоль. Мій журнал також надсилається до обробника консолі за замовчуванням, чого я не хочу. Якщо ви запустите мій код, ви побачите додаткові два рядки, надіслані на консоль. Я не хочу використовувати обробник консолі за замовчуванням. Хтось знає, як відключити обробник консолі за замовчуванням. Я хочу використовувати лише два обробники, які я створив.

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. ??");
    }
}

1
Чи можу я обережно запропонувати використовувати b.append(formatMessage(arg0))замість b.append(arg0.getMessage()). За допомогою formatMessageметоду, який ви робите сумісним для форматування з використанням public void log(Level level, String msg, Object param1)та подібними методами.
Віктор

Відповіді:


102

Обробник консолі за замовчуванням приєднаний до кореневого реєстратора, який є батьківським для всіх інших реєстраторів, включаючи ваш. Тож я бачу два шляхи вирішення вашої проблеми:

Якщо це стосується лише цього конкретного класу, найпростішим рішенням було б відключити передачу журналів батьківському реєстратору:

logger.setUseParentHandlers(false);

Якщо ви хочете змінити цю поведінку для всього свого додатка, ви можете видалити консольний обробник за замовчуванням із кореневого журналу перед додаванням власних обробників:

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

Примітка: якщо ви хочете використовувати однакові обробники журналів і в інших класах, найкращий спосіб - це перемістити конфігурацію журналу у файл конфігурації в довгостроковій перспективі.


2
Метод setUseParentHandlers працює, дякую. як я можу видалити обробник консолі за замовчуванням з кореневого журналу?
loudiyimo

10
Ви також можете використовувати Logger.getLogger ("") - це працює для мене там, де "глобальний" ні (може бути результатом SLF4J у суміші?)
sehugg

2
Якщо ви хочете slf4j, пропоную скористатися цим LogManager.getLogManager().reset(); SLF4JBridgeHandler.install();
Somatik

8
"" - це ідентифікатор кореневого реєстратора. "глобальний" - це іменований реєстратор (дочірній каталог кореня), який створюється за замовчуванням і застосовуватиметься у простих сценаріях ведення журналу
Паоло Фулгоні,

1
Ця відповідь не працює для мене, але відповідь Домініка
BullyWiiPlaza

108

Просто зробіть

LogManager.getLogManager().reset();

1
Дякую, це правильна відповідь. Відповідь, позначена як правильна, не працює.
Андреас Л.

1
Це повинно означати, що це вплине на кожного обробника для кожного іменованого, Loggerтому це може бути проблемою для більш складної системи журналу. Це слід викликати один раз на початку процесу, щоб переконатися, що реєстратор futur не вплине. І звичайно, той, кому знадобиться консоль, повинен отримати ConsoleHandler, як очікувалося.
AxelH

20

Це дивно, але Logger.getLogger("global") не працює в моїй установці (як і Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)).

Однак Logger.getLogger("")робить роботу добре.

Сподіваюся, ця інформація також комусь допомагає ...


3
хтось може сказати нам, чому getLogger (Logger.GLOBAL_LOGGER_NAME) не працює, але getLogger ("") працює?
deinocheirus

2
@deinocheirus див. мій коментар до цієї відповіді
Паоло Фульгоні,

9

Виконайте скидання конфігурації та встановіть для кореневого рівня значення OFF

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

5

Ви повинні доручити своєму реєстратору не надсилати повідомлення до батьківського реєстратора:

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

Однак це слід зробити перед додаванням будь-яких обробників до реєстратора.


У моєму випадку це спрацювало, хоча мені довелося додати обробник вручну для цього реєстратора.
Sachin Gorade
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.