Log4j 动态日志分流

使用场景

在项目运维时候需要监控特定的Logger的输出的日志,比如只查看名称为 com.mylogger Logger 输出的日志,一般情况下多个Logger都会输出到同一个文件当中,如果从磁盘上的文件检索获取比较繁琐,并且不便于查看,在程序中实现对指定的Logger日志分流,比如使用com.logger Logger 另外在输出一份日志到指定的文件下,这样查看起来就比较方便,并且在不需要的时候还可以关闭分流功能。

实现方案

Log4j有完善的配置Logge Api,通过Api动态的为指定Logger增加Appender从而实现日志分流的功能。

示例代码

创建Logger

Logger 可以使用Propteies , XML 文件格式创建,这里为了熟悉使用API,特意使用API的模式创建Logger。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public static Logger getLoggerByName(String name) {
// 生成新的Logger
// 如果已经有了一个Logger实例返回現有的
Logger logger = Logger.getLogger(name);
// 清空Appender。特別是不想使用現存实例时一定要初期化
logger.removeAllAppenders();
// 设定Logger级別。
logger.setLevel(Level.DEBUG);
// 设定是否继承父Logger。
// 默认为true。继承root輸出。
// 设定false后将不输出root。
logger.setAdditivity(true);
// 生成新的Appender
RollingFileAppender appender = new RollingFileAppender();
appender.setName("myappender");
PatternLayout layout = new PatternLayout();
// log的输出形式
String conversionPattern = "[%d{yy/MM/dd HH:mm:ss:SSS}] [%p] [%c-%t] %m%n";
layout.setConversionPattern(conversionPattern);
appender.setLayout(layout);
// log输出路径
appender.setFile("c:/" + "/logs/" + name + ".log");
// log的文字码
appender.setEncoding("UTF-8");
//设定log文件大小和备份数量
appender.setMaxFileSize("1024KB");
appender.setMaxBackupIndex(1);
// true:在已存在log文件后面追加 false:新log覆盖以前的log
appender.setAppend(true);
// 适用当前配置
appender.activateOptions();
// 将新的Appender加到Logger中
logger.addAppender(appender);
return logger;
}

使用API 动态的增加Appender

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public static void addCustomLogger(String name) {
/**
* Logger logger = Logger.getLogger(name); 如果不存在会创建新的Logger,以下方法不会创建
* 只会返回已有的
*/
Logger logger = Logger.getRootLogger().getLoggerRepository().exists(name);
if(logger != null){
RollingFileAppender appender = new RollingFileAppender();
PatternLayout layout = new PatternLayout();
// log的输出形式
String conversionPattern = "[%d{yy/MM/dd HH:mm:ss:SSS}] [%p] [%c-%t] %m%n";
layout.setConversionPattern(conversionPattern);
appender.setLayout(layout);
appender.setName("Custom");
// log输出路径
appender.setFile("c:/" + "/logs/Custom.log");
// log的文字码
appender.setEncoding("UTF-8");
//设定log文件大小和备份数量
appender.setMaxFileSize("1024KB");
appender.setMaxBackupIndex(1);
// true:在已存在log文件后面追加 false:新log覆盖以前的log
appender.setAppend(true);
// 适用当前配置
appender.activateOptions();
// 将新的Appender加到Logger中
logger.addAppender(appender);
}
}

删除Appender

在不需要的删除Appender

1
2
3
4
5
6
public static void removeCustomLogger(String name){
Logger logger = Logger.getRootLogger().getLoggerRepository().exists(name);
if(logger != null){
logger.removeAppender("Custom");
}
}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void main(String[] args) {
Logger logger = getLoggerByName("com.mylogger");
for(int i = 0 ; i< 100 ; i++){
logger.debug(i + " message");
}

addCustomLogger("com.mylogger");
for(int i = 0 ; i< 100 ; i++){
logger.debug(i + "Custom message");
}
removeCustomLogger("com.mylogger");

for(int i = 0 ; i< 100 ; i++){
logger.debug(i + "Removed message");
}
}