3

In my application at one point I set the root Logger of java.util.logging and all it's handlers to Level.FINEST like this:

Logger.getLogger("").setLevel(Level.FINEST);
for (Handler handler : Logger.getLogger("").getHandlers()) {
      handler.setLevel(Level.FINEST);
}

In a later point I create a class Logger like this:

private static final Logger JAVA_LOG = Logger.getLogger(MyClass.class.getName());

Now this loggers Level is INFO (which seems to be the default for JUL), while it's root Loggers Level is properly set to FINEST. Shouldn't setting the Level for the root Logger also set the Level for all children loggers of the root Logger? Am I doing something wrong in retrieving the class Logger?

Würgspaß
  • 4,205
  • 2
  • 23
  • 40
Jdv
  • 883
  • 7
  • 28

2 Answers2

2

Shouldn't setting the Level for the root Logger also set the Level for all children loggers of the root Logger?

No, apparently you are creating a new Logger object. Javadoc for getLogger states:

If a new logger is created its log level will be configured based on the LogManager configuration and it will configured to also send logging output to its parent's Handlers.

Please note, that even if there had been a Logger object with the same name before, you cannot rely on getLogger to return the same object as it might have been garbage collected if there is no strong reference to the object.

If your aim is to create all Logger objects within your project with the same log level, you should not do it programmatically but by configuration. That is where java.util.logging comes in handy. The overall advantage is that you can run your application in different log levels without even changeing a single line of code.

Simply edit your configuration file (which essentially is the above mentioned LogManager configuration). It is called logging.properties and located in your JRE directory. There you can edit the last paragraph and configure project-wide or class-narrowed log levels:

############################################################
# Facility specific properties.
# Provides extra control for each logger.
############################################################

myProject.MyClass.level = FINE
myProject.MyOtherNotSoImportantClass.level = INFO
mySecondProject.MainClass.level = NONE

An even better solution is to copy logging.properties to your project directory and call your app with

java -Djava.util.logging.config.file=./src/test/resources/logging.properties
Würgspaß
  • 4,205
  • 2
  • 23
  • 40
  • Thanks for the reply. Can you tell me if there is a way to programmatically achieve what I was asking for? Creating a setting so that future class loggers will be created with a specific Level? – Jdv Feb 20 '19 at 14:26
  • @Jdv If your logger would not be final, you could create the logger and change its log level in a static intializer. But why? see updated answer. – Würgspaß Feb 20 '19 at 23:33
1

The accepted answer is completely valid and I totally agree with it.

That said, I would like to add this tidbit of knowledge... do with it what you will.

private static final Logger JAVA_LOG = Logger.getLogger(MyClass.class.getName());
static { JAVA_LOG.setLevel(null); }

This will tell it to inherit its ancestors log level. Logger.setLevel() javadoc

If the new level is null, it means that this node should inherit its level from its nearest ancestor with a specific (non-null) level value.

Atspulgs
  • 1,099
  • 10
  • 9