Comment puis-je désactiver le gestionnaire de console par défaut tout en utilisant l'API de journalisation Java?

92

Salut, j'essaye d'implémenter la journalisation java dans mon application. Je veux utiliser deux gestionnaires. Un gestionnaire de fichiers et mon propre gestionnaire de console. Mes deux gestionnaires fonctionnent bien. Ma journalisation est envoyée vers un fichier et vers la console. Ma journalisation est également envoyée au gestionnaire de console par défaut, ce que je ne veux pas. Si vous exécutez mon code, vous verrez deux lignes supplémentaires envoyées à la console. Je ne veux pas utiliser le gestionnaire de console par défaut. Quelqu'un sait-il comment désactiver le gestionnaire de console par défaut. Je souhaite uniquement utiliser les deux gestionnaires que j'ai créés.

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
la source
1
Puis-je doucement suggérer d'utiliser à la b.append(formatMessage(arg0))place de b.append(arg0.getMessage()). Avec la formatMessageméthode, vous rendez compatible votre formateur avec l'utilisation public void log(Level level, String msg, Object param1)et des méthodes similaires.
Victor

Réponses:

102

Le gestionnaire de console par défaut est attaché à l'enregistreur racine, qui est un parent de tous les autres enregistreurs, y compris le vôtre. Je vois donc deux façons de résoudre votre problème:

Si cela n'affecte que votre classe particulière, la solution la plus simple serait de désactiver la transmission des journaux à l'enregistreur parent:

logger.setUseParentHandlers(false);

Si vous souhaitez modifier ce comportement pour l'ensemble de votre application, vous pouvez supprimer complètement le gestionnaire de console par défaut de l'enregistreur racine avant d'ajouter vos propres gestionnaires:

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

Remarque: si vous souhaitez utiliser les mêmes gestionnaires de journaux dans d'autres classes également, le meilleur moyen est de déplacer la configuration du journal dans un fichier de configuration à long terme.

Péter Török
la source
2
La méthode setUseParentHandlers fonctionne, merci. comment puis-je supprimer le gestionnaire de console par défaut de l'enregistreur racine?
loudiyimo
10
Vous pouvez également utiliser Logger.getLogger ("") - cela fonctionne pour moi là où "global" ne fonctionne pas (peut-être le résultat de SLF4J dans le mix?)
sehugg
2
Si vous voulez slf4j, je vous suggère de l'utiliser LogManager.getLogManager().reset(); SLF4JBridgeHandler.install();
Somatik
8
"" est l'identifiant de l'enregistreur racine. "global" est un enregistreur nommé (enfant de root) qui est créé par défaut et doit être utilisé dans des scénarios de journalisation simples
Paolo Fulgoni
1
Cette réponse ne fonctionne pas pour moi mais celle de Dominique fonctionne
BullyWiiPlaza
108

Fais juste

LogManager.getLogManager().reset();
Dominique
la source
1
Merci, c'est la bonne réponse. La réponse marquée comme correcte ne fonctionne pas.
Andreas L.
1
Cela devrait indiquer que cela aura un impact sur chaque gestionnaire pour chaque nommé, Loggerdonc cela pourrait être un problème pour un système de journal plus complexe. Cela devrait être appelé une fois au début du processus pour être sûr que le futur enregistreur ne sera pas affecté. Et bien sûr, celui qui aura besoin de la console devra recevoir un ConsoleHandlerto by comme prévu.
AxelH
20

Ceci est étrange mais Logger.getLogger("global") ne fonctionne pas dans ma configuration (ainsi que Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)).

Cependant Logger.getLogger("")fait bien le travail.

J'espère que cette information aide également quelqu'un ...

Dîme
la source
3
quelqu'un peut-il nous dire pourquoi getLogger (Logger.GLOBAL_LOGGER_NAME) ne fonctionne pas mais getLogger ("") fonctionne-t-il?
deinocheirus
2
@deinocheirus voir mon commentaire sur cette réponse
Paolo Fulgoni
9

Réinitialisez la configuration et réglez le niveau racine sur OFF

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

Vous devez demander à votre enregistreur de ne pas envoyer ses messages jusqu'à son enregistreur parent:

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

Cependant, cela doit être fait avant d'ajouter d'autres gestionnaires à l'enregistreur.

JustSayin
la source
Cela a fonctionné dans mon cas, même si j'ai dû ajouter un gestionnaire manuellement pour cet enregistreur.
Sachin Gorade