- 浏览: 72520 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
须等待:
强烈同意。。。。这个编辑器简直太不好用了!
对于在Ubuntu下的Eclipse上安装SVN客户端插件Subclipse的补充 -
nudtgk2000:
flysnail 写道 思路挺好,
谢谢鼓励,还是初学者,不 ...
重写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 776获取类文件所在的绝对路径 写道 "Jav ... -
重写CountDownLatch以实现线程状态监视
2012-11-04 20:25 1505需求:管理线程需要及时知道工作线程全部处于等待状态,并满足等待 ... -
byte型检查
2012-09-09 21:14 798byte b; //... ... // 范围检查,确保只 ... -
【转】Dom4j的使用(全而好的文章)
2012-08-07 15:09 938java解析xml汇总, 结论就是Dom4j比其他几种好 ... -
【转】正则表达式的一些资料
2012-08-07 15:07 846JAVA 正则表达式 (超详细)http://blog.csd ... -
【转摘】Exception in thread "main" java.lang.OutOfMemoryError: Java heap space解决方法
2012-08-04 18:02 14915摘自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 1241容器 概念 Java API 所提供的用于在程序中 ... -
走了一段值得的弯路
2012-03-16 21:27 1043class C { int i; S ... -
马士兵课程笔记(续5)
2012-03-09 19:28 1439常用类 字符串相关类(String, StringBuff ... -
马士兵课程笔记(续4)
2012-02-28 21:58 1122数组 数组可以看成是多个相同类型数据组合,对这些数据的统一 ... -
马士兵课程笔记(续3)
2012-02-22 16:47 1488抽象类 关键字abstract 含有抽象方法的类必须声明 ... -
马士兵课程笔记(续2)
2012-01-03 15:50 1128J2SDK中主要的包介绍 位置%JAVAHOME%\jr ... -
马士兵课程笔记
2011-11-14 07:47 1259J2EE框架 EJB (Enterprise Ja ... -
JAVA中 @Override 的作用(转)
2011-10-22 22:44 2560<!-- @pa ...
相关推荐
在“Log4j2实现不同线程不同级别日志输出到不同的文件中”这个主题中,我们将深入探讨如何利用Log4j2实现这一高级日志管理需求。 1. **日志级别**: - 在Log4j2中,日志级别包括DEBUG、INFO、WARN、ERROR、FATAL...
Log4j是一款广泛使用的Java日志记录框架,它允许开发者按照功能模块或特定需求记录应用程序运行过程中的事件信息。在“log4j按功能保存日志”的场景中,我们通常会利用Log4j的配置灵活性,将不同功能的日志分别写入...
- 通过正确配置和使用Log4j,我们可以在多线程环境中实现每个线程独立的日志输出,这对于调试、性能分析和问题定位非常有帮助。 - `LogTest`项目提供了一个实用的例子,演示了如何在实践中应用这些概念,有助于...
Log4j提供了一个根Logger,也支持自定义Logger,以实现不同模块的独立日志管理。 6. **Filters**:过滤器允许更精细地控制哪些日志信息会被记录。你可以根据日志级别、日志源或其他条件来过滤日志。 7. **Lookups*...
在IT行业中,日志记录是系统监控和故障排查的关键部分,而Log4j作为Java领域广泛使用的日志框架,能够帮助开发者实现灵活、高效的日志处理。本文将深入探讨如何利用Log4j实现多线程环境下读取多个配置文件,以达到...
深入研究Log4j 1.2.16的源代码,你可以了解到如何实现日志事件的线程安全处理,以及如何优化日志性能,比如通过缓存日志输出格式来减少不必要的字符串连接操作。此外,源码中还包含了一些关键的类,如Category...
Log4j,作为Java领域中最广泛使用的日志记录框架之一,其强大的功能和灵活性深受开发者喜爱。本文将详细介绍Log4j的基本概念、配置和使用,以及如何将其融入自定义的日志记录工具中。 1. **Log4j简介** - Log4j是...
Log4j2 支持日志分离,即在一个应用程序中使用多个独立的日志记录配置: - **Separate ClassLoaders**:使用不同的类加载器隔离日志配置。 - **Separate Contexts**:每个配置使用独立的 LoggerContext。 #### 15....
标题中的"ssh+aop+log4j+日志拦截器+注解"涉及到的是Java Web开发中的几个核心组件和技术,这些技术在构建大型、分布式的企业级应用时常常被使用。下面将详细介绍这些知识点: 1. SSH (Spring, Struts, Hibernate)...
Log4j 是一个广泛使用的日志记录框架,尤其在Java应用程序中。它的核心在于灵活性和可配置性,允许开发者按照需求定制日志记录的方式。在Log4j.properties配置文件中,我们可以通过设置Logger、Appender和Layout来...
它最初是作为Jakarta项目的一部分出现的,随着时间的发展,Log4j逐渐成为了一个独立且功能强大的日志解决方案。Log4j的设计理念是灵活与高效,它允许开发者轻松地配置日志输出的位置、格式以及级别。 #### 日志的...
Log4j是一款广泛使用的Java日志记录框架,它允许开发者以灵活的方式控制程序的日志输出。在Java应用程序中,日志记录是至关重要的,因为它帮助我们跟踪错误、调试代码、监控系统性能以及进行安全审计。Log4j因其高度...
除了基本的日志功能,log4j-1.2.15还支持一些高级特性,如异步日志记录(使用AsyncAppender)、日志事件的自定义处理(通过编写自定义Appender和Layout)、MDC(Mapped Diagnostic Context)和NDC(Nested ...
在Java开发领域,Spring Boot是一个...通过引入Log4j依赖,配置日志输出格式和级别,以及在代码中使用`Logger`接口,我们可以实现高效且易于管理和分析的日志系统。这在开发、调试和维护Spring Boot应用时非常有用。
Log4Qt,顾名思义,是Apache Log4J日志框架的一个Qt实现,为Qt应用程序提供了强大的日志处理功能。由于Log4Qt的文档相对较少,理解其工作原理和用法往往需要参考Log4J的资料。本文将深入探讨Log4Qt的核心概念、配置...
Log4j是一款广泛使用的日志框架,它允许我们自定义日志级别、格式以及输出目的地。本文将围绕`log4j.properties`配置文件,探讨其基本用法和重要概念。 一、Log4j的基本结构 Log4j主要由三个核心组件构成:Logger...
### log4j常用配置详解 ### #### 一、log4j.properties 配置解析 #### 在Java开发领域中,log4j是一款非常流行的日志框架,它提供了丰富的配置选项来满足...希望本文能帮助大家更好地理解和使用log4j进行日志管理。
5. **多线程支持**:Log4j在多线程环境下表现稳定,每个线程都有独立的日志记录对象,避免了同步开销。 6. **日志级别**:Log4j提供了TRACE、DEBUG、INFO、WARN、ERROR和FATAL六种日志级别,可以根据需要调整日志...
Log4j 是一个广泛使用的 Java 日志框架,由 Apache 软件基金会开发。它为应用程序提供了灵活的日志记录功能,允许开发者调整日志级别,定制日志格式,以及将日志输出到不同的目的地,如控制台、文件、数据库等。...