用Log4j实现线程独立日志
(2012-11-16 17:16:39)需求:
思想:
具体代码:
自定义Appender
- package
threadlogger.appender; -
- import
java.io.File; - import
java.io.IOException; -
- import
org.apache.log4j.DailyRollingFileAppender ; - import
org.apache.log4j.Layout; -
-
- public
class ThreadSeperateDailyRolli ngFileAppender extends -
DailyRollingFileAppender - {
-
public ThreadSeperateDailyRolli ngFileAppender() {} -
-
public ThreadSeperateDailyRolli ngFileAppender(Layout layout, String datePattern) throws IOException -
{ -
// 改动只有这点:以线程名命名日志文件 -
super(layout, -
"log" + File.separator + Thread.currentThread().getName(), -
datePattern); -
} - }
- package
threadlogger; -
- import
java.io.IOException; -
- import
org.apache.log4j.ConsoleAppender; - import
org.apache.log4j.Level; - import
org.apache.log4j.Logger; - import
org.apache.log4j.PatternLayout; -
- import
threadlogger.appender.ThreadSeperateDailyRolli ngFileAppender; -
-
- public
class ThreadLogger - {
-
ThreadLogger() {}; -
-
public static Logger getLogger() -
{ -
Logger logger = null; -
// 创建一个Logger实例, 就以线程名命名 -
logger = Logger.getLogger(Thread.currentThread().getName()); -
-
PatternLayout layout = new PatternLayout("%-4r %-5p [%d{yyyy-MM-dd HH:mm:ss,SSS}] %l%t: %m%n"); -
-
// 控制台输出 -
ConsoleAppender concoleAppender = new ConsoleAppender(layout, "System.out"); -
-
// 文件输出 -
ThreadSeperateDailyRolli ngFileAppender R = null; -
try -
{ -
R = new ThreadSeperateDailyRolli ngFileAppender(layout, "'.'yyyy-MM-dd'.log'"); -
} -
catch (IOException e) -
{ -
e.printStackTrace(); -
} -
// 参数配置, 因为没有找到仅靠配置文件的办法, 只好放在这里设 -
R.setAppend(false); -
R.setImmediateFlush(true); -
R.setThreshold(Level.WARN); -
-
// 绑定到Logger -
logger.setLevel(Level.DEBUG); -
logger.addAppender(concoleAppender); -
logger.addAppender(R); -
-
return logger; -
} -
- }
- import
org.apache.log4j.Logger; -
- import
threadlogger.ThreadLogger; -
-
- public
class TestLog - {
-
// 这是主线程的Logger,这些不需独立日志的类也可以创建为普通的Logger,通过配置文件配置参数 -
static Logger logger = ThreadLogger.getLogger(); -
-
public TestLog() {} -
-
-
public static void main(String[] args) -
{ -
logger.warn(TestLog.class + " started!"); -
-
ThreadBody threadBody = new ThreadBody(); -
for(int i=0; i<</span>5; ++i) { -
new Thread(threadBody).start(); -
} -
-
logger.debug("this is debug"); -
logger.info("this is info"); -
logger.warn("this is warn"); -
logger.error("this is error"); -
} -
- }
-
- class
ThreadBody implements Runnable - {
-
public ThreadBody() {} -
-
-
@Override -
public void run() -
{ -
// 注意线程独立的Logger实例要在run方法内实现 -
Logger logger = ThreadLogger.getLogger(); -
-
logger.warn(Thread.currentThread().getName() + " started!"); -
-
logger.debug("this is debug"); -
logger.info("this is info"); -
logger.warn("this is warn"); -
logger.error("this is error"); -
-
logger.warn(Thread.currentThread().getName() + " finished!"); -
} -
- }
测试结果:
- 0
WARN [2012-11-05 14:31:40,227] testlog.TestLog.main(TestLog.java:21)main: class testlog.TestLog started! - 27
DEBUG [2012-11-05 14:31:40,254] testlog.TestLog.main(TestLog.java:28)main: this is debug - 27
INFO [2012-11-05 14:31:40,254] testlog.TestLog.main(TestLog.java:29)main: this is info - 27
WARN [2012-11-05 14:31:40,254] testlog.TestLog.main(TestLog.java:30)main: this is warn - 28
ERROR [2012-11-05 14:31:40,255] testlog.TestLog.main(TestLog.java:31)main: this is error - 30
WARN [2012-11-05 14:31:40,257] testlog.ThreadBody.run(TestLog.java:49)Thread-1: Thread-1 started! - 33
WARN [2012-11-05 14:31:40,260] testlog.ThreadBody.run(TestLog.java:49)Thread-0: Thread-0 started! - 36
WARN [2012-11-05 14:31:40,263] testlog.ThreadBody.run(TestLog.java:49)Thread-3: Thread-3 started! - 38
WARN [2012-11-05 14:31:40,265] testlog.ThreadBody.run(TestLog.java:49)Thread-2: Thread-2 started! - 40
DEBUG [2012-11-05 14:31:40,267] testlog.ThreadBody.run(TestLog.java:51)Thread-2: this is debug - 40
INFO [2012-11-05 14:31:40,267] testlog.ThreadBody.run(TestLog.java:52)Thread-2: this is info - 40
WARN [2012-11-05 14:31:40,267] testlog.ThreadBody.run(TestLog.java:53)Thread-2: this is warn - 41
ERROR [2012-11-05 14:31:40,268] testlog.ThreadBody.run(TestLog.java:54)Thread-2: this is error - 41
WARN [2012-11-05 14:31:40,268] testlog.ThreadBody.run(TestLog.java:56)Thread-2: Thread-2 finished! - 44
DEBUG [2012-11-05 14:31:40,271] testlog.ThreadBody.run(TestLog.java:51)Thread-3: this is debug - 46
INFO [2012-11-05 14:31:40,273] testlog.ThreadBody.run(TestLog.java:52)Thread-3: this is info - 46
WARN [2012-11-05 14:31:40,273] testlog.ThreadBody.run(TestLog.java:53)Thread-3: this is warn - 47
ERROR [2012-11-05 14:31:40,274] testlog.ThreadBody.run(TestLog.java:54)Thread-3: this is error - 47
WARN [2012-11-05 14:31:40,274] testlog.ThreadBody.run(TestLog.java:56)Thread-3: Thread-3 finished! - 38
WARN [2012-11-05 14:31:40,265] testlog.ThreadBody.run(TestLog.java:49)Thread-4: Thread-4 started! - 49
DEBUG [2012-11-05 14:31:40,276] testlog.ThreadBody.run(TestLog.java:51)Thread-1: this is debug - 50
INFO [2012-11-05 14:31:40,277] testlog.ThreadBody.run(TestLog.java:52)Thread-1: this is info - 50
WARN [2012-11-05 14:31:40,277] testlog.ThreadBody.run(TestLog.java:53)Thread-1: this is warn - 50
ERROR [2012-11-05 14:31:40,277] testlog.ThreadBody.run(TestLog.java:54)Thread-1: this is error - 50
WARN [2012-11-05 14:31:40,277] testlog.ThreadBody.run(TestLog.java:56)Thread-1: Thread-1 finished! - 50
DEBUG [2012-11-05 14:31:40,277] testlog.ThreadBody.run(TestLog.java:51)Thread-0: this is debug - 50
INFO [2012-11-05 14:31:40,277] testlog.ThreadBody.run(TestLog.java:52)Thread-0: this is info - 50
DEBUG [2012-11-05 14:31:40,277] testlog.ThreadBody.run(TestLog.java:51)Thread-4: this is debug - 50
WARN [2012-11-05 14:31:40,277] testlog.ThreadBody.run(TestLog.java:53)Thread-0: this is warn - 51
INFO [2012-11-05 14:31:40,278] testlog.ThreadBody.run(TestLog.java:52)Thread-4: this is info - 51
ERROR [2012-11-05 14:31:40,278] testlog.ThreadBody.run(TestLog.java:54)Thread-0: this is error - 51
WARN [2012-11-05 14:31:40,278] testlog.ThreadBody.run(TestLog.java:53)Thread-4: this is warn - 51
ERROR [2012-11-05 14:31:40,278] testlog.ThreadBody.run(TestLog.java:54)Thread-4: this is error - 51
WARN [2012-11-05 14:31:40,278] testlog.ThreadBody.run(TestLog.java:56)Thread-0: Thread-0 finished! - 51
WARN [2012-11-05 14:31:40,278] testlog.ThreadBody.run(TestLog.java:56)Thread-4: Thread-4 finished!
log4j.additivity是 子Logger 是否继承 父Logger 的 输出源(appender) 的标志位。具体说,默认情况下 子Logger 会继承 父Logger 的appender,也就是说 子Logger 会在 父Logger 的appender里输出。若是additivity设为false,则 子Logger 只会在自己的appender里输出,而不会在 父Logger 的appender里输出。
如:
log4j.rootLogger=INFO, stdout,logfile
log4j.logger.com.ambow.upgrade=INFO, dataSync
则com.ambow.upgrade包及其子包下的Logger不光在Appender dataSync里输出,也会在rootLogger的Appender stuout和logfile中输出;
若想让com.ambow.upgrade包及其子包下的Logger只在Appender dataSync中输出,则在log4j.properties中添加下行即可:
log4j.additivity.com.ambow.upgrade=false