Programmatically change log level in Log4j2
The Easy Way :
EDITED according to log4j2 version 2.4 FAQ
You can set a logger’s level with the class Configurator from Log4j Core. BUT be aware that the Configurator class is not part of the public API.
// org.apache.logging.log4j.core.config.Configurator;
Configurator.setLevel("com.example.Foo", Level.DEBUG);
// You can also set the root logger:
Configurator.setRootLevel(Level.DEBUG);
Source
The Preferable Way :
EDITED to reflect changes in the API introduced in Log4j2 version 2.0.2
If you wish to change the root logger level, do something like this :
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration config = ctx.getConfiguration();
LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
loggerConfig.setLevel(level);
ctx.updateLoggers(); // This causes all Loggers to refetch information from their LoggerConfig.
Here is the javadoc for LoggerConfig.
Change log level programmatically
I would strongly suggest that you do NOT use a programmatic solution for this because it will make your code depend on the implementation details of log4j2. This will make long term maintenance of your code problematic if the implementation changes. So, if you don't want to go with the JMX approach then you could set up your log4j2 configuration to use a DynamicThresholdFilter.
Here is a simple example of the filter approach:
First, a log4j2.xml file to configure the log4j2 system:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
<DynamicThresholdFilter key="myLogLvl" defaultThreshold="ERROR"
onMatch="ACCEPT" onMismatch="DENY">
<KeyValuePair key="TRACE" value="TRACE"/>
<KeyValuePair key="DEBUG" value="DEBUG"/>
<KeyValuePair key="INFO" value="INFO"/>
<KeyValuePair key="WARN" value="WARN"/>
<KeyValuePair key="FATAL" value="FATAL"/>
</DynamicThresholdFilter>
</Console>
</Appenders>
<Loggers>
<Root level="ALL">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
Notice how I have set up the filter so that the DynamicThresholdFilter
has a key of "myLogLvl" and then several KeyValuePair
that define the log level threshold based on the value in ThreadContext
for the key "myLogLvl". I assumed you wanted to use the names of the levels as the value you would put into ThreadContext
.
Also notice that I have set the Root
logger's level to "ALL". This is so that all messages will be accepted by the logger and then filtered by the filter. In other words I'm putting the filter in control of which messages are accepted rather than the logger.
Here is a simple Java class to generate some logs:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
public class SomeClass {
private static final Logger log = LogManager.getLogger();
public static void main(String[] args){
ThreadContext.put("myLogLvl", "WARN");
if(log.isDebugEnabled())
log.debug("This is some debug! (This should not appear in console)");
log.info("Here's some info! (This should not appear in console)");
log.error("Some error happened! (We will see this in the console)");
//Maybe now I want INFO log level
ThreadContext.put("myLogLvl", "INFO");
log.info("This should now appear in the console");
log.debug("This still should --not-- appear");
log.fatal("This will also appear");
}
}
Notice the first I do is set the ThreadContext
variable "myLogLvl" to "WARN" so that only messages that are "WARN" level or more specific are accepted. If you don't do this there will be no value for "myLogLvl" which means the default level defined in the filter will not apply either, so all messages will be accepted.
Here is sample output generated by the above:
10:39:44.668 [main] ERROR example.SomeClass - Some error happened! (We will see this in the console)
10:39:44.670 [main] INFO example.SomeClass - This should now appear in the console
10:39:44.670 [main] FATAL example.SomeClass - This will also appear
Hope this helps!
Log4j: Change log level programmatically that works for to-be created loggers
Didn't find the resource anymore, but as to my faded memory LogManager.getLogger("com.my.company").setLevel(whateverloglevel)
should do the job.
All loggers that are created with LogManager.getLogger(MyClass.class)
where MyClass is in com.my.company or in a subtree of that will be affected.
whateverloglevel
is one of Level:
- ALL
- The ALL has the lowest possible rank and is intended to turn on all logging.
- DEBUG
- The DEBUG Level designates fine-grained informational events that are most useful to debug an application.
- ERROR
- The ERROR level designates error events that might still allow the application to continue running.
- FATAL
- The FATAL level designates very severe error events that will presumably lead the application to abort.
- INFO
- The INFO level designates informational messages that highlight the progress of the application at coarse-grained level.
- OFF
- The OFF has the highest possible rank and is intended to turn off logging.
- TRACE
- The TRACE Level designates finer-grained informational events than the DEBUG
- WARN The WARN level designates potentially harmful situations.
Be aware that this probably does not work in log4j 2.
For (I think) version >= 2.4 see:
- log4j FAQ
- Programmatically change log level in Log4j2
Dynamically Changing log4j log 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 does not change logging level at runtime
Found the real issue. Had to use:
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
instead of
LoggerContext ctx = (LoggerContext) LogManager.getContext();
API stating the difference being "returns the LoggerContext" and "returns the current LoggerContext". And I clearly missed this bit of information for the version without boolean parameter:
"WARNING - The LoggerContext returned by this method may not be the LoggerContext used to create a Logger for the calling class."
Changing log level for a keyword in log4j2
@fatCop's answer is mostly correct. You can start with log4j2.xml configured as
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="AppName" packages="">
<RegexFilter regex="*database*" onMatch="DENY" onMismatch="DENY"/>
<Appenders>
<RollingFile name="RollingFile" fileName="logs/app.log"
filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] %m%n</pattern>
</PatternLayout>
<TimeBasedTriggeringPolicy />
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
Because this is using a global filter it will cause nothing to be logged. When you are ready to enable logging do
final LoggerContext loggerContext = LoggerContext.getContext(false);
final Configuration config = loggerContext.getConfiguration();
Filter filter = RegexFilter.createFilter("database", null, false, Result.ACCEPT, RESULT.DENY);
config.setFilter(filter);
When you want it disabled then replace the filter with a new one that is set back to DENY on a match.
Note that the logging level on the root logger is irrelevant since the filter is only accepting or denying events.
Related Topics
Sorting a List with Stream.Sorted() in Java
Directly Convert CSV File to JSON File Using the Jackson Library
What's in an Eclipse .Classpath/.Project File
What Are the Pros and Cons of Performing Calculations in SQL VS. in Your Application
Itext Merge Documents with Acrofields
Are There Best Practices for (Java) Package Organization
Java.Lang.Outofmemoryerror: Permgen Space
Are Non-Capturing Groups Redundant
Using Setvalueat to Recreate Mutually Exclusive Check Boxes
Validation of a List of Objects in Spring
Convert a String of Hex into Ascii in Java
Java Thread Priority Has No Effect
How Can My Java Program Store Files Inside of Its .Jar File
Appearance of Java Security Dialog
How to Configure JPA for Testing in Maven
Java: Jprogressbar (Or Equivalent) in a Jtabbedpane Tab Title