1. 程式人生 > >Log4j 不同的包輸出到不同的檔案

Log4j 不同的包輸出到不同的檔案

        今天想做個小專案,用quartz啟動兩個自動作業,因為以後還要有很多自動作業要新增進來,所以考慮不把日誌輸出到一個檔案,而是每個自動作業Log輸出到獨立的一個檔案,每個自動作業放在不同的java包裡,用包來配置log4j。問題來了,當我在 log4j.rootLogger 裡配置兩個不同包的log時,這兩個log總是輸出到自己以及到對方配置的檔案裡,如:

log4j.properties:

log4j.rootLogger=info, zeng.quartz , zeng.quartz2

log4j.appender.zeng.quartz=org.apache.log4j.DailyRollingFileAppender   
log4j.appender.zeng.quartz.File=../quartzLog/log/log1.log


log4j.appender.zeng.quartz.MaxFileSize=10KB  
log4j.appender.zeng.quartz.MaxBackupIndex=4
log4j.appender.zeng.quartz.layout=org.apache.log4j.PatternLayout
log4j.appender.zeng.quartz.DatePattern  ='.'yyyy-MM-dd
log4j.appender.zeng.quartz.Threshold = DEBUG
log4j.appender.zeng.quartz.layout.ConversionPattern= %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
#log4j.additivity.zeng.quartz=false

log4j.appender.zeng.quartz2=org.apache.log4j.DailyRollingFileAppender   
log4j.appender.zeng.quartz2.File=../quartzLog/log/log2.log
log4j.appender.zeng.quartz2.MaxFileSize=10KB  
log4j.appender.zeng.quartz2.MaxBackupIndex=4
log4j.appender.zeng.quartz2.layout=org.apache.log4j.PatternLayout
log4j.appender.zeng.quartz2.DatePattern  ='.'yyyy-MM-dd
log4j.appender.zeng.quartz2.Threshold = DEBUG
log4j.appender.zeng.quartz2.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
#log4j.additivity.zeng.quartz2=false

java:

package <span style="color:#FF0000;">zeng.quartz</span>;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.log4j.Logger;

/**
 * @author Zeng 2016-4-24
 */
