[ACCEPTED]-java.util.logging.Logger doesn't respect java.util.logging.Level?-logging
Even though the Logger level is set to ALL, the 4 ConsoleHandler (the default Handler on the 3 logger) still has a default level of INFO. This 2 comes from the default logging.properties 1 in JAVA_HOME/jre/lib
Instead of looping through all handlers 2 and set the logging level, I prefer to set 1 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);
An indivual at my workplace found the following 22 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 21 handler to finest (exclusively) then it 20 didn't work. When I set both to FINEST
then it 19 works. His explanation was:
Both the logger 18 and its handlers have Log Levels… The order 17 of filtering is Logger then Handlers. That 16 means it checks to see if the log message 15 passes the loggers filter first, then sends 14 the message on to the individual handlers 13 for filtering.
He further explained it using 12 the following examples:
Logger myLogger
has a level ofFINEST
and 11 a singleConsoleHandler myHandler
which has a level ofINFO
myLogger.fine("foo")
à message 10 makes it past the logger’s filter, but gets 9 stopper by the handler’s filter… Nothing 8 output.myLogger.info("foo")
à passes both filters andfoo
is output.
Now…
Logger myLogger
has 7 a level ofINFO
and a singleConsoleHandler myHandler
which has a level 6 ofFINEST
myLogger.fine("foo")
à message gets stopped by the logger’s 5 filter and never makes it to the handler... Nothing 4 output.myLogger.info("foo")
à passes both filters andfoo
is output.
Now…
Logger myLogger
has 3 a level ofFINEST
and a singleConsoleHandler myHandler
which has a level 2 ofFINEST
myLogger.fine("foo")
à passes both filters and "foo
" is output.myLogger.info("foo")
à 1 passes both filters andfoo
is output.
You need to set the log level on both the 4 handlers in the logger, and the logger itself. Logging 3 is only performed at the "coarsest" of the 2 two levels. Here is a logging class that 1 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);
}
}
Other users have already given good answer 5 why it happened (ConsoleHandler has a separate 4 level variable). I reuse my application 3 logger's level and copy it up to the parent 2 hiearchy. Also provides easy way to refresh 1 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();
}
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
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.