¿Cómo puedo deshabilitar el controlador de consola predeterminado, mientras uso la API de registro de Java?

92

Hola, estoy tratando de implementar el registro de Java en mi aplicación. Quiero usar dos controladores. Un administrador de archivos y mi propio administrador de consola. Mis dos controladores funcionan bien. Mi registro se envía a un archivo y a la consola. Mi registro también se envía al controlador de consola predeterminado, que no quiero. Si ejecuta mi código, verá dos líneas adicionales enviadas a la consola. No quiero usar el controlador de consola predeterminado. ¿Alguien sabe cómo deshabilitar el controlador de consola predeterminado? Solo quiero usar los dos controladores que he creado.

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. ??");
    }
}
ruidoso
fuente
1
¿Puedo sugerir suavemente usar en b.append(formatMessage(arg0))lugar de b.append(arg0.getMessage()). Con el formatMessagemétodo está haciendo compatible su formateador con el uso public void log(Level level, String msg, Object param1)y métodos similares.
Victor

Respuestas:

102

El controlador de consola predeterminado está adjunto al registrador raíz, que es padre de todos los demás registradores, incluido el suyo. Entonces veo dos formas de resolver tu problema:

Si esto solo afecta a esta clase particular suya, la solución más simple sería deshabilitar el paso de los registros al registrador principal:

logger.setUseParentHandlers(false);

Si desea cambiar este comportamiento para toda su aplicación, puede eliminar el controlador de consola predeterminado del registrador raíz por completo antes de agregar sus propios controladores:

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

Nota: si también desea utilizar los mismos controladores de registro en otras clases, la mejor manera es mover la configuración del registro a un archivo de configuración a largo plazo.

Péter Török
fuente
2
El método setUseParentHandlers funciona, gracias. ¿Cómo puedo eliminar el controlador de consola predeterminado del registrador raíz?
loudiyimo
10
También puede utilizar Logger.getLogger ("") - esto funciona para mí donde "global" no (¿puede ser el resultado de SLF4J en la mezcla?)
sehugg
2
Si quieres slf4j, te sugiero que uses esto LogManager.getLogManager().reset(); SLF4JBridgeHandler.install();
Somatik
8
"" es el identificador del registrador raíz. "global" es un registrador con nombre (hijo de la raíz) que se crea de forma predeterminada y se utilizará en escenarios de registro simples
Paolo Fulgoni
1
Esta respuesta no funciona para mí, pero el uno por Dominique hace
BullyWiiPlaza
108

Solo haz

LogManager.getLogManager().reset();
Dominique
fuente
1
Gracias, esta es la respuesta correcta. La respuesta marcada como correcta, no funciona.
Andreas L.
1
Esto debería señalar que esto afectará a todos los controladores de cada nombre, Loggerpor lo que podría ser un problema para un sistema de registro más complejo. Esto debe llamarse una vez al comienzo del proceso para asegurarse de que el futuro registrador no se vea afectado. Y, por supuesto, el que necesitará la consola deberá recibir un ConsoleHandlerto by como se esperaba.
AxelH
20

Esto es extraño pero Logger.getLogger("global") no funciona en mi configuración (ni tampoco Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)).

Sin embargo, Logger.getLogger("")hace bien el trabajo.

Espero que esta información también ayude a alguien ...

Moneda de diez centavos
fuente
3
¿Alguien puede decirnos por qué getLogger (Logger.GLOBAL_LOGGER_NAME) no funciona pero getLogger ("") sí?
deinocheirus
2
@deinocheirus vea mi comentario a esta respuesta
Paolo Fulgoni
9

Realice un restablecimiento de la configuración y establezca el nivel raíz en APAGADO

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

Debe indicarle a su registrador que no envíe sus mensajes hasta su registrador principal:

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

Sin embargo, esto debe hacerse antes de agregar más controladores al registrador.

Sólo digo
fuente
Esto funcionó en mi caso, aunque tuve que agregar un controlador manualmente para este registrador.
Sachin Gorade