我有以下问题。我正在开发一个应用程序,它为所有记录器使用文件appender(log4j版本1.2)。一切正常,但现在我需要根据一些运行时参数登录到不同的文件。
作为限制,我还需要限制log4j.xml配置信息的数量,因为我事先不知道这个参数会占用多少个值,因此我无法配置不同的appender(FileAppenders)指向log4j配置文件中的不同文件。我还需要限制添加的新代码量,例如,可以将运行时参数作为记录器名称的一部分传递(LoggerFactory.getLogger(runtimeParameter + getClass)等),但我不想创建一个新的FileAppender按代码,然后将新的Appender添加到最近创建的记录器中(作为一个附带问题,这个替代方案会起作用吗?)。
我认为也许创建一个基于他提供的名称(基于运行时参数)打开不同文件的新appender会起作用,但我不知道该怎么做,我不知道它会怎样并发执行时的行为(因为它将是所有记录器的单个追加器)。
谢谢你,原谅我的英语!
答案 0 :(得分:0)
在您的情况下,听起来最简单的解决方法是以编程方式实时配置和创建记录器对象。
是的,它有效。幸运的是,我刚刚解决了这个问题,并提供了示例代码。这是针对log4j2的。我相信它在1.2
中更容易和直接/**
* Dynamically creates an instance of a Logger.
*
* @param appenderName
* most often will be the name of the class this logger will
* belong to.
* @param logFileName
* the file name to save the logs to
* @return
*/
public static org.apache.logging.log4j.Logger createInstanceLogger(String appenderName,
String logFileName) {
//call getLogger() which will create and load a logger with a default configuration
org.apache.logging.log4j.Logger logger = org.apache.logging.log4j.LogManager
.getLogger(String.format("DynamicLogger%s",
String.valueOf(DynamicLogManager.loggerCount++)));
org.apache.logging.log4j.core.Logger coreLogger = (org.apache.logging.log4j.core.Logger) logger; // cast logger to core logger to access protected methods
org.apache.logging.log4j.core.LoggerContext context = coreLogger.getContext();
org.apache.logging.log4j.core.config.BaseConfiguration configuration = (org.apache.logging.log4j.core.config.BaseConfiguration) context
.getConfiguration();
TriggeringPolicy compositePolicy = CompositeTriggeringPolicy.createPolicy(
SizeBasedTriggeringPolicy.createPolicy("5mb"),
TimeBasedTriggeringPolicy.createPolicy("1", "true"));
String fileName = String.format("%1$s/%2$s", appenderName, logFileName);
String filePattern = String.format("%1$s/%2$s.%%d{yyyy-MM-dd}",
appenderName, logFileName);
Layout<String> layout = PatternLayout.createLayout(DynamicLogManager._conversionPattern,
configuration, RegexReplacement.createRegexReplacement("a^", "."), //empty regex replacement
"utf-8", "false");
Filter f = ThresholdFilter.createFilter("trace", "accept", "accept");
Appender a = RollingFileAppender.createAppender(fileName, //fileName
filePattern, //filePattern
"true", //append
appenderName, //appender name
"true", //bufferred io
"true", //immediate flush
compositePolicy, //policy
null, //strategy default
layout, //layout
f, //filter none
"true", //ignore exceptions
"false", //advertise
"null", //advertise uri
configuration //configuration
);
a.start();
coreLogger.addAppender(a);
//this is where we would figure out how to configure the logger to listen on a configuration file
coreLogger.setLevel(Level.ALL); //set the log level of the logger that we are returning to Level.ALL
return coreLogger; //cast logger back to Logger interface