97

Hi I am trying to implement the java logging in my application. I want to use two handlers. A file handler and my own console handler. Both of my handlers work fine. My logging is send to a file and to the console . My logging is also sent to the default console handler, which i do not want. If you run my code you will see extra two line sent to the console. I don't want to use the default console handler. Does anyone know how to disable the default console handler. I only want to use the two handlers I have created.

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. ??");
    }
}
Grim
  • 1,938
  • 10
  • 56
  • 123
loudiyimo
  • 1,177
  • 2
  • 12
  • 11
  • 1
    Can i gently suggest to use `b.append(formatMessage(arg0))` instead of `b.append(arg0.getMessage())`. With the `formatMessage` method you are making compatible your formatter with the use `public void log(Level level, String msg, Object param1)` and similar methods. – Victor Aug 08 '15 at 19:37

5 Answers5

117

Just do

LogManager.getLogManager().reset();
Dominique
  • 2,019
  • 1
  • 15
  • 5
  • 1
    Thank you, this is the right answer. The answer marked as correct, does not work. – Andreas L. Nov 05 '15 at 10:04
  • 1
    This should point that this will impact every handler for every named `Logger` so this could be a problem for a more complex Log system. This should be call once at the beginning of the process to be sure the futur logger won't be impacted. And of course, the one that will need the console will need to receive a `ConsoleHandler` to by as expected. – AxelH May 05 '17 at 07:28
113

The default console handler is attached to the root logger, which is a parent of all other loggers including yours. So I see two ways to solve your problem:

If this is only affects this particular class of yours, the simplest solution would be to disable passing the logs up to the parent logger:

logger.setUseParentHandlers(false);

If you want to change this behaviour for your whole app, you could remove the default console handler from the root logger altogether before adding your own handlers:

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

Note: if you want to use the same log handlers in other classes too, the best way is to move the log configuration into a config file in the long run.

Andrea Spadaccini
  • 12,378
  • 5
  • 40
  • 54
Péter Török
  • 114,404
  • 31
  • 268
  • 329
  • 2
    setUseParentHandlers method works, thanks. how can i remove the default console handler from the root logger ? – loudiyimo Mar 28 '10 at 14:41
  • @loudiyimo just added the example :-) – Péter Török Mar 28 '10 at 14:42
  • 10
    You could also use Logger.getLogger("") - this works for me where "global" does not (may be the result of SLF4J in the mix?) – sehugg Feb 11 '11 at 05:36
  • 2
    If you want slf4j I suggest you use this `LogManager.getLogManager().reset(); SLF4JBridgeHandler.install();` – Somatik Jul 27 '11 at 14:59
  • LogManager.getLogManager().reset() is better than iterating thru and removing handlers. – daaku Oct 30 '11 at 20:26
  • sehugg, I'm also using SLF4J and on Windows "global" works fine. On MacOS "global" returns null but a blank string "" works. Maybe it's the combination of SLF4J and MacOS. – Sarel Botha Feb 04 '13 at 15:32
  • Using `Logger.getLogger("global");` or `Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);` didn't work for me. I'm using IBM J9 VM (build 2.4, J2RE 1.6.0 IBM J9 2.4). I also think that `LogManager.getLogManager().reset()` is the best answer to this question. In our situation we don't need a workaround, there is a method in JUL API that does exactly what we need. – boumbh Oct 02 '13 at 08:33
  • 9
    "" is the identifier of the root logger. "global" is a named logger (child of root) which is created by default and shall be used in simple logging scenarios – Paolo Fulgoni Apr 01 '14 at 16:26
  • since 1.7 `Logger.getGlobal()` – benez Sep 03 '15 at 13:21
  • 1
    This answer doesn't work for me but the one by Dominique does – BullyWiiPlaza Jan 21 '16 at 10:10
  • Even if this is more verbose to clear the handlers by hand, using the `LogManager` to reset the handlers is risky if we use more than one handler because it will impact every named handlers.. – AxelH May 05 '17 at 07:32
21

This is strange but Logger.getLogger("global") does not work in my setup (as well as Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)).

However Logger.getLogger("") does the job well.

Hope this info also helps somebody...

Dime
  • 2,041
  • 3
  • 23
  • 29
9

Do a reset of the configuration and set the root level to OFF

LogManager.getLogManager().reset();
Logger globalLogger = Logger.getLogger(java.util.logging.Logger.GLOBAL_LOGGER_NAME);
globalLogger.setLevel(java.util.logging.Level.OFF);
Manuel
  • 101
  • 1
  • 1
6

You must instruct your logger not to send its messages on up to its parent logger:

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

However, this should be done before adding any more handlers to logger.

sebnukem
  • 8,143
  • 6
  • 38
  • 48
JustSayin
  • 61
  • 1
  • 2