【问题标题】:Java - configure custom loggers for useJava - 配置自定义记录器以供使用
【发布时间】:2016-10-12 02:23:55
【问题描述】:

尝试使用 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

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

但是,当我(例如)时,两个文件都没有创建

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");
    }
}

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

在哪里

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>

请帮忙...

【问题讨论】:

  • 从您的属性文件中删除 " 字符。
  • @VGR 删除了",似乎没有任何区别。

标签: java logging java.util.logging


【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-03
    • 1970-01-01
    • 1970-01-01
    • 2019-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多