有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

日志Java配置自定义日志记录器以供使用

尝试使用java.util.logging失败

试图利用https://stackoverflow.com/a/8249319/3322533

handlers = mypackage.logging.RequestFileHandler, mypackage.logging.MainFileHandler
config   =

mainLogger.handlers       = mypackage.logging.MainFileHandler

requestLogger.handlers    = mypackage.logging.RequestFileHandler

java.util.logging.ConsoleHandler.level     = INFO
java.util.logging.ConsoleHandler.filter    =
java.util.logging.ConsoleHandler.formatter = mypackage.logging.VerySimpleFormatter
java.util.logging.ConsoleHandler.encoding  =

mypackage.RequestFileHandler.level     = SEVERE
mypackage.RequestFileHandler.filter    =
mypackage.RequestFileHandler.formatter = mypackage.logging.VerySimpleFormatter
mypackage.RequestFileHandler.encoding  =
mypackage.RequestFileHandler.limit     =
mypackage.RequestFileHandler.count     =
mypackage.RequestFileHandler.append    = false
mypackage.RequestFileHandler.pattern   = REQUESTS.%u.%g.log

mypackage.MainFileHandler.level     = INFO
mypackage.MainFileHandler.filter    =
mypackage.MainFileHandler.formatter = mypackage.logging.VerySimpleFormatter
mypackage.MainFileHandler.encoding  =
mypackage.MainFileHandler.limit     =
mypackage.MainFileHandler.count     =
mypackage.MainFileHandler.append    = false
mypackage.MainFileHandler.pattern   = MAIN.%u.%g.log

在哪里

public class MainFileHandler extends FileHandler {
    public MainFileHandler() throws IOException, SecurityException {
        super();
    }
}

public class RequestFileHandler extends FileHandler {
    public RequestFileHandler() throws IOException, SecurityException {
        super();
    }
}

目的:提供两个可通过

Logger.getLogger("mainLogger");

Logger.getLogger("requestLogger");

分别,一个将(独占地)写入MAIN[...].log,另一个将写入REQUESTS[...].log

(对可以记录到任一文件中的消息数量没有限制,如有必要,使用日志记录级别过滤掉任何一个文件中不需要的MSG。)

但是,当I(例如)时,两个文件都不会创建

public static final Logger log = Logger.getLogger("mainLogger");

然后

public void configureLogger(){
    try {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        InputStream config = classLoader.getResourceAsStream("logging.properties");

        LogManager.getLogManager().readConfiguration(config);

    }catch(Exception ex){
       throw new RuntimeException("logging properties failed");
    }
}

在我之前

log.info("Hello World!")

我知道已加载属性,因为当我在handlers = ...列表中包含java.util.logging.ConsoleHandler并使用全局记录器时,格式化程序将应用于控制台输出

所以。。。我想我设置文件记录器的尝试是错误的。我怎样才能让它工作

编辑

因此,我删除了[...].pattern = [...]行,而是硬编码了文件名:

public class MainFileHandler extends FileHandler implements FileHandlerProperties {
    public MainFileHandler() throws IOException, SecurityException {
        super("MAIN_" + new SimpleDateFormat(TIME_PATTERN).format(new Date()) + ".log");
    }
}

^{10}pr$

在哪里

public interface FileHandlerProperties {
    static final String TIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
}

这两个文件现在都已创建,但它们都包含完全相同的内容(尽管它们的级别设置和记录器不同),并且它们包含的内容是xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE log SYSTEM "logger.dtd">
<log>
<record>
  <date>2016-10-10T18:49:23</date>
  <millis>1476118163654</millis>
  <sequence>0</sequence>
  <logger>mainLogger</logger>
  <level>INFO</level>
  <class>mypackage.main.Main</class>
  <method>&lt;init&gt;</method>
  <thread>1</thread>
  <message>Hello World</message>
</record>
</log>

请帮忙


共 (1) 个答案

  1. # 1 楼答案

    问题是,在类加载期间对Logger.getLogger的第一次调用读取日志配置,而configureLogger方法由于JDK-8033661: readConfiguration does not cleanly reinitialize the logging system而失败

    要解决这个问题,您必须确保configureLogger在第一次调用Logger.getLogger之前运行

    public class BootMain {
    
        static {
            configureLogger();
            mainLogger = Logger.getLogger("mainLogger");
            requestLogger = Logger.getLogger("requestLogger");
        }
    
        private static final Logger mainLogger;
    
        private static final Logger requestLogger;
    
        public static void main(String[] args) throws IOException {
            mainLogger.log(Level.SEVERE, "Test from main.");
            requestLogger.log(Level.SEVERE, "Test from request.");
            System.out.println(new File(".").getCanonicalPath());
        }
    
        private static void configureLogger() {
            try {
                InputStream config = config();
                LogManager.getLogManager().readConfiguration(config);
            } catch (Exception ex) {
                throw new RuntimeException("logging properties failed");
            }
        }
    
        private static String prefix() {
            return "mypackage.logging";
        }
    
        private static InputStream config() throws IOException {
            String p = prefix();
            Properties props = new Properties();
            props.put("mainLogger.handlers", p + ".MainFileHandler");
            props.put("requestLogger.handlers", p + ".RequestFileHandler");
            props.put(p + ".RequestFileHandler.level", "SEVERE");
            props.put(p + ".MainFileHandler.level", "INFO");
            props.put(p + ".RequestFileHandler.pattern", "REQUESTS.%u.%g.log");
            props.put(p + ".MainFileHandler.pattern", "MAIN.%u.%g.log");
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            props.store(out, "");
            return new ByteArrayInputStream(out.toByteArray());
        }
    }
    

    还要确保您没有使用非常旧的JDK版本,否则可能会遇到JDK-5089480: java.util.logging.FileHandler uses hardcoded classname when reading properties

    否则可以使用LogManager config option to manually setup your configuration