简体   繁体   中英

Logging doesn't work for lower levels

I am using java.util.logging, which works fine for higher levels above FINE but doesn't work for lower levels, though I have set level as FINEST. I have tried giving it Level.ALL also. I have user defined class as follows.

public class Tracer extends Logger {
    public Tracer(String name) {
        super(name, null);
        addFileHandler();
        addConsoleHandler();
    }

    private void addConsoleHandler() {
        SSFormatter ssFormatter = new SSFormatter();
        ConsoleHandler consoleHandler = new ConsoleHandler();
        consoleHandler.setFormatter(ssFormatter);
        consoleHandler.setLevel(Level.FINEST);
        this.addHandler(consoleHandler);
    }

    private void addFileHandler() {
        try {
            FileHandler fileHandler = new FileHandler("log.txt", false);
            fileHandler.setFormatter(new SSFormatter());
            fileHandler.setLevel(Level.FINEST);
            this.addHandler(fileHandler);
        } catch (SecurityException e) {
            e.printStackTrace();
            this.warning("SecurityException occurred while adding FileHandler");
        } catch (IOException e) {
            e.printStackTrace();
            this.warning("IOException occurred while adding FileHandler");
        }
    }

    private class SSFormatter extends Formatter {

        @Override
        public String format(LogRecord paramLogRecord) {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(paramLogRecord.getLoggerName()).append("|")
                    .append(paramLogRecord.getSourceClassName()).append("|")
                    .append(paramLogRecord.getSourceMethodName()).append(":::")
                    .append(paramLogRecord.getMessage()).append("\n");
            return stringBuilder.toString();
        }
    }
    public static void main(String[] args) {
        Tracer tracer = new Tracer("ss.tracer");
        tracer.info("This is to test my tracer");
        tracer.warning("This is warning from my tracer");
        tracer.severe("This is severe from my tracer");
        tracer.fine("this is fine");
        tracer.finer("this is finer");
        tracer.finest("this is finest");
    }
}

When I run main method, I get the console and file output as follows

ss.tracer|screen.seizer.trace.Tracer|main:::This is to test my tracer
ss.tracer|screen.seizer.trace.Tracer|main:::This is warning from my tracer
ss.tracer|screen.seizer.trace.Tracer|main:::This is severe from my tracer

Thanks, Hope I have put forward my question clear.

I am using java.util.logging, which works fine for higher levels above FINE but doesn't work for lower levels, though I have set level as FINEST.

The handlers have levels but the Logger also has a level which defaults to INFO . Here's the line from the Logger constructor:

levelValue = Level.INFO.intValue();

Even if the level in the handlers is lower than INFO , if the logger level is higher then none of those log messages will make it to the handlers. In each of the fine and other methods there are checks like:

if (Level.FINE.intValue() < levelValue) {
    return;
}

If you call something like the following in your main then all of the level messages will be printed.

tracer.setLevel(Level.ALL);

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(L    ogRecord 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);
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM