Jak mogę wyłączyć domyślną procedurę obsługi konsoli podczas korzystania z interfejsu API logowania w języku Java?

93

Cześć, próbuję zaimplementować logowanie java w mojej aplikacji. Chcę użyć dwóch programów obsługi. Program obsługi plików i mój własny program obsługi konsoli. Obaj moi handlowcy działają dobrze. Moje logowanie jest wysyłane do pliku i do konsoli. Moje logowanie jest również wysyłane do domyślnego programu obsługi konsoli, czego nie chcę. Jeśli uruchomisz mój kod, zobaczysz dodatkowe dwie linie wysłane do konsoli. Nie chcę używać domyślnej obsługi konsoli. Czy ktoś wie, jak wyłączyć domyślną obsługę konsoli. Chcę używać tylko dwóch utworzonych przeze mnie programów obsługi.

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
źródło
1
Czy mogę delikatnie zasugerować użycie b.append(formatMessage(arg0))zamiast b.append(arg0.getMessage()). Za pomocą formatMessagemetody, którą dostosowujesz formater do public void log(Level level, String msg, Object param1)metod używanych i podobnych.
Victor

Odpowiedzi:

102

Domyślna procedura obsługi konsoli jest dołączona do głównego programu rejestrującego, który jest rodzicem wszystkich innych programów rejestrujących, w tym Twojego. Widzę więc dwa sposoby rozwiązania problemu:

Jeśli dotyczy to tylko tej konkretnej klasy, najprostszym rozwiązaniem byłoby wyłączenie przekazywania dzienników do nadrzędnego rejestratora:

logger.setUseParentHandlers(false);

Jeśli chcesz zmienić to zachowanie dla całej aplikacji, możesz całkowicie usunąć domyślną obsługę konsoli z głównego programu rejestrującego przed dodaniem własnych programów obsługi:

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

Uwaga: jeśli chcesz używać tych samych programów obsługi dziennika również w innych klasach, najlepszym sposobem jest przeniesienie konfiguracji dziennika do pliku konfiguracyjnego na dłuższą metę.

Péter Török
źródło
2
Metoda setUseParentHandlers działa, dzięki. jak mogę usunąć domyślną obsługę konsoli z głównego programu rejestrującego?
loudiyimo
10
Możesz także użyć Logger.getLogger ("") - to działa dla mnie, gdzie "global" nie działa (może być wynikiem SLF4J w miksie?)
sehugg
2
Jeśli chcesz slf4j, proponuję użyć tego LogManager.getLogManager().reset(); SLF4JBridgeHandler.install();
Somatik
8
„” jest identyfikatorem głównego programu rejestrującego. „global” to nazwany rejestrator (dziecko roota), który jest tworzony domyślnie i powinien być używany w prostych scenariuszach logowania
Paolo Fulgoni
1
Ta odpowiedź nie działa dla mnie, ale ta autorstwa Dominique tak
BullyWiiPlaza
109

Po prostu zrób

LogManager.getLogManager().reset();
Dominique
źródło
1
Dziękuję, to jest właściwa odpowiedź. Odpowiedź oznaczona jako poprawna nie działa.
Andreas L.
1
Powinno to wskazywać, że wpłynie to na każdą procedurę obsługi dla każdej nazwanej, Loggerwięc może to być problem dla bardziej złożonego systemu dziennika. Należy to wywołać raz na początku procesu, aby mieć pewność, że nie wpłynie to na futur logger. I oczywiście ten, który będzie potrzebował konsoli, będzie musiał otrzymać to ConsoleHandler, zgodnie z oczekiwaniami.
AxelH
20

Jest to dziwne, ale Logger.getLogger("global") nie działa w mojej konfiguracji (a także Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)).

Jednak Logger.getLogger("")działa dobrze.

Mam nadzieję, że te informacje również komuś pomogą ...

Moneta dziesięciocentowa
źródło
3
Czy ktoś może nam powiedzieć, dlaczego getLogger (Logger.GLOBAL_LOGGER_NAME) nie działa, a getLogger („”) działa?
deinocheirus
2
@deinocheirus zobacz mój komentarz do tej odpowiedzi
Paolo Fulgoni
9

Zresetuj konfigurację i ustaw poziom główny na WYŁ

LogManager.getLogManager().reset();
Logger globalLogger = Logger.getLogger(java.util.logging.Logger.GLOBAL_LOGGER_NAME);
globalLogger.setLevel(java.util.logging.Level.OFF);
Manuel
źródło
5

Musisz poinstruować swój rejestrator, aby nie wysyłał swoich komunikatów do swojego nadrzędnego rejestratora:

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

Należy to jednak zrobić przed dodaniem kolejnych programów obsługi do rejestratora.

Tylko mówię
źródło
To zadziałało w moim przypadku, chociaż musiałem ręcznie dodać program obsługi dla tego rejestratora.
Sachin Gorade