我使用以下log4j2配置:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5.5level %-60.60logger - %msg%n" />
<Filters>
<ThresholdFilter level="info" onMatch="ACCEPT"
onMismatch="DENY" />
</Filters>
</Console>
<RollingFile name="RollingFile"
fileName="${sys:log.file}"
filePattern="${sys:log.parent.path}\$${date:yyyy-MM}\${sys:log.file.name}-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout>
<Pattern>
%d{yyy-MM-dd HH:mm:ss.SSS} [%30.30t]%-10.10level%-60.60logger - %msg%n
</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="60 MB" />
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="RollingFile" />
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
当文件位置作为命令行参数传递时设置系统参数,然后函数reconfigureLog()设置属性
public static void reconfigureLog(String logPath)
{
File logFile = new File(logPath);
System.setProperty("log.file", logPath);
System.setProperty("log.parent.path", logFile.getParent());
System.setProperty("log.file.name", FilenameUtils.getBaseName(logFile.getName()));
org.apache.logging.log4j.core.Logger rootLogger = (org.apache.logging.log4j.core.Logger) LogManager
.getRootLogger();
LoggerContext context = rootLogger.getContext();
context.reconfigure();
}
这是我从命令行读取参数然后稍后设置的场景的示例用法。
if (cmd.hasOption("logFile"))
{
String logPath = cmd.getOptionValue("logFile");
Utility.reconfigureLog(logPath);
logger = LogManager.getLogger(Test.class);
}
每个类都有一个静态记录器初始化,如下所示:
private final static Logger logger = LogManager.getLogger(Connector.class);
问题是当我运行应用程序时,正在创建${sys.log.file}
,然后创建参数中的相应日志文件。通过参数进行推测,似乎会自动添加RolllingFile下的参数fileName。
log4j2的调试日志是:
2015-12-03 11:07:19,204 main DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.RollingFileAppender for element RollingFile with params(fileName="${sys:log.file}", filePattern="${sys:log.parent.path}\${date:yyyy-MM}\${sys:log.file.name}-%d{MM-dd-yyyy}-%i.log.gz", append="null", name="RollingFile", bufferedIO="null", bufferSize="null", immediateFlush="null", Policies(CompositeTriggeringPolicy(policies=[TimeBasedTriggeringPolicy(nextRolloverMillis=0, interval=1, modulate=false), SizeBasedTriggeringPolicy(size=62914560)])), null, PatternLayout(%d{yyy-MM-dd HH:mm:ss.SSS} [%30.30t]%-10.10level%-60.60logger - %msg%n), null, ignoreExceptions="null", advertise="null", advertiseURI="null", Configuration(<path>\Connector\target\classes\log4j2.xml))
2015-12-03 11:07:19,207 main DEBUG Starting RollingFileManager ${sys:log.file}
可以看出系统参数是字面上的选择而不是替换。我需要避免早期初始化并仅在调用reconfigureLog方法后启动此加载。
当我可以将系统参数用作应用程序的一部分时,如何避免创建${sys.log.file}
?
答案 0 :(得分:2)
只需使用$ {main: - value}查找替换$ {sys:value}查找。
http://logging.apache.org/log4j/2.x/manual/lookups.html#AppMainArgsLookup
将此功能与配置属性结合使用
http://logging.apache.org/log4j/2.x/manual/configuration.html#PropertySubstitution
你可以使用参数进行一些非常强大的配置,而无需接触代码。
从PropertySubstitution文档中密切注意这一点。
如果没有找到与查找关联的查找中的键的值 前缀然后是与属性中的键关联的值 将使用配置文件中的声明。如果没有价值 发现变量声明将作为值返回。默认 可以通过执行以下操作在配置中声明值:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Properties>
<Property name="--file">log_file_path</property>
</Properties>
...
</Configuration>
这意味着像${main:--file}
这样的配置查找将返回命令行参数--file如果它存在但是如果它不会返回属性声明中的默认值(我不确定是否有名称)属性需要是“file”或“--file”才能正确匹配)。如果您的目标是在启动时通过参数简单地设置日志文件,则不需要代码。