Reputation: 718
I'd like to have 1 configuration file that contains information about how/where/what logger in particular class should log.
Example:
class Foo
package myApp;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
class Foo {
static final Logger logger = Logger.getLogger(Foo.class.getName());
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("C:\\path\\to\\myApp.log.properties");
LogManager.getLogManager(). readConfiguration(fis);
logger.log(Level.INFO, "Msg message");
Bar obj = new Bar();
obj.doSth();
}
class Bar
package myApp;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Bar {
static final Logger logger = Logger.getLogger(Bar.class.getName());
public Bar() {
}
public void doSth() {
logger.log(Level.WARNING, "Msg message");
}
}
File myApp.log.properties
handlers =
config =
myApp.Foo.handlers = java.util.logging.ConsoleHandler
myApp.Foo.useParentHandlers = false
myApp.Foo.level = INFO
myApp.Bar.handlers = java.util.logging.ConsoleHandler
myApp.Bar.useParentHandlers = false
myApp.Bar.level = INFO
Output:
Jul 23, 2014 1:27:12 PM myApp.Bar doSth
WARNING: Msg message
As you can see, the log record for Foo is missing, i guess it's because logger is static and is created before configuration for LogManager is loaded and set.
Could you please suggest solution where log record is printed for Foo's logger? Also with a static logger and without using commandline parameter -D configFile
when the program is executed?
Upvotes: 0
Views: 1779
Reputation: 11065
In your example, LogingToFile.doSth
is called instead of Bar.doSth
. Modify your config file to include:
myApp.LogingToFile.handlers = java.util.logging.ConsoleHandler
myApp.LogingToFile.useParentHandlers = false
myApp.LogingToFile.level = INFO
Or add new Bar().doSth();
to your main method.
Reading through the LogManager
source code it appears that Handlers
are only loaded when the logger is created after the configuration is set. This is bug JDK-8033661
readConfiguration does not cleanly reinitialize the logging system. The listed workarounds are:
- Do not use per-logger handlers in your log configuration file
- Do not call readConfiguration() or readConfiguration(InputStream), but store the configuration in a file and load it on JVM startup
- Configure your logging through API calls
Given your constraints, the workaround will be to load the configuration before creating the loggers.
class Foo {
static {
try (FileInputStream fis = new FileInputStream("C:\\path\\to\\myApp.log.properties")) {
LogManager.getLogManager().readConfiguration(fis);
} catch (IOException ex) {
throw new ExceptionInInitializerError(ex);
}
}
static final Logger logger = Logger.getLogger(Foo.class.getName());
public static void main(String[] args) throws IOException {
logger.log(Level.INFO, "Msg message");
Bar obj = new Bar();
obj.doSth();
}
}
Upvotes: 1