Java 如何使用我的日志格式创建我自己的自定义控制台记录器?

Java 如何使用我的日志格式创建我自己的自定义控制台记录器?,java,logging,Java,Logging,我使用标准的Java日志api,即Java.util.logging 我发现这方面的教程使用了扩展格式化程序,但是在Java8中格式化程序是最终的 我想要的是创建自己的类,该类确定在控制台中发送的消息的格式。这是我初始化日志记录的未完成代码: // Init logger { // get the global logger to configure it Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);

我使用标准的Java日志api,即
Java.util.logging

我发现这方面的教程使用了
扩展格式化程序
,但是在Java8中格式化程序是最终的

我想要的是创建自己的类,该类确定在控制台中发送的消息的格式。这是我初始化日志记录的未完成代码:

 // Init logger
 {
    // get the global logger to configure it
    Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
    // Remove all old/default loggers
    Logger rootLogger = Logger.getLogger("");
    java.util.logging.Handler[] handlers = rootLogger.getHandlers();
    for(java.util.logging.Handler h: handlers)
        rootLogger.removeHandler(h);

    logger.addHandler(new ConsoleLoggerBase());
 }
这是我登录标准输出的类:

package cz.autoclient.logging;

import java.util.logging.Handler;
import java.util.logging.LogRecord;

public class ConsoleLoggerBase extends Handler {

    @Override
    public void publish(LogRecord record) {
        System.out.println(record.getMessage());
    }

    @Override
    public void flush() {
        System.out.flush();
    }
    // No need to close system.out
    @Override
    public void close() throws SecurityException {}
}
但是程序日志是空的。。。我很惊讶在互联网上找不到关于这一点的简明信息。有人能解释一下我应该如何使用这个API吗?

您必须始终向正在修改的日志记录者报告。否则,您的记录器可以与新连接的处理程序一起被垃圾收集

正如报告中所述:

日志记录器在日志命名空间中跟踪其父日志记录器。记录器的父级是其在日志名称空间中最近的现存祖先。根记录器(名为“”)没有父级

您正在将处理程序附加到
全局\u记录器\u名称
。全局记录器的父级是根记录器。通常,全局记录器没有子项,因此,除非直接向全局记录器写入数据,否则不会看到任何输出。我的建议是忘记使用全局记录器。相反,请关注修改根记录器的输出格式,并让应用程序代码创建命名记录器

您不必创建自定义处理程序。而是创建一个自定义格式化程序,并将其安装在连接到根记录器的ConsoleHandler上

以下是一个示例程序:

import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

public class ModifyRoot {

    private static final Logger[] PINNED_LOGGERS;

    static {
        //Assuming the default config file.
        PINNED_LOGGERS = new Logger[]{
            Logger.getLogger(""),
            Logger.getLogger(ModifyRoot.class.getName())
        };

        for (Logger l : PINNED_LOGGERS) {
            for (Handler h : l.getHandlers()) {
                if (h instanceof ConsoleHandler) {
                    h.setFormatter(new DynamicFormatter());
                    h.setLevel(Level.ALL);
                }
            }
        }

        //Safe because it is already pinned.
        Logger.getLogger(ModifyRoot.class.getName()).setLevel(Level.ALL);
    }

    private static class DynamicFormatter extends java.util.logging.Formatter {

        @Override
        public String format(LogRecord record) {
            if (isJumpSite(record)) {
                return record.getSourceClassName() + '.'
                        + record.getSourceMethodName() + ' '
                        + formatMessage(record) + System.lineSeparator();
            } else {
                return formatMessage(record) + System.lineSeparator();
            }
        }

        private boolean isJumpSite(LogRecord record) {
            //Check the raw message not the formatted message.
            final String msg = String.valueOf(record.getMessage());
            return msg.startsWith("ENTRY") || msg.startsWith("RETURN")
                    || msg.startsWith("THROW");
        }
    }

    //========
    private static final String CLASS_NAME = ModifyRoot.class.getName();
    private static final Logger logger = Logger.getLogger(CLASS_NAME);

    public static void main(String[] args) {
        logger.entering(CLASS_NAME, "main");
        logger.info("Hello World!");
        logger.exiting(CLASS_NAME, "main");
    }
}
哪些产出:

ModifyRoot.main ENTRY
Hello World!
ModifyRoot.main RETURN

您应该考虑使用系统属性配置日志,并创建自己的代码>日志记录。属性文件。

< p>您必须始终对正在修改的记录器进行修改。否则,您的记录器可以与新连接的处理程序一起被垃圾收集

正如报告中所述:

日志记录器在日志命名空间中跟踪其父日志记录器。记录器的父级是其在日志名称空间中最近的现存祖先。根记录器(名为“”)没有父级

您正在将处理程序附加到
全局\u记录器\u名称
。全局记录器的父级是根记录器。通常,全局记录器没有子项,因此,除非直接向全局记录器写入数据,否则不会看到任何输出。我的建议是忘记使用全局记录器。相反,请关注修改根记录器的输出格式,并让应用程序代码创建命名记录器

您不必创建自定义处理程序。而是创建一个自定义格式化程序,并将其安装在连接到根记录器的ConsoleHandler上

以下是一个示例程序:

import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

public class ModifyRoot {

    private static final Logger[] PINNED_LOGGERS;

    static {
        //Assuming the default config file.
        PINNED_LOGGERS = new Logger[]{
            Logger.getLogger(""),
            Logger.getLogger(ModifyRoot.class.getName())
        };

        for (Logger l : PINNED_LOGGERS) {
            for (Handler h : l.getHandlers()) {
                if (h instanceof ConsoleHandler) {
                    h.setFormatter(new DynamicFormatter());
                    h.setLevel(Level.ALL);
                }
            }
        }

        //Safe because it is already pinned.
        Logger.getLogger(ModifyRoot.class.getName()).setLevel(Level.ALL);
    }

    private static class DynamicFormatter extends java.util.logging.Formatter {

        @Override
        public String format(LogRecord record) {
            if (isJumpSite(record)) {
                return record.getSourceClassName() + '.'
                        + record.getSourceMethodName() + ' '
                        + formatMessage(record) + System.lineSeparator();
            } else {
                return formatMessage(record) + System.lineSeparator();
            }
        }

        private boolean isJumpSite(LogRecord record) {
            //Check the raw message not the formatted message.
            final String msg = String.valueOf(record.getMessage());
            return msg.startsWith("ENTRY") || msg.startsWith("RETURN")
                    || msg.startsWith("THROW");
        }
    }

    //========
    private static final String CLASS_NAME = ModifyRoot.class.getName();
    private static final Logger logger = Logger.getLogger(CLASS_NAME);

    public static void main(String[] args) {
        logger.entering(CLASS_NAME, "main");
        logger.info("Hello World!");
        logger.exiting(CLASS_NAME, "main");
    }
}
哪些产出:

ModifyRoot.main ENTRY
Hello World!
ModifyRoot.main RETURN

你应该考虑使用系统属性配置日志记录器并创建自己的代码>日志记录。属性< /COD>文件。< /P>你错了。是最终的,但不是。你错了。是最终的,但不是。