Dynamically Changing log4j log level
For log4j 2 API , you can use
Logger logger = LogManager.getRootLogger();
Configurator.setAllLevels(logger.getName(), Level.getLevel(level));
Changing the log level is simple; modifying other portions of the configuration will pose a more in depth approach.
LogManager.getRootLogger().setLevel(Level.DEBUG);
The changes are permanent through the life cyle of the Logger
. On reinitialization the configuration will be read and used as setting the level at runtime does not persist the level change.
UPDATE: If you are using Log4j 2 you should remove the calls to setLevel
per the documentation as this can be achieved via implementation classes.
Calls to logger.setLevel() or similar methods are not supported in the API. Applications should remove these. Equivalent functionality is provided in the Log4j 2 implementation classes but may leave the application susceptible to changes in Log4j 2 internals.
Log4j2 can be configured to refresh its configuration by scanning the log4j2.xml file (or equivalent) at given intervals. Just add the "monitorInterval" parameter to your configuration tag. See line 2 of the sample log4j2.xml file, which tells log4j to to re-scan its configuration if more than 5 seconds have passed since the last log event.
<?xml version="1.0" encoding="UTF-8" ?>
<Configuration status="warn" monitorInterval="5" name="tryItApp" packages="">
<Appenders>
<RollingFile name="MY_TRY_IT"
fileName="/var/log/tryIt.log"
filePattern="/var/log/tryIt-%i.log.gz">
<Policies>
<SizeBasedTriggeringPolicy size="25 MB"/>
</Policies>
...
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="MY_TRY_IT"/>
</Root>
</Loggers>
</Configuration>
There are extra steps to make this work if you are deploying to a tomcat instance, inside an IDE, or when using spring boot. That seems somewhat out of scope here and probably merits a separate question.
File Watchdog
Log4j is able to watch the log4j.xml
file for configuration changes. If you change the log4j file, log4j will automatically refresh the log levels according to your changes. See the documentation of org.apache.log4j.xml.DOMConfigurator.configureAndWatch(String,long
) for details. The default wait time between checks is 60 seconds. These changes would be persistent, since you directly change the configuration file on the filesystem. All you need to do is to invoke DOMConfigurator.configureAndWatch() once.
Caution: configureAndWatch method is unsafe for use in J2EE environments due to a Thread leak
JMX
Another way to set the log level (or reconfiguring in general) log4j is by using JMX. Log4j registers its loggers as JMX MBeans. Using the application servers MBeanServer consoles (or JDK's jconsole.exe) you can reconfigure each individual loggers. These changes are not persistent and would be reset to the config as set in the configuration file after you restart your application (server).
Self-Made
As described by Aaron, you can set the log level programmatically. You can implement it in your application in the way you would like it to happen. For example, you could have a GUI where the user or admin changes the log level and then call the setLevel()
methods on the logger. Whether you persist the settings somewhere or not is up to you.