前言
程序有做到同时存在几个任务线程
如果只有一份日志,那么任务线程多了的话,日志信息就难以查找
因此我思考了了一下,如果每一个线程都存在自己的日志,那么就可以完美的解决这个问题
就像进程一样
首先需要自己创建一个Looger实例
我的需求主要是日志文件是新的就可以
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.ThreadSeperateDailyRollingFileAppender;
public class ThreadLogger
{
public static Logger getLogger(String logFile,Class clazz)
{
// 创建一个Logger实例, 就以线程名命名
Logger logger = Logger.getLogger(clazz);
PatternLayout layout = new PatternLayout("%-4r %-5p [%d{yyyy-MM-dd HH:mm:ss,SSS}] %l%t: %m%n");
// 文件输出
DailyRollingFileAppender appender= null;
try
{
appender = new DailyRollingFileAppender(layout, logfile,"'.'yyyy-MM-dd'.log'");
}
catch (IOException e)
{
e.printStackTrace();
}
logger.addAppender(appender);
return logger;
}
}
使用(简化),我觉得每个线程任务code是唯一的,因此打印的日志相同任务code的都是同一份日志文件
public class ThreadLog implements Runnable{
private String code;
private Logger logger;
ThreadLog (String code){
this.code = code;
logger = ThreadLogger.getLogger(code,ThreadLog .class);
}
run(){};
.........
}
结果
。。。。。。。
日志一片混乱,线程不安全,日志重复打印都出来了
上述结果最后定位
就是线程的问题,和重复打印没什么关系
- 原先我在声明logger的时候还是有加上static 关键字
后来又去掉了 - 后来我甚至加上了ThreadLocal 线程本地变量来声明logger
但是还是不行
最后慢慢的查找原因,发现Logger 他没有提供被被实例化的方法,只有通过工厂.getLogger()来获取实例,并且每一个名称相同的实例都是同一个
关键:每一个logger名称相同的实例都是同一个
所以想要线程独立日志,日志类logger的名称也得是惟一的
最后代码修改
public class ThreadLogger
{
public static Logger getLogger(String logFile,Class clazz)
{
// 创建一个Logger实例, 就以线程名命名
Logger logger = Logger.getLogger(logFile + clazz);
PatternLayout layout = new PatternLayout("%-4r %-5p [%d{yyyy-MM-dd HH:mm:ss,SSS}] %l%t: %m%n");
// 文件输出
DailyRollingFileAppender appender= null;
try
{
appender = new DailyRollingFileAppender(layout, logfile,"'.'yyyy-MM-dd'.log'");
}
catch (IOException e)
{
e.printStackTrace();
}
logger.addAppender(appender);
return logger;
}
}