对于Log4J日志信息的优化、读取与分析  2008-09-30   Java  

通过日志可以了解程序的运行情况,以备将来查看或调试。当前很多系统都使用了Log4J来进行日志的输出,包括Java、.Net、PHP等诸多系统,对于如何使用Log4J输出日志本文不再赘述,主要结合产品环境遇到的问题提供一个有效地记录日志的最佳实践。

在项目交付给客户后,往往需要对日志进行分析以查找系统存在的问题。而当前应用软件系统大多都是多服务器多层次的复杂体系,每个服务器上又是多线程,系统一般支持多个用户同时在线,这样日志输出时就造成了所有用户的日志信息交错地混合在一起,读取分析起来比较困难。

在产品环境中,需要针对以下问题输出必要的信息以有利于问题的分析和解决。
1.多服务器问题
可以为不同服务器创建不同的日志文件。
2.多线程问题
在日志中增加线程ID等信息。
3.多客户机问题
在日志中增加客户机IP地址等信息。
4.多用户问题
在日志中增加用户名等信息。
5.多时段问题
在日志中增加时间戳信息。
6.多程序问题
在日志中增加源代码信息,包括类名、方法名和行号。

日志中增加以上六项内容之后,就可以区分出来每个用户的日志信息了,再根据时间排序之后就很容易还原出每个用户的操作流程了,而实现这个功能,对于程序几乎没有任何影响!

以上六项信息,除了IP地址、用户名之外Log4J都可以自动获取的。IP地址和用户名可以利用Log4J中的映射诊断上下文(Mapped Diagnostic Context,MDC)功能来实现,映射诊断上下文可以将日志与当前正在运行的线程关联起来。这些运行时的信息可以输出到每条日志消息中。

首先,登录成功后,需要将用户名和IP地址写入HttpSession中,如:

session.setAttribute("userName", "张三");
session.setAttribute("clientIP",request.getRemoteAddr());

其次,写一个过滤器(Filter)中,从HttpSession中取出用户名和IP地址写入MDC供Log4J输出日志时使用。

public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
	String userName = null;
	String clientIP = null;

	// 从Session中获取信息
	HttpSession session = ((HttpServletRequest) request).getSession();
	if (session != null) {
		userName = (String) session.getAttribute("userName");
		clientIP = (String) session.getAttribute("clientIP");
	}

	if (userName == null) {
		userName = "unKnownUser";
	}
	if (clientIP == null) {
		clientIP = request.getRemoteAddr();
	}

	// 将用户名和客户机IP地址写入诊断上下文中.
   // 在Log4J的配置文件中,PatternLayout可以如此引用:%X{userName} %X{clientIP}
	MDC.put("userName", userName);
	MDC.put("clientIP", clientIP);

	// 继续处理其它过滤器.
	chain.doFilter(request, response);

}

再次,log4j.properties文件中的配置如下:

log4j.appender.RollingFileAppender=org.apache.log4j.RollingFileAppender
log4j.appender.RollingFileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.RollingFileAppender.layout.ConversionPattern=
%X{userName} %X{clientIP} %d %-5p [%t] %C{2} (%F:%L) - %m%n
log4j.appender.RollingFileAppender.MaximumFileSize=1024000
log4j.appender.RollingFileAppender.File=test.log

log4j.rootLogger=ERROR

log4j.logger.com.yourcompany=DEBUG, RollingFileAppender

然后,输出的日志信息就是下面的格式:

张三 192.168.1.2 2008-09-11 11:28:09,774 DEBUG [http-9080-14] base.LoginAction
 (LoginAction.java:81) - 登录成功

最后:使用Chainsaw V2可以读取分析Log4J的日志文件,新建一个LogFilePatternReceiver接收器,其中,
fileURL:file:///c:/test.log
logFormat:PROP(userName) PROP(clientIP) TIMESTAMP LEVEL [THREAD]
CLASS (FILE:LINE) - MESSAGE
name:test
点击OK按钮,然后就可以在Chainsaw中对日志进行过滤或排序了。
比如,可以设定:PROP.clientIP == ‘192.168.1.2′ && PROP.userName == ‘张三’,并按照时间戳进行排序,
这样就可以看到用户“张三”从客户机“192.168.1.2”上访问web网站的一系列操作了。


 发表评论

(必填)

(必填)

评论(必填,最多字数:100):