Configuring Log4j Loggers Programmatically
You can add/remove Appender programmatically to Log4j:
ConsoleAppender console = new ConsoleAppender(); //create appender
//configure the appender
String PATTERN = "%d [%p|%c|%C{1}] %m%n";
console.setLayout(new PatternLayout(PATTERN));
console.setThreshold(Level.FATAL);
console.activateOptions();
//add appender to any Logger (here is root)
Logger.getRootLogger().addAppender(console);
FileAppender fa = new FileAppender();
fa.setName("FileLogger");
fa.setFile("mylog.log");
fa.setLayout(new PatternLayout("%d %-5p [%c{1}] %m%n"));
fa.setThreshold(Level.DEBUG);
fa.setAppend(true);
fa.activateOptions();
//add appender to any Logger (here is root)
Logger.getRootLogger().addAppender(fa);
//repeat with all other desired appenders
I'd suggest you put it into an init() somewhere, where you are sure, that this will be executed before anything else.
You can then remove all existing appenders on the root logger with
Logger.getRootLogger().getLoggerRepository().resetConfiguration();
and start with adding your own. You need log4j in the classpath of course for this to work.
Remark:
You can take any Logger.getLogger(...)
you like to add appenders. I just took the root logger because it is at the bottom of all things and will handle everything that is passed through other appenders in other categories (unless configured otherwise by setting the additivity flag).
If you need to know how logging works and how is decided where logs are written read this manual for more infos about that.
In Short:
Logger fizz = LoggerFactory.getLogger("com.fizz")
will give you a logger for the category "com.fizz".
For the above example this means that everything logged with it will be referred to the console and file appender on the root logger.
If you add an appender to
Logger.getLogger("com.fizz").addAppender(newAppender)
then logging from fizz
will be handled by alle the appenders from the root logger and the newAppender
.
You don't create Loggers with the configuration, you just provide handlers for all possible categories in your system.
How to configure Logger Programmatically in log4j2.02?
The official documentation shows an example : Programatically Adding to the Current Configuration
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Configuration config = ctx.getConfiguration();
Layout layout = PatternLayout.createLayout(PatternLayout.SIMPLE_CONVERSION_PATTERN, config, null, null,null, null);
Appender appender = FileAppender.createAppender("target/test.log", "false", "false", "File", "true", "false", "false", "4000", layout, null, "false", null, config);
appender.start();
config.addAppender(appender);
AppenderRef ref = AppenderRef.createAppenderRef("File", null, null);
AppenderRef[] refs = new AppenderRef[] {ref};
LoggerConfig loggerConfig = LoggerConfig.createLogger("false", "info", "org.apache.logging.log4j", "true", refs, null, config, null );
loggerConfig.addAppender(appender, null, null);
config.addLogger("org.apache.logging.log4j", loggerConfig);
ctx.updateLoggers();
With these limitations :
- If the configuration file is changed the configuration will be reloaded and the manual changes will be lost.
- Modification to the running configuration requires that all the methods being called (addAppender and addLogger) be synchronized.
This solution avoids to use method from the core implementation org.apache.logging.log4j.core.Logger
, and it avoids dirty cast like that :
import org.apache.logging.log4j.Logger;
Logger logger = (Logger) LogManager.getLogger(this.getClass());
((org.apache.logging.log4j.core.Logger) logger).addAppender(...); // Bypassing the public API
Configuring a Logger Programmatically with Log4J 2?
You do this:
// 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);
See the FAQ: https://logging.apache.org/log4j/2.x/faq.html#reconfig_level_from_code
Gary
log4j - Programmatical configuration
Simple! After you create your third appender (C) get a logger for your namespace (darius.ws), set the INFO level for this logger. At the end just append this C appender to the logger.
FileAppender fileAppender = new FileAppender();
fileAppender.setName("C");
fileAppender.setFile("C.log");
fileAppender.setLayout(new PatternLayout("%d %-5p [%c{1}] %m%n"));
fileAppender.setThreshold(Level.INFO);
fileAppender.setAppend(true);
...
Logger someLogger = Logger.getLogger("darius.ws");
someLogger.setLevel(Level.INFO);
someLogger.addAppender(fileAppender);
Best regards
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.
How to configure log4j 2 to asynchonous mode programmatically?
If you can't use system property and log4j2.component.properties
file. You can try the ConfigurationFactory.setConfigurationFactory
method.
Here's a brief example:
Log4j2.java
public class Log4j2 {
static {
ConfigurationFactory.setConfigurationFactory(new CustomConfigurationFactory()); // This must be called before any other calls to Log4j
}
private static Logger logger = LogManager.getLogger();
public static void main(String[] args) {
logger.info("hello");
}
}
CustomConfigurationFactory.java
@Plugin(name = "CustomConfigurationFactory", category = ConfigurationFactory.CATEGORY)
@Order(50)
public class CustomConfigurationFactory extends ConfigurationFactory {
private static Configuration createConfiguration(final String name, ConfigurationBuilder<BuiltConfiguration> builder) {
builder.setConfigurationName(name);
AppenderComponentBuilder appenderBuilder = builder.newAppender("Stdout", "CONSOLE").
addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);
appenderBuilder.add(builder.newLayout("PatternLayout").
addAttribute("pattern", "%level: %msg%n"));
builder.add(appenderBuilder);
RootLoggerComponentBuilder rootLoggerBuilder = builder.newAsyncRootLogger(Level.DEBUG); // use newAsyncRootLogger instead of newRootLogger
rootLoggerBuilder.add(builder.newAppenderRef("Stdout"));
builder.add(rootLoggerBuilder);
return builder.build();
}
@Override
public Configuration getConfiguration(final LoggerContext loggerContext, final ConfigurationSource source) {
return getConfiguration(loggerContext, source.toString(), null);
}
@Override
public Configuration getConfiguration(final LoggerContext loggerContext, final String name, final URI configLocation) {
ConfigurationBuilder<BuiltConfiguration> builder = newConfigurationBuilder();
return createConfiguration(name, builder);
}
@Override
protected String[] getSupportedTypes() {
return new String[]{"*"};
}
}
Hope this helps :-)
Programmatically Configuring Log4J From Kotlin
Thanks for the helpful comments, guys. I was not aware that this was an ongoing issue. I have since mitigated it by dual-compiling Java and Kotlin in the project. Will close this once SO allows me to answer my own question.
Related Topics
How to Make a New List in Java
Android - How to Take Screenshot Programmatically
How to Use Okhttp to Upload a File
How to Get Timezone from Android Mobile
Android Layout with Listview and Buttons
Android Microsoft Office Library (.Doc, .Docx, .Xls, .Ppt, etc.)
Error Inflating Class Com.Google.Ads.Adview
Clearing and Setting the Default Home Application
Private Final Static Attribute VS Private Final Attribute
Getting Jsoup to Support Dynamically Generated HTML by JavaScript
Map.Clear() VS New Map:Which One Will Be Better
Asynctask.Executeonexecutor() Before API Level 11
How to Change Text of a Textview in Navigation Drawer Header
How to Avoid Garbage Collection Delays in Java Games? (Best Practices)
Android Telegram App --> Java.Lang.Unsatisfiedlinkerror: No Implementation Found for Void