原文:http://wenhai.iteye.com/blog/2037765
问题:
在进行多线程编程时,经常会在调试信息中看到线程的处理流程,需要在日志中体现当前线程信息。因Java中的线程名称采用了默认的“Thread-1”等字符串,定位不方便。
分析:
在JDK1.5开始对Thread类加入了getId()方法,即每个线程都有一个唯一的数字来代替。
在记录日志时,是否可以通过记录线程ID来提升日志线程信息的清晰度?
解决:
Log4j默认只提供了对线程名称的现实,即使用占位符%t来显示名称。
如果需要显示线程ID,需要拓展log4j。
1.拓展Log4j的PatternParser
代码:
- package org.apache.log4j;
- import org.apache.log4j.helpers.FormattingInfo;
- import org.apache.log4j.helpers.PatternConverter;
- import org.apache.log4j.helpers.PatternParser;
- import org.apache.log4j.spi.LoggingEvent;
- public class ExPatternParser extends PatternParser {
- public ExPatternParser(String pattern) {
- super(pattern);
- }
- /**
- * 重写finalizeConverter,对特定的占位符进行处理,T表示线程ID占位符
- */
- @Override
- protected void finalizeConverter(char c) {
- if (c == 'T') {
- this.addConverter(new ExPatternConverter(this.formattingInfo));
- } else {
- super.finalizeConverter(c);
- }
- }
- private static class ExPatternConverter extends PatternConverter {
- public ExPatternConverter(FormattingInfo fi) {
- super(fi);
- }
- /**
- * 当需要显示线程ID的时候,返回当前调用线程的ID
- */
- @Override
- protected String convert(LoggingEvent event) {
- return String.valueOf(Thread.currentThread().getId());
- }
- }
- }
2.拓展PatternLayout类,使用拓展的ExPatternParser类
代码:
- package org.apache.log4j;
- import org.apache.log4j.PatternLayout;
- import org.apache.log4j.helpers.PatternParser;
- public class ExPatternLayout extends PatternLayout {
- public ExPatternLayout(String pattern) {
- super(pattern);
- }
- public ExPatternLayout() {
- super();
- }
- /**
- * 重写createPatternParser方法,返回PatternParser的子类
- */
- @Override
- protected PatternParser createPatternParser(String pattern) {
- return new ExPatternParser(pattern);
- }
- }
3.修改Log4j的配置文件,将输出样式修改为拓展类ExPatternLayout
- #设置输出样式
- log4j.appender.appender1.layout=org.apache.log4j.ExPatternLayout
4.运行程序。