public class MyQuartz1 {
	private transient static final Logger logger = Logger
			.getLogger(MyQuartz1.class);
//	private transient static final Logger logger = Logger
//			.getLogger("zeng.quartz.MyQuartz1");
	private static final String OUT_PATH = "C:\\Users\\Administrator\\Desktop\\QuartzLog.txt";
	private static final String RN = "\n";
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	public void beginTask() throws Exception {
		logger.info("Task MyQuartz1 begin!");
		try {
			File f = new File(OUT_PATH);
			logger.info("File path: " + OUT_PATH);
			BufferedWriter bw = new BufferedWriter(new FileWriter(f, true));
			bw.write(sdf.format(new Date()) + RN);
			bw.close();
			logger.info("Already wrote to file");
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		logger.info("Task MyQuartz1 end!");
	}
}

package <span style="color:#FF0000;">zeng.quartz2</span>;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.log4j.Logger;

/**
 * @author Zeng
 * 2016-4-24
 */
public class MyQuartz2 {
	private transient static final Logger logger = Logger
			.getLogger(MyQuartz2.class);
//	private transient static final Logger logger = Logger
//			.getLogger("zeng.quartz2.MyQuartz2");
	private static final String OUT_PATH = "C:\\Users\\Administrator\\Desktop\\QuartzLog2.txt";
	private static final String RN = "\n";
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	public void beginTask() throws Exception {
		logger.info("Task MyQuartz2 begin!");
		try {
			File f = new File(OUT_PATH);
			logger.info("File path: " + OUT_PATH);
			BufferedWriter bw = new BufferedWriter(new FileWriter(f, true));
			bw.write(sdf.format(new Date()) + RN);
			bw.close();
			logger.info("Already wrote to file");
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		logger.info("Task MyQuartz2 end!");
	}
}

這樣配置的話,
MyQuartz1 
的log會打到log1.loglog2.log裡!:

2016-04-24 15:32:00  [ schedule_Worker-1:9817 ] - [ INFO ]  Task MyQuartz1 begin!
2016-04-24 15:32:00  [ schedule_Worker-1:9819 ] - [ INFO ]  File path: C:\Users\Administrator\Desktop\QuartzLog.txt
2016-04-24 15:32:00  [ schedule_Worker-2:9818 ] - [ INFO ]  Task MyQuartz2 begin!
2016-04-24 15:32:00  [ schedule_Worker-2:9819 ] - [ INFO ]  File path: C:\Users\Administrator\Desktop\QuartzLog2.txt
2016-04-24 15:32:00  [ schedule_Worker-1:9820 ] - [ INFO ]  Already wrote to file
2016-04-24 15:32:00  [ schedule_Worker-2:9821 ] - [ INFO ]  Already wrote to file
2016-04-24 15:32:00  [ schedule_Worker-1:9821 ] - [ INFO ]  Task MyQuartz1 end!
2016-04-24 15:32:00  [ schedule_Worker-2:9821 ] - [ INFO ]  Task MyQuartz2 end!

MyQuartz2 
的log也會打到log1.loglog2.log裡!:

2016-04-24 15:32:00  [ schedule_Worker-1:9817 ] - [ INFO ]  Task MyQuartz1 begin!
2016-04-24 15:32:00  [ schedule_Worker-1:9819 ] - [ INFO ]  File path: C:\Users\Administrator\Desktop\QuartzLog.txt
2016-04-24 15:32:00  [ schedule_Worker-2:9818 ] - [ INFO ]  Task MyQuartz2 begin!
2016-04-24 15:32:00  [ schedule_Worker-2:9819 ] - [ INFO ]  File path: C:\Users\Administrator\Desktop\QuartzLog2.txt
2016-04-24 15:32:00  [ schedule_Worker-1:9820 ] - [ INFO ]  Already wrote to file
2016-04-24 15:32:00  [ schedule_Worker-2:9821 ] - [ INFO ]  Already wrote to file
2016-04-24 15:32:00  [ schedule_Worker-1:9821 ] - [ INFO ]  Task MyQuartz1 end!
2016-04-24 15:32:00  [ schedule_Worker-2:9821 ] - [ INFO ]  Task MyQuartz2 end!

原因是我把 log4j.rootLogger=info, zeng.quartz , zeng.quartz2 中的 zeng.quartz , zeng.quartz2 配置到了 rootLogger 裡了,而 rootLogger 作為跟Log, 裡面配置的所有log都會互通的,就是說Java裡取到的Logger例項如果屬於 rootLogger ,用這個例項打的log,也會打到 rootLogger 其他例項裡。具體到我的例子就是,我在

MyQuartz1
private transient static final Logger logger = Logger
			.getLogger(MyQuartz1.class);
拿到的這個 logger,是配置在 rootLogger 裡的,當我用這個logger打
logger.info("Task MyQuartz1 begin!");
這條資訊時,

這個log打到 zeng.quartz 配置的 log1.log裡。

然後發現rootLogger 裡還有 zeng.quartz2 這個配置,就又把

logger.info("Task MyQuartz1 begin!");
這個log打到 zeng.quartz2 配置的 log2.log裡。


於是 log1.log 和  log2.log 都有了這條資訊。  

MyQuartz2
裡打的log同理。

因為

MyQuartz1
MyQuartz2
同時啟動,所以會有上面一個log檔案裡並行打log的效果。

解決:

不把自定義的log配置到rootLogger 裡,自定義的log用 log4j.logger 來定義:

log4j.properties:


log4j.rootLogger=info, stdout, rootFile

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d-[quartzProject] %p %m%n

log4j.appender.rootFile=org.apache.log4j.DailyRollingFileAppender   
log4j.appender.rootFile.File=../quartzLog/log/root.log
log4j.appender.rootFile.MaxFileSize=10KB  
log4j.appender.rootFile.MaxBackupIndex=4
log4j.appender.rootFile.layout=org.apache.log4j.PatternLayout
log4j.appender.rootFile.DatePattern  ='.'yyyy-MM-dd
log4j.appender.rootFile.Threshold = DEBUG
log4j.appender.rootFile.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

log4j.logger.zeng.quartz=DEBUG,zeng.quartz   
log4j.appender.zeng.quartz=org.apache.log4j.DailyRollingFileAppender   
log4j.appender.zeng.quartz.File=../quartzLog/log/log1.log
log4j.appender.zeng.quartz.MaxFileSize=10KB  
log4j.appender.zeng.quartz.MaxBackupIndex=4
log4j.appender.zeng.quartz.layout=org.apache.log4j.PatternLayout
log4j.appender.zeng.quartz.DatePattern  ='.'yyyy-MM-dd
log4j.appender.zeng.quartz.Threshold = DEBUG
log4j.appender.zeng.quartz.layout.ConversionPattern= %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
#log4j.additivity.zeng.quartz=false

log4j.logger.zeng.quartz2=DEBUG,zeng.quartz2
log4j.appender.zeng.quartz2=org.apache.log4j.DailyRollingFileAppender   
log4j.appender.zeng.quartz2.File=../quartzLog/log/log2.log
log4j.appender.zeng.quartz2.MaxFileSize=10KB  
log4j.appender.zeng.quartz2.MaxBackupIndex=4
log4j.appender.zeng.quartz2.layout=org.apache.log4j.PatternLayout
log4j.appender.zeng.quartz2.DatePattern  ='.'yyyy-MM-dd
log4j.appender.zeng.quartz2.Threshold = DEBUG
log4j.appender.zeng.quartz2.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
#log4j.additivity.zeng.quartz2=false

log4j.logger.org.springframework=ERROR
log4j.logger.org.hibernate=ERROR
log4j.logger.org.hibernate.ps.PreparedStatementCache=ERROR

這樣就是預期的那樣打log:

log1.log

2016-04-24 15:32:00  [ schedule_Worker-1:9817 ] - [ INFO ]  Task MyQuartz1 begin!
2016-04-24 15:32:00  [ schedule_Worker-1:9819 ] - [ INFO ]  File path: C:\Users\Administrator\Desktop\QuartzLog.txt
2016-04-24 15:32:00  [ schedule_Worker-1:9820 ] - [ INFO ]  Already wrote to file
2016-04-24 15:32:00  [ schedule_Worker-1:9821 ] - [ INFO ]  Task MyQuartz1 end!

log2.log

2016-04-24 15:32:00  [ schedule_Worker-2:9818 ] - [ INFO ]  Task MyQuartz2 begin!
2016-04-24 15:32:00  [ schedule_Worker-2:9819 ] - [ INFO ]  File path: C:\Users\Administrator\Desktop\QuartzLog2.txt
2016-04-24 15:32:00  [ schedule_Worker-2:9821 ] - [ INFO ]  Already wrote to file
2016-04-24 15:32:00  [ schedule_Worker-2:9821 ] - [ INFO ]  Task MyQuartz2 end!

root.log:

2016-04-24 15:32:00  [ schedule_Worker-1:9817 ] - [ INFO ]  Task MyQuartz1 begin!
2016-04-24 15:32:00  [ schedule_Worker-1:9819 ] - [ INFO ]  File path: C:\Users\Administrator\Desktop\QuartzLog.txt
2016-04-24 15:32:00  [ schedule_Worker-2:9818 ] - [ INFO ]  Task MyQuartz2 begin!
2016-04-24 15:32:00  [ schedule_Worker-2:9819 ] - [ INFO ]  File path: C:\Users\Administrator\Desktop\QuartzLog2.txt
2016-04-24 15:32:00  [ schedule_Worker-1:9820 ] - [ INFO ]  Already wrote to file
2016-04-24 15:32:00  [ schedule_Worker-2:9821 ] - [ INFO ]  Already wrote to file
2016-04-24 15:32:00  [ schedule_Worker-1:9821 ] - [ INFO ]  Task MyQuartz1 end!
2016-04-24 15:32:00  [ schedule_Worker-2:9821 ] - [ INFO ]  Task MyQuartz2 end!