java.util.logging.Logger doesn't respect java.util.logging.Level?

前端 未结 6 1583
被撕碎了的回忆
被撕碎了的回忆 2020-12-02 18:14

In plain Java SE 6 environment:

Logger l = Logger.getLogger(\"nameless\");
l.setLevel(Level.ALL);
l.fine(\"somemessage\");

Nothing shows up

相关标签:
6条回答
  • 2020-12-02 18:38

    Instead of looping through all handlers and set the logging level, I prefer to set only the level of the console handler:

    //get the top Logger
    Logger topLogger = java.util.logging.Logger.getLogger("");
    
    // Handler for console (reuse it if it already exists)
    Handler consoleHandler = null;
    //see if there is already a console handler
    for (Handler handler : topLogger.getHandlers()) {
        if (handler instanceof ConsoleHandler) {
            //found the console handler
            consoleHandler = handler;
            break;
        }
    }
    
    
    if (consoleHandler == null) {
        //there was no console handler found, create a new one
        consoleHandler = new ConsoleHandler();
        topLogger.addHandler(consoleHandler);
    }
    //set the console handler to fine:
    consoleHandler.setLevel(java.util.logging.Level.FINEST);
    
    0 讨论(0)
  • 2020-12-02 18:49

    Even though the Logger level is set to ALL, the ConsoleHandler (the default Handler on the logger) still has a default level of INFO. This comes from the default logging.properties in JAVA_HOME/jre/lib

    0 讨论(0)
  • 2020-12-02 18:54
    private final static Logger LOGGER = Logger.getLogger(WoTServer.class.getName());
    for(Handler h : LOGGER.getParent().getHandlers()){
        if(h instanceof ConsoleHandler){
            h.setLevel(Level.ALL);
        }
    } 
    
    0 讨论(0)
  • 2020-12-02 19:01

    An indivual at my workplace found the following to work:

    public class Foo {
        private final static Logger logger = Logger.getLogger(Foo.class.getName());
        public static final void main(String[] args) {
            ConsoleHandler ch = new ConsoleHandler();
            ch.setLevel(Level.FINEST);
            Foo.logger.addHandler(ch);
            Foo.logger.setLevel(Level.FINEST);
            Foo.logger.finest("test");
        }
    }
    

    If you just set the root or the handler to finest (exclusively) then it didn't work. When I set both to FINEST then it works. His explanation was:

    Both the logger and its handlers have Log Levels… The order of filtering is Logger then Handlers. That means it checks to see if the log message passes the loggers filter first, then sends the message on to the individual handlers for filtering.

    He further explained it using the following examples:

    • Logger myLogger has a level of FINEST and a single ConsoleHandler myHandler which has a level of INFO

    • myLogger.fine("foo") à message makes it past the logger’s filter, but gets stopper by the handler’s filter… Nothing output.

    • myLogger.info("foo") à passes both filters and foo is output.

    Now…

    • Logger myLogger has a level of INFO and a single ConsoleHandler myHandler which has a level of FINEST

    • myLogger.fine("foo") à message gets stopped by the logger’s filter and never makes it to the handler... Nothing output.

    • myLogger.info("foo") à passes both filters and foo is output.

    Now…

    • Logger myLogger has a level of FINEST and a single ConsoleHandler myHandler which has a level of FINEST

    • myLogger.fine("foo") à passes both filters and "foo" is output.

    • myLogger.info("foo") à passes both filters and foo is output.

    0 讨论(0)
  • 2020-12-02 19:01

    Other users have already given good answer why it happened (ConsoleHandler has a separate level variable). I reuse my application logger's level and copy it up to the parent hiearchy. Also provides easy way to refresh levels at runtime anytime I want.

    // Set same level all loggers and handlers up to the parent level
    // OFF,SEVERE,WARNING,INFO,CONFIG,FINE,FINER,FINEST,ALL
    Logger logger = Logger.getLogger(this.getClass().getPackage().getName());
    //Level level = Level.parse("FINEST");
    Level level = logger.getLevel();
    Logger tempLogger = logger;
    while(tempLogger != null) {
       tempLogger.setLevel(level);
       for(Handler handler : tempLogger.getHandlers())
          handler.setLevel(level);
       tempLogger = tempLogger.getParent();
    }
    
    0 讨论(0)
  • 2020-12-02 19:01

    You need to set the log level on both the handlers in the logger, and the logger itself. Logging is only performed at the "coarsest" of the two levels. Here is a logging class that does the job.

    import java.io.PrintWriter;
    import java.io.StringWriter;
    import java.time.Instant;
    import java.time.ZoneId;
    import java.time.ZonedDateTime;
    import java.time.format.DateTimeFormatter;
    import java.util.logging.ConsoleHandler;
    import java.util.logging.Formatter;
    import java.util.logging.Handler;
    import java.util.logging.Level;
    import java.util.logging.LogRecord;
    import java.util.logging.Logger;
    
    public class Log {
    
        private static final Logger logger = Logger.getGlobal();
    
        private static Level logLevel = Level.INFO;
        static {
            // Remove all the default handlers (usually just one console handler)
            Logger rootLogger = Logger.getLogger("");
            Handler[] rootHandlers = rootLogger.getHandlers();
            for (Handler handler : rootHandlers) {
                rootLogger.removeHandler(handler);
            }
    
            // Add our own handler
            ConsoleHandler handler = new ConsoleHandler();
            handler.setLevel(logLevel);
            handler.setFormatter(new LogFormatter());
            logger.addHandler(handler);
            logger.setLevel(logLevel);
        }
    
        public static class LogFormatter extends Formatter {
            @Override
            public String format(LogRecord record) {
                String stackTrace = "";
                Throwable thrown = record.getThrown();
                if (thrown != null) {
                    StringWriter stacktraceWriter = new StringWriter();
                    try (PrintWriter writer = new PrintWriter(stacktraceWriter)) {
                        thrown.printStackTrace(writer);
                    }
                    stackTrace = stacktraceWriter.toString();
                }
                return ZonedDateTime.ofInstant(Instant.ofEpochMilli(record.getMillis()), ZoneId.of("UTC")).format(DateTimeFormatter.ISO_ZONED_DATE_TIME) + "\t" + record.getLevel()
                        + "\t" + record.getMessage() + "\n" + stackTrace;
            }
        }
    
        private static final String classname = Log.class.getName();
    
        private static String callerRef() {
            StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
            if (stackTraceElements.length < 4) {
                return "";
            } else {
                int i = 1;
                for (; i < stackTraceElements.length; i++) {
                    if (stackTraceElements[i].getClassName().equals(classname)) {
                        break;
                    }
                }
                for (; i < stackTraceElements.length; i++) {
                    if (!stackTraceElements[i].getClassName().equals(classname)) {
                        break;
                    }
                }
                if (i < stackTraceElements.length) {
                    return stackTraceElements[i].toString();
                } else {
                    return "[in unknown method]";
                }
            }
        }
    
        public static void setLogLevel(Level newLogLevel) {
            logLevel = newLogLevel;
            for (Handler handler : logger.getHandlers()) {
                handler.setLevel(newLogLevel);
            }
            Log.logger.setLevel(newLogLevel);
        }
    
        public static int getLevelNum() {
            return logLevel.intValue();
        }
    
        public static int getLevelNum(Level level) {
            return level.intValue();
        }
    
        public static void fine(String msg) {
            logger.log(Level.FINE, msg);
        }
    
        public static void info(String msg) {
            logger.log(Level.INFO, msg);
        }
    
        public static void warning(String msg) {
            logger.log(Level.WARNING, msg + "\t " + callerRef());
        }
    
        public static void error(String msg) {
            logger.log(Level.SEVERE, msg + "\t " + callerRef());
        }
    
        public static void exception(String msg, Throwable cause) {
            logger.log(Level.SEVERE, msg + "\t " + callerRef(), cause);
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题