Change global setting for Logger instances

JavaLogging

Java Problem Overview


I'm using java.util.logging.Logger as the logging engine for my application. Each class uses it's own logger, i.e., each class has:

private final Logger logger = Logger.getLogger(this.getClass().getName());

I want to set a logging level for all my classes, and be able to change it (i.e., have the setting in one place). Is there a way to do this, other that using a global Level variable and manually set each logger to it?

Java Solutions


Solution 1 - Java

One easy way is to use a logging properties file, by including this VM argument:

-Djava.util.logging.config.file="logging.properties" 

where "logging.properties" is the path to a file containing logging configuration. For relative paths, the working directory of the process is significant.

In that file, include a line like this:

.level= INFO

This sets the global level, which can be overridden for specific handlers and loggers. For example, a specific logger's level can be overridden like this:

 com.xyz.foo.level = SEVERE

You can get a template for a logging properties file from jre6\lib\logging.properties.

Solution 2 - Java

As Andy answered, in most cases you should use the property file and the VM argument, thus its independent from your code.

But if you want to go programatically for some reason (I myself had a good reason in one case) you can access the Handlers like this too:

Logger rootLogger = LogManager.getLogManager().getLogger("");
rootLogger.setLevel(Level.INFO);
for (Handler h : rootLogger.getHandlers()) {
	h.setLevel(Level.INFO);
}

EDIT I added the setLevel to the root logger as searchengine27 pointed out in in his answer.

The Handlers are File or Console Handlers that you setup via the properties or programatically too.

Or change filters like this:

Logger rootLogger = LogManager.getLogManager().getLogger("");
rootLogger.setFilter(new Filter() {
    @Override
	public boolean isLoggable(LogRecord record) {
			return "something".equals(record.getLoggerName());
	}
});

Solution 3 - Java

So I don't entirely like all of the answers here, so I'm going to chime in.

Config file use

You're seeing a lot of answers in here telling you to use the config file because it is best practice. I want to explain better how to do this programatically, but before I do, I want to say that I can see where they are coming from, and in the mood of being objective, I will enlighten you a bit (especially because nobody says why its bad practice). I actually want to share what somebody said in a separate StackOverflow answer that is in relation to setting the logger level programatically (https://stackoverflow.com/questions/6315699/why-are-the-level-fine-logging-messages-not-showing):

> This is not recommended, for it would result in overriding the global configuration. Using this throughout your code base will result in a possibly unmanageable logger configuration.

On that note, I think Andy Thomas has a goodish answer related to not doing it non-programatically.

Programatically setting the Level

That being said, I want to go into a bit more detail about doing it programatically, because I think it has its uses.

Imagine a scenario where you are writing something with a command line interface and you have an option to specify the verbosity of your execution, or even where it goes to (as in dynamic log files). I may be mistaken, but you would probably not want to do this statically in a .conf file. Especially so if you don't want to make your userbase responsible for setting these things (for whatever arbitrary reason) in the config file. This comes at the expense of the above quote, however. Here is an example of how you can do it programatically, keeping all of the existing handlers to whatever level they are at already, and only FileHandler's assume the new level:

public static void setDebugLevel(Level newLvl) {
    Logger rootLogger = LogManager.getLogManager().getLogger("");
    Handler[] handlers = rootLogger.getHandlers();
    rootLogger.setLevel(newLvl);
    for (Handler h : handlers) {
        if(h instanceof FileHandler)
            h.setLevel(newLvl);
    }
}

I wanted to expand on this, over the accepted answer for one reason in particular. When doing it programatically, you just want to make sure that you set the level for the logger and the handler(s). The way it works, is it will check to see if the request is too low for the logger, and if it is it will discard it. Then the handler(s) have the same check, so you will want to make sure both the loggers and handlers are set to the level you want it.

Solution 4 - Java

One-liner Java 8 approach to morja's answer:

Arrays.stream(LogManager.getLogManager().getLogger("").getHandlers()).forEach(h -> h.setLevel(Level.INFO));

Solution 5 - Java

JUL(java.util.logging) is java default logger within jvm.

Java Logging Technology--see Overview

So you may find that there is a default config file already in C:\Program Files\Java\jre1.8.0_221\lib\logging.properties

I recommend that you create a new config file under your project to override the default setting, do as following:

config file name, logging.properties, all log level can be found in Class Level

handlers= java.util.logging.ConsoleHandler
.level= INFO
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format= [%1$tF %1$tT] [%4$-7s] %5$s %n

# your specific logger level
com.xyz.foo.level = SEVERE

Then add jvm option to enable the config

java -Djava.util.logging.config.file="logging.properties" -Duser.country=CN -Duser.language=en

user.country and user.language may have an effect on log message localization

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAmir RachumView Question on Stackoverflow
Solution 1 - JavaAndy ThomasView Answer on Stackoverflow
Solution 2 - JavamorjaView Answer on Stackoverflow
Solution 3 - Javasearchengine27View Answer on Stackoverflow
Solution 4 - Javamarcelovca90View Answer on Stackoverflow
Solution 5 - JavaLuke CheungView Answer on Stackoverflow