- 浏览: 71208 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
须等待:
强烈同意。。。。这个编辑器简直太不好用了!
对于在Ubuntu下的Eclipse上安装SVN客户端插件Subclipse的补充 -
nudtgk2000:
<div class="quote_title ...
重写CountDownLatch以实现线程状态监视 -
flysnail:
思路挺好,:)
重写CountDownLatch以实现线程状态监视
需求:
在一个项目里,我使用Log4j生成日志,我不希望任务线程组各个线程都记录在同一个日志里,那样太乱了,而是单独生成日志记录。这样的话,需要针对每个线程创建Logger实例,实例名应对应线程名,而每个Logger实例的文件名应分别对应于实例名或者线程名。
思想:
在网上搜了很多文章后,我还是找不到在配置文件里根据Logger实例以变量形式设置动态File的方法。那么只能打源码的主意了。打开 org.apache.log4j.DailyRollingFileAppender 的源码简单分析了一下:DailyRollingFileAppender 继承了FileAppender类,它个构造方法是DailyRollingFileAppender (Layout layout, String filename, String datePattern),那么可以写个自定义的Appender继承DailyRollingFileAppender,在构造方法里直接将filename设成当前线程名;再将Appender、layout的参数设置及与Logger的绑定封装在一个静态方法里就可以达到目的了。
具体代码:
自定义Appender
package threadlogger.appender; import java.io.File; import java.io.IOException; import org.apache.log4j.DailyRollingFileAppender; import org.apache.log4j.Layout; /** * @author Kevin Kwok */ public class ThreadSeperateDailyRollingFileAppender extends DailyRollingFileAppender { public ThreadSeperateDailyRollingFileAppender() {} public ThreadSeperateDailyRollingFileAppender(Layout layout, String datePattern) throws IOException { // 改动只有这点:以线程名命名日志文件 super(layout, "log" + File.separator + Thread.currentThread().getName(), datePattern); } }
封装获得线程独立日志的Logger实例的类:
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.ThreadSeperateDailyRollingFileAppender; /** * @author Kevin Kwok */ 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"); // 文件输出 ThreadSeperateDailyRollingFileAppender R = null; try { R = new ThreadSeperateDailyRollingFileAppender(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; } }
测试例程:package testlog;
import org.apache.log4j.Logger; import threadlogger.ThreadLogger; /** * @author Kevin Kwok */ public class TestLog { // 这是主线程的Logger,这些不需独立日志的类也可以创建为普通的Logger,通过配置文件配置参数 static Logger logger = ThreadLogger.getLogger(); public TestLog() {} /** * @param args */ public static void main(String[] args) { logger.warn(TestLog.class + " started!"); ThreadBody threadBody = new ThreadBody(); for(int i=0; i<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() {} /* (non-Javadoc) * @see java.lang.Runnable#run() */ @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!
同时,log文件夹下出现了main、Thread-0~Thread-4五个日志文件,记录了各自线程的信息。
参考:
- End -
发表评论
-
【转】常用的系统属性
2012-11-21 17:02 743获取类文件所在的绝对路径 写道 "Jav ... -
重写CountDownLatch以实现线程状态监视
2012-11-04 20:25 1467需求:管理线程需要及时知道工作线程全部处于等待状态,并满足等待 ... -
byte型检查
2012-09-09 21:14 761byte b; //... ... // 范围检查,确保只 ... -
【转】Dom4j的使用(全而好的文章)
2012-08-07 15:09 908java解析xml汇总, 结论就是Dom4j比其他几种好 ... -
【转】正则表达式的一些资料
2012-08-07 15:07 818JAVA 正则表达式 (超详细)http://blog.csd ... -
【转摘】Exception in thread "main" java.lang.OutOfMemoryError: Java heap space解决方法
2012-08-04 18:02 14846摘自http://hi.baidu.com/61919 ... -
【转】java解析xml汇总
2012-07-31 20:53 16java解析xml汇总 -
java.io.InputStream.mark(int readlimit) 方法的个人理解
2012-05-16 16:04 0在马士兵java课程的IO这一章[1]中遇到 java.io ... -
马士兵课程笔记(续7) —— 流
2012-03-20 18:51 0Java 流式输入/输出原理 ... -
马士兵课程笔记(续6)
2012-03-18 18:31 1207容器 概念 Java API 所提供的用于在程序中 ... -
走了一段值得的弯路
2012-03-16 21:27 1013class C { int i; S ... -
马士兵课程笔记(续5)
2012-03-09 19:28 1408常用类 字符串相关类(String, StringBuff ... -
马士兵课程笔记(续4)
2012-02-28 21:58 1083数组 数组可以看成是多个相同类型数据组合,对这些数据的统一 ... -
马士兵课程笔记(续3)
2012-02-22 16:47 1432抽象类 关键字abstract 含有抽象方法的类必须声明 ... -
马士兵课程笔记(续2)
2012-01-03 15:50 1089J2SDK中主要的包介绍 位置%JAVAHOME%\jr ... -
马士兵课程笔记
2011-11-14 07:47 1222J2EE框架 EJB (Enterprise Ja ... -
JAVA中 @Override 的作用(转)
2011-10-22 22:44 2530<!-- @pa ...
相关推荐
Log4j2实现不同线程不同级别日志输出到不同的文件中 源码+log4j jar包
使用log4j2实现日志数据脱敏
log4j按功能保存日志
最近写的demo。安卓环境使用log4j 滚动日志。 实现数据format格式化传输记录日志内容。 非配置文件的方式
log4j+slf4j实现 log4j测试代码,log4j+slf4j实现 log4j测试代码,
log4j中配置日志文件相对路径方法分析 方法一、 解决的办法自然是用相对路径代替绝对路径,其实log4j的FileAppender本身就有这样的机制,如:log4j.appender.logfile.File=${WORKDIR}/logs/app.log 其中“${...
博文“Log4j多线程实践”中测试工程的源码,利用log4j实现每个子线程独立输出日志文件。
1.该工程为maven构建,要有maven环境 2.支持异步打印 3.支持多线程打印
Kafka及Log4j实现日志集中管理功能的相关程序代码,了解kafka工作原理
参照了几个网上大神配置,部分教程的描述有误,最终调试完成,可以实现kettle日志输出,测试版本...需要替换的文件为,Kettle的程序目录下data-integration-6.0\plugins\kettle5-log4j-plugin中有一个log4j.xml文件。
每天生成一个log4j日志文件,如果只需要将最近一段时间内的日志文件保留,以前或更早的文件不用保留。例如只保留最近一周的日志,日志文件保留3天等等这些。。。通过这个jar包就可以实现。 log4j.properties文件在...
演示了java记录通过log4j2记录日志到mysql数据库中
详细介绍了log4j的使用方法,介绍了java中日志记录如何写入数据库,对于初学者来说很不错的一个文档
对Log4j2异步写日志的效率测试源码
若依框架使用的log4j2.16.0,修复log4j漏洞log4j2下载最新log4j2.16.0下载
根据项目需要,要求日志文件名及输出的日志内容头为特殊的格式,因此重写了log4j的一些方法,如要求的格式和项目不同,可根据示例参考进行再次的修改
log4j2配置文件,按照文件大小划分日志,保存日期天数内的日志,指纹日志命名规则,日志输出等级等功能
log4j.rootLogger=debug,CONSOLE,testfile,A1,MAIL ################### # Console Appender ################### log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.Target=...
使用Slf4j集成Log4j2构建项目日志系统的完美解决方案.docx