在appender输出的过程中,还可以同时指定输出的格式
通过代码:
String layoutPrefix = prefix + ".layout";
配置:
log4j.appender.console.layout=org.apache.log4j.SimpleLayout
通过log4j.rootLogger继续在类中搜索
找到void configureRootCategory方法
在这个方法中执行了this.parseCategory方法
观察该方法:
找打代码StringTokenizer st = new StringTokenizer(value, ",");
表示要以逗号的方式来切割字符串,证明了log4j.rootLogger的取值,其中可以有多个值,使用逗号进行分隔
通过代码:
String levelStr = st.nextToken();
表示切割后的第一个值是日志的级别
通过代码:
while(st.hasMoreTokens())
表示接下来的值,是可以通过while循环遍历得到的
第2~第n个值,就是我们配置的其他的信息,这个信息就是appenderName
证明了我们配置的方式
log4j.rootLogger=日志级别,appenderName1,appenderName2,appenderName3....
表示可以同时在根节点上配置多个日志输出的途径
通过我们自己的配置文件,就可以将原有的加载代码去除掉了
void parseCategory(Properties props, Logger logger, String optionKey, String loggerName, String value) {
LogLog.debug("Parsing for [" + loggerName + "] with value=[" + value + "].");
StringTokenizer st = new StringTokenizer(value, ",");
if (!value.startsWith(",") && !value.equals("")) {
if (!st.hasMoreTokens()) {
return;
}
String levelStr = st.nextToken();
LogLog.debug("Level token is [" + levelStr + "].");
if (!"inherited".equalsIgnoreCase(levelStr) && !"null".equalsIgnoreCase(levelStr)) {
logger.setLevel(OptionConverter.toLevel(levelStr, Level.DEBUG));
} else if (loggerName.equals("root")) {
LogLog.warn("The root logger cannot be set to null.");
} else {
logger.setLevel((Level)null);
}
LogLog.debug("Category " + loggerName + " set to " + logger.getLevel());
}
logger.removeAllAppenders();
while(st.hasMoreTokens()) {
String appenderName = st.nextToken().trim();
if (appenderName != null && !appenderName.equals(",")) {
LogLog.debug("Parsing appender named \"" + appenderName + "\".");
Appender appender = this.parseAppender(props, appenderName);
if (appender != null) {
logger.addAppender(appender);
}
}
}
}