如何使用属性文件设置Java日志记录?(java.util.logging)

91
我有一个愚蠢的Java日志记录问题:我从我的应用程序配置文件中加载日志记录配置,但是在读取该文件后它就不再记录任何内容了(文件看起来与您在网上找到的示例非常相似,除了额外的应用程序配置 - 删除此配置也无法解决问题)。"initializing..."日志行看起来很好,但是"starting app"和其他进一步的消息既没有记录到控制台,也没有创建日志文件。我在这里漏掉了什么?

Logger代码如下:

...
Logger log = Logger.getLogger("myApp");
log.setLevel(Level.ALL);
log.info("initializing - trying to load configuration file ...");

Properties preferences = new Properties();
try {
    FileInputStream configFile = new FileInputStream("/path/to/app.properties");
    preferences.load(configFile);
    LogManager.getLogManager().readConfiguration(configFile);
} catch (IOException ex)
{
    System.out.println("WARNING: Could not open configuration file");
    System.out.println("WARNING: Logging not configured (console output only)");
}
log.info("starting myApp");
...

这是配置文件:

appconfig1 = foo
appconfig2 = bar

# Logging
handlers = java.util.logging.FileHandler, java.util.logging.ConsoleHandler
.level = ALL

# File Logging
java.util.logging.FileHandler.pattern = %h/myApp.log
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.FileHandler.level = INFO

# Console Logging
java.util.logging.ConsoleHandler.level = ALL
6个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
113

你可以通过命令行设置日志配置文件:

$ java -Djava.util.logging.config.file=/path/to/app.properties MainClass

这种方式看起来更加简洁易懂,并且更加容易维护。


1
是的,我可能会添加一个检查,如果设置了这个属性,就让它覆盖我的配置 - 把所有内容都放在一个配置文件中,可以直接使用,这将是很好的。谢谢! - VolkA
这只能在本地工作,一旦部署,您需要将属性文件作为流。 - user1191027

30

好的,首先直觉在这里:

handlers = java.util.logging.FileHandler, java.util.logging.ConsoleHandler
.level = ALL

Java属性文件解析器并不是非常智能,我不确定它是否能处理这个。但我会再去查看文档……

与此同时,请尝试:

handlers = java.util.logging.FileHandler
java.util.logging.ConsoleHandler.level = ALL

更新

没错,需要多喝点咖啡。算了。

在我认真考虑的时候,请注意你可以使用Properties中的方法来加载和打印prop文件:也许写一个最小程序看看Java认为它读入了什么文件是值得的。

另一个更新

这一行:

    FileInputStream configFile = new FileInputStream("/path/to/app.properties"));

代码多了一个右括号,导致编译失败。请确认你正在使用正确的类文件。


嗯,它似乎与readConfiguration行有关 - 我用调试器逐步执行了这个过程,在此调用后,LogManager的所有属性都被清除了。 - VolkA
5
好的,我明白了 - 我正在两次使用相同的输入流,因此需要使用 configFile.reset() 重新定位它 - 否则 loadConfiguration() 调用将无法读取任何内容。顺便说一下,) 只是从我的工作代码中复制错误。 - VolkA
3
我不太确定这里的答案是什么? - Ondra Žižka
@OndraŽižka 答案是“你的代码由于语法错误而无法工作。” - Charlie Martin

13

我已经尝试过你在上面的代码中提供的代码,并且不使用 [preferences.load(configFile);] 语句,它会正常工作。这里是一个运行示例代码

public static void main(String[] s) {
    
    Logger log = Logger.getLogger("MyClass");
    try {
        FileInputStream fis =  new FileInputStream("p.properties");
        LogManager.getLogManager().readConfiguration(fis);
        
        log.setLevel(Level.FINE);
        log.addHandler(new java.util.logging.ConsoleHandler());
        log.setUseParentHandlers(false);
    
        log.info("starting myApp");
        fis.close();
    
    } catch(IOException e) {
        e.printStackTrace();
    }
}

1
p.properties文件应该与主类放置在同一目录下? - Luís Soares
你应该在 finally 块中关闭流,或者使用 try-with-resource。 - Valerij Dobler

9
Logger log = Logger.getLogger("myApp");
log.setLevel(Level.ALL);
log.info("initializing - trying to load configuration file ...");

//Properties preferences = new Properties();
try {
    //FileInputStream configFile = new //FileInputStream("/path/to/app.properties");
    //preferences.load(configFile);
    InputStream configFile = myApp.class.getResourceAsStream("app.properties");
    LogManager.getLogManager().readConfiguration(configFile);
} catch (IOException ex)
{
    System.out.println("WARNING: Could not open configuration file");
    System.out.println("WARNING: Logging not configured (console output only)");
}
log.info("starting myApp");

这个正常运行了..:) 你需要在readConfiguration()中传递InputStream。


3

您是否在正确的路径中搜索日志文件:%h/one%u.log

这里的 %h 代表您的主目录:在 Windows 中,它默认为:C:\Documents and Settings(user_name)。

我已经尝试了您发布的示例代码,并且在指定配置文件路径(通过代码或 Java 参数 logging.properties)后它可以正常工作。


先生,我可以知道哪里有在线文档说明%h解析为我的主目录,%u解析为其他内容等吗? - Luk Aron

0

java.util.logging.config.file是一个文件系统路径,在Java世界中不如类路径方便。

还有一个java.util.logging.config.class选项,它指定了一个具有无参构造函数的初始化类,该类将位于类路径上...

这样,您的初始化逻辑就不在main()方法中,您可以在类路径中搜索属性文件:

try (Inputstream stream : JulBootstrap.class.getResourceAsStream("/logging.properties")){
    LogManager.readConfiguration(stream);
}
其他例子在这里: 在运行时设置java.util.logging.config.file

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,