Como posso desativar o manipulador de console padrão, ao usar a API de registro Java?

92

Oi, estou tentando implementar o log de java em meu aplicativo. Eu quero usar dois manipuladores. Um gerenciador de arquivos e meu próprio gerenciador de console. Ambos os meus manipuladores funcionam bem. Meu registro é enviado para um arquivo e para o console. Meu registro também é enviado para o manipulador de console padrão, que eu não desejo. Se você executar meu código, verá duas linhas extras enviadas para o console. Não quero usar o manipulador de console padrão. Alguém sabe como desabilitar o manipulador de console padrão. Desejo usar apenas os dois manipuladores que criei.

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
fonte
1
Posso sugerir gentilmente para usar em b.append(formatMessage(arg0))vez de b.append(arg0.getMessage()). Com o formatMessagemétodo, você está tornando o formatador compatível com o uso public void log(Level level, String msg, Object param1)e métodos semelhantes.
Victor

Respostas:

102

O manipulador de console padrão é anexado ao logger root, que é pai de todos os outros loggers incluindo o seu. Portanto, vejo duas maneiras de resolver seu problema:

Se isso afetar apenas esta sua classe específica, a solução mais simples seria desativar a passagem dos registros para o registrador pai:

logger.setUseParentHandlers(false);

Se você quiser alterar esse comportamento para todo o seu aplicativo, poderá remover o manipulador de console padrão do logger raiz antes de adicionar seus próprios manipuladores:

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

Nota: se você quiser usar os mesmos manipuladores de log em outras classes também, a melhor maneira é mover a configuração do log para um arquivo de configuração a longo prazo.

Péter Török
fonte
2
O método setUseParentHandlers funciona, obrigado. como posso remover o manipulador de console padrão do logger root?
loudiyimo
10
Você também pode usar Logger.getLogger ("") - isso funciona para mim onde "global" não (pode ser o resultado de SLF4J na combinação?)
sehugg
2
Se você quiser slf4j, eu sugiro que você use isto LogManager.getLogManager().reset(); SLF4JBridgeHandler.install();
Somatik
8
"" é o identificador do logger raiz. "global" é um logger nomeado (filho da raiz) que é criado por padrão e deve ser usado em cenários de log simples
Paolo Fulgoni 01 de
1
Esta resposta não funciona para mim, mas a de Dominique sim
BullyWiiPlaza
108

Apenas faça

LogManager.getLogManager().reset();
Dominique
fonte
1
Obrigado, esta é a resposta certa. A resposta marcada como correta não funciona.
Andreas L.
1
Isso deve indicar que isso afetará todos os manipuladores de todos os nomes, Loggerportanto, pode ser um problema para um sistema de Log mais complexo. Isso deve ser chamado uma vez no início do processo para ter certeza de que o futur logger não será afetado. E, claro, aquele que precisará do console precisará receber um ConsoleHandlerto by conforme o esperado.
AxelH
20

Isso é estranho, mas Logger.getLogger("global") não funciona na minha configuração (bem como Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)).

No entanto, Logger.getLogger("")faz o trabalho bem.

Espero que esta informação também ajude alguém ...

Dime
fonte
3
alguém pode nos dizer por que getLogger (Logger.GLOBAL_LOGGER_NAME) não funciona, mas getLogger ("") funciona?
deinocheirus 01 de
2
@deinocheirus veja meu comentário a esta resposta
Paolo Fulgoni 01 de
9

Faça uma redefinição da configuração e defina o nível raiz para DESLIGADO

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

Você deve instruir seu agente de log para não enviar suas mensagens até o agente de log pai:

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

No entanto, isso deve ser feito antes de adicionar mais manipuladores ao logger.

Apenas dizendo
fonte
Isso funcionou no meu caso, embora eu tivesse que adicionar o manipulador manualmente para este logger.
Sachin Gorade