Setting java.util.logging.config.file at runtime
Asked Answered
C

2

12

I am trying to set the java util logging config file at runtime to avoid having to set it as a VM parameter. But this just doesn't work. Whenever I am trying to reread the configuration, logging is disabled at all.

See the following code snippet:

package test;

import java.io.FileInputStream;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;

public class A {
  private static final Logger LOGGER= Logger.getLogger(A.class.getName());

  public static void main(String[] args) throws Exception {
    System.out.println("--- start");
    LOGGER.log(Level.SEVERE, "SEVERE 1");
    LOGGER.log(Level.FINEST, "FINEST 1");
    LogManager.getLogManager().readConfiguration();
    LOGGER.log(Level.SEVERE, "SEVERE 2");
    LOGGER.log(Level.FINEST, "FINEST 2");
    LogManager.getLogManager().readConfiguration(new FileInputStream("/tmp/logging.properties"));
    LOGGER.log(Level.SEVERE, "SEVERE 3");
    LOGGER.log(Level.FINEST, "FINEST 3");
    System.out.println("--- end");
  }
}

This is the output if I run the class without any VM argument:

--- start
09.11.2012 09:59:25 test.A main
SCHWERWIEGEND: SEVERE 1
09.11.2012 09:59:25 test.A main
SCHWERWIEGEND: SEVERE 2
--- end

As you can see, only the SEVERE levels are logged, as this is the default of the JREs logging.properties. Calling LogManager#readConfiguration() doesn't change anything. But when trying to read the configuration from my logging.properties, absolutely nothing is logged. There is no difference in calling LogManager#readConfiguration(InputStream) or setting the java.util.logging.config.file property and calling LogManager#readConfiguration().

Now see the next output, when I run the same code with the VM property -Djava.util.logging.config.file=/tmp/logging.properties :

--- start
2012-11-09 10:03:44.0838 SEVERE  [test.A#main()] - SEVERE 1
2012-11-09 10:03:44.0843 FINEST  [test.A#main()] - FINEST 1
--- end

As you can see, both the SEVERE and the FINEST levels are logged and they are logged in a different format. Both is specified in my custom logging.properties. But logging stops here after calling LogManager#readConfiguration()! This is different from the example above and I don't understand it. Also, just as in the example above, calling LogManager#readConfiguration(InputStream) doesn't work.

So what is the problem? According to the javadoc setting the java.util.logging.config.file property at runtime should work. Also both readConfiguration() methods should work as I expect. So what is the problem?

Cappadocia answered 9/11, 2012 at 10:11 Comment(4)
this might help you: #6316199Immunology
No, it doesn't help. Maybe I misunderstand your suggestion, but that question and its answer talk about configuring the logger fully programmatically. I want to use the logging.properties file, but read it at runtime (since I don't want to set a VM parameter at the commandline). Also, what is confusing me, is that the readConfiguration() methods don't seem to do what they are meant to do.Cappadocia
I tested it, it works for me. readConfiguration() reads configuration and after this, the new logger config is used. JDK 1.6.0_27.Havildar
I tried with JDK 1.6.0_26, 1.6.0_31 and 1.7.0_07. All under Linux. Neither of them works. Did you try my code snippet above? If yes, what was the output? If not, can you provide an example that worked for you, so I can try it out with this?Cappadocia
H
6

Probably a problem with your logging properties. I noticed that I had to use both level specifications in the config (root and console) to get the result.
Maybe your root logger level is below FINEST, e.g. INFO (.level=INFO).
Or not set at all, in which case I suppose it to be INFO.

I ran your code with the following logging.properties:

handlers=java.util.logging.ConsoleHandler
.level=FINEST
java.util.logging.ConsoleHandler.level=FINEST

Without specifying the -Djava.util.logging.config.file=/tmp/logging.properties output was:

--- start
09.11.2012 14:25:49 testing.Scribble main
SCHWERWIEGEND: SEVERE 1
09.11.2012 14:25:49 testing.Scribble main
SCHWERWIEGEND: SEVERE 2
09.11.2012 14:25:49 testing.Scribble main
SCHWERWIEGEND: SEVERE 3
09.11.2012 14:25:49 testing.Scribble main
AM FEINSTEN: FINEST 3
--- end

Looks correct! (My test class is called testing.Scribble, thats the only difference)

Using -Djava.util.logging.config.file=/tmp/logging.properties output is:

--- start
09.11.2012 14:31:06 testing.Scribble main
SCHWERWIEGEND: SEVERE 1
09.11.2012 14:31:06 testing.Scribble main
AM FEINSTEN: FINEST 1
09.11.2012 14:31:06 testing.Scribble main
SCHWERWIEGEND: SEVERE 2
09.11.2012 14:31:06 testing.Scribble main
AM FEINSTEN: FINEST 2
09.11.2012 14:31:06 testing.Scribble main
SCHWERWIEGEND: SEVERE 3
09.11.2012 14:31:06 testing.Scribble main
AM FEINSTEN: FINEST 3
--- end

Looks also correct!

Havildar answered 9/11, 2012 at 13:35 Comment(1)
You are right. The problem was in my logging.properties. It was the handlers directive. In my logging.properties I wrote it with a dot in front of it: .handlers. After removing the dot, it works. But what puzzles me, is that the very same logging.properties file works correct when setting it via VM parameter. That's quite strange (and I would call it a bug).Cappadocia
D
0

Instead of java.util.logging.config.file (which requires absolute or relative file system path) you could use java.util.logging.config.class which will take a class from classpath.

In Gradle build:

subprojects {
    // JavaForkOptions is base interface for JavaExec, BootRun, Test tasks...
    tasks.withType(JavaForkOptions) {
        systemProperty("java.util.logging.config.class", "com.evil.JulBootstrap")
    }
}

JulBootstrap has trivial implementation - a no-arg constructor:

public class JulBootstrap {
    public JulBootstrap() {
        final Logger rootLogger = Logger.getLogger("");
        rootLogger.setLevel(Level.FINER);
        // See SLF4JBridgeHandler.install().
        rootLogger.addHandler(new SLF4JBridgeHandler());
    }
}

You could do fancy things, like load properties file (and maybe tweak some settings programmaticly):

try (Inputstream stream : JulBootstrap.class.getResourceAsStream("/logging.properties")){
    LogManager.readConfiguration(stream);
}
...
Dineric answered 3/10, 2023 at 13:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.