2

I want my Logger with a FileHandler to use the settings defined in my config file. Do I have to use Logger.getLogger or Logger.addHandler(new FileHandler()) after I have used LogManager.readConfiguration(InputStream) or is there more to it? In other words, what is the order that I am supposed to do the following 3 things (getLogger, addHandler, readConfigurations) assuming it has to do with the order and isn't something else?

I wasn't able to find many examples of this and the ones I found had the LogManager.readConfiguration after Logger.getLogger, but that doesn't seem to work.

Here is the config file:

handlers = java.util.logging.FileHandler

.level = ALL

# Default
java.util.logging.FileHandler.limit = 10000000
java.util.logging.FileHandler.count = 10
java.util.logging.FileHandler.append = true
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.FileHandler.level = FINE

EDIT: Here is the part of the code relating to the configuration.

String configFilename = "C:\\Users\\dalawh\\Documents\\config.properties";
LogManager manager = LogManager.getLogManager();
String property = manager.getProperty(this.getClass().getPackage().getName()); //DEBUGGING
LogManager.getLogManager().readConfiguration(new FileInputStream(configFilename));
String property2 = manager.getProperty(this.getClass().getPackage().getName()); //DEBUGGING

Logger logger = java.util.logging.Logger.getLogger(this.getClass().getPackage().getName());
String property3 = manager.getProperty(this.getClass().getPackage().getName()); //DEBUGGING
String filename = "C:\\Users\\dalawh\\Documents\\log.log";
this.fileHandler = new FileHandler(filename);
this.logger.addHandler(this.fileHandler);
dalawh
  • 886
  • 8
  • 15
  • 37

1 Answers1

3

Related to this is: configure Logger via global config file.

A call to LogManager.readConfiguration will determine what logger.getLogger will return. If you define a handler in your properties file you will not have to add the handler later. If you want to add a handler using code then the solution you are looking for is:

  1. LogManager.readConfiguration
  2. Logger.getLogger and store a strong reference to it
  3. Create new handler
  4. Logger.addHandler

If you define java.util.logging.config.file as a system property in your startup script you don't have to write any code.

-Djava.util.logging.config.file="path to file"

For more information read the LogManager class level documentation.

If you can't define that property on startup then you can resort to the LogManager.readConfiguration(InputStream) method to perform the setup. You don't have to call any other methods unless you run into JDK-8033661 readConfiguration does not cleanly reinitialize the logging system or JDK-5035854 LogManager.readConfiguration does not properly modify existing loggers.

If neither of those options work you can resort to just getting a logger and calling the configuration methods as needed.

To troubleshoot your issue add the following:

String configFilename = "C:\\Users\\dalawh\\Documents\\config.properties";
System.out.println(new File(configFilename).length());
LogManager manager = LogManager.getLogManager();
LogManager.getLogManager().readConfiguration(new FileInputStream(configFilename));
String property = manager.getProperty("java.util.logging.FileHandler.formatter"); //DEBUGGING
System.out.println(property);
  1. If java.util.logging.SimpleFormatter is printed then you know you have configured the LogManager.
  2. If nothing is printed then an exception was thrown then you must have set an empty value in your properties file.
  3. If null is printed then your config file is incorrect or something reset the LogManager.

Here is a simple test to prove that the log manager works.

public class LogManagerTest {

    public static void main(String[] arg) throws IOException {
        read(LogManager.getLogManager(), create());
        FileHandler h = new FileHandler();
        h.close();
        System.out.println(h.getFormatter());
    }

    private static Properties create() {
        Properties props = new Properties();
        props.setProperty("java.util.logging.FileHandler.formatter", 
                "java.util.logging.SimpleFormatter");
        return props;
    }

    private static void read(LogManager manager, Properties props) throws IOException {
        final ByteArrayOutputStream out = new ByteArrayOutputStream(512);
        props.store(out, "No comment");
        manager.readConfiguration(new ByteArrayInputStream(out.toByteArray()));
    }
}
jmehrens
  • 10,580
  • 1
  • 38
  • 47
  • Thanks for the additional information, but this is not quite what I am looking for. I am already using LogManager.readConfiguration(InputStream) to read the configuration from a file I have, which I have specified in the InputStream. My question is what is the order that I am supposed to do the following 3 things (getLogger, addHandler, readConfigurations) assuming it has to do with the order and isn't something else? – dalawh Sep 23 '14 at 02:30
  • The logger still seems to use the default configs. I read the configurations from a file I have, then I got the Logger, then I added the FileHandler to the Logger, but the Logger still logged in xml instead of using the simple formatter as specified in the config file. – dalawh Sep 24 '14 at 03:35
  • @dalawh you either haven read the configuration or something is calling LogManager.reset. Call LogManager.getProperty to verify that your settings were loaded before you create your file handler. – jmehrens Sep 24 '14 at 12:34
  • I used getProperty in 3 different areas and it kept returning null. I included the code in the original question. Is something wrong with my configuration file? – dalawh Sep 25 '14 at 04:10
  • Those keys are not defined in the file. Look for "java.util.logging.FileHandler.formatter" since that is what you are looking for in the output file. – jmehrens Sep 25 '14 at 13:38
  • My understanding of the Logger is not as good as yours, so bare with me. I am don't quite understand. From your previous explanations, I thought you meant that once the LogManager reads from the configuration file, all loggers/handlers created hence forth that is define in the config file will use those configs. Am I mistaken? If I am not mistaken, shouldn't the new FileHandler that I created after it read the configurations use the configs defined in the configuration file? I did define the limit, count, append formatter, and level. This is a mouthful; I hope everything makes sense. – dalawh Sep 25 '14 at 20:21
  • Right but in this case LogManager.reset can undo your settings. Don't get hung up on that. Read the related link at the top of my answer. It is really the same issue as this one so use the example code in that answer and start testing. Write code to prove everything you think you have done. Read my edits to the answer. – jmehrens Sep 26 '14 at 12:32
  • Your troubleshooting method is the same as mines except yours prints to the console. I used the debugger to step through it instead and as I have mentioned, I get null when I use LogManager.getProperty. I also get no exceptions. I will respond to the articles you provided momentarily. – dalawh Sep 26 '14 at 17:23
  • In response to https://bugs.openjdk.java.net/browse/JDK-8033661, I want to use per-logger handlers, that way when I change one property, it doesn't affect all of them, and I would rather not use the API calls, otherwise, I will have to restart the application every time and it will not be possible if the user doesn't have the application's source code. I might be forced to use the JVM startup method. In response to https://bugs.openjdk.java.net/browse/JDK-5035854, doesn't that just say that their are bugs that have not been fixed? If that is the case, it's a shame. – dalawh Sep 26 '14 at 17:27
  • The configurations are being read in correctly, but when FileHandler is created, it doesn't use the values in the config file. – dalawh Oct 04 '14 at 22:20
  • How did you prove that? If that is true then you are running into the bugs I pointed out or something is calling reset between the readConfiguration and new FileHandler(). Merge new code sample into your project instead of loading from a file. See if that works. – jmehrens Oct 06 '14 at 15:33