java.util.logging控制台处理程序不记录信息级别以下的消息

2cmtqfgy  于 2021-06-27  发布在  Java
关注(0)|答案(1)|浏览(236)

下面是我的记录器的代码。登录到文件工作得很好,但是控制台处理程序不会在level.info下面打印任何消息。

public class ServerLogger {

    /*
     * Log file size 
     */
    final private static int FILE_SIZE = 1024 * 100;

    /**
     * Creates and return server logger
     * 
     * @param dir log files directory
     * @param consoleEnabled if set to true then logging to console is enabled 
     * @param debugEnabled if set to true then debug level of logging is enabled
     * 
     * @return sever logger
     * 
     * @throws SecurityException
     * @throws IOException
     */
    public static Logger getLogger(final String dir, final boolean consoleEnabled, final boolean debugEnabled) 
    throws SecurityException, IOException {

        Logger logger = Logger.getLogger(Server.class.getName());
        logger.setUseParentHandlers(false);

        /* 
         * remove all handlers if any
         */
        Handler[] handlers = logger.getHandlers();

        if (handlers.length > 0) {
            for (Handler handler : handlers)
                logger.removeHandler(handler);
        }

        /*
         * create formatter 
         */
        Formatter formatter = new LineFormatter();

        /*
         * if console logging is enabled then add console handler
         */
        if (consoleEnabled) {
            ConsoleHandler consoleHandler =  new ConsoleHandler();
            consoleHandler.setFormatter(formatter);
            logger.addHandler(consoleHandler);
        }

        /*
         * add file handler
         */
        String nameTemplate = dir + "\\" + "server-log%g.txt";

        FileHandler fileHandler = new FileHandler(nameTemplate, FILE_SIZE, 10);
        fileHandler.setFormatter(formatter);
        logger.addHandler(fileHandler);

        Level level = debugEnabled ? Level.FINE : Level.INFO;
        logger.setLevel(level);

        return logger;
    }

    static private class LineFormatter extends Formatter {

        @Override
        public String format(LogRecord record) {
            return String.format("[%1$tF %1$tT] [%4$-7s] %5$s %n", record.getMillis(), record.getSourceMethodName(),
                   record.getLoggerName(), record.getLevel(), record.getMessage(), record.getThrown());
        }
    };

    public static void main(String[] args) throws SecurityException, IOException {

        //test
        Logger logger = ServerLogger.getLogger("C:\\logs", true, true);

        logger.severe("severe");
        logger.warning("warning");
        logger.info("info");
        logger.config("config");
        logger.fine("fine");
        logger.finer("finer");
        logger.finest("finest");

    }

我替换了 ConsoleHandlerStreamHandler 但这没用。替代 logger.setLevel(level)logger.setLevel(Level.ALL) 也没用。使用设置处理程序级别 handler.set(Level level) 不会改变什么。控制台上的消息是:

[2020-12-30 22:09:59] [SEVERE ] severe 
[2020-12-30 22:10:00] [WARNING] warning 
[2020-12-30 22:10:00] [INFO   ] info

你能帮忙吗。

wf82jlnq

wf82jlnq1#

永远别让你的记录程序被垃圾收集。具体做法如下:

private static final Logger logger = Logger.getLogger(Server.class.getName());

如果记录器被垃圾收集,则所有更改都将丢失并回退到logging.properties。
下一个问题是,如果您以编程方式删除处理程序,您也必须关闭它们。

if (handlers.length > 0) { //The if is not needed, just the for loop.
        for (Handler handler : handlers) {
            logger.removeHandler(handler);
            handler.close(); //Don't leak resources.
        }
 }

下一个问题是必须将控制台处理程序级别设置为all:

ConsoleHandler consoleHandler =  new ConsoleHandler();
consoleHandler.setFormatter(formatter);
consoleHandler.setLevel(Level.ALL);
//consoleHandler.setLevel(debugEnabled ? Level.FINE : Level.INFO); //This would work too.

这允许处理程序接受低于info的日志记录。
虽然使用静态方法设置日志配置“有效”,但实际上您只需要设置一次配置。在运行时更改记录器树非常快速,可能会导致消息丢失。您应该使用记录器配置文件、记录器类或静态初始值设定项块,以便配置只加载一次。
小心使用streamhandler+system.err或system.out。隐式或显式关闭streamhandler将关闭它正在 Package 的系统流,这将停止所有到console的输出。控制台管理员不会这样做。

相关问题