日期:2014-05-16  浏览次数:21257 次

多线程环境下 Apache Log4j 的 NDC/MDC 开发
从CSDN分享过来,原文名为:在 Web 应用中增加用户跟踪功能,学习在多线程环境下 Apache Log4j 的 NDC/MDC 开发

进行用户跟踪的重要性

随着 Web 应用的复杂化,用户在网站上的操作过程日益复杂。网站功能的多样化和交互性的提高为用户提供了多种可能的浏览路径。对于一个复杂的站点,用户在网站上操作的行为模式和操作习惯的分析,会给网站的优化提供基础的数据支持。而从技术上要为这种分析提供支持,就需要记录下每个用户在网站上的操作过程。另一方面,这种数据的记录也有助于解决用户在使用中出现的问题。我们只要知道用户遇到问题的时间和一些基本信息,就可以从日志中查出此用户遇到问题时的操作过程,从而有助于再现用户的出错场景,进而帮助用户解决问题。此外,网站用户的安全审计和分析用户特征的数据挖掘等工作也需要提供一个方法能对用户的网站操作进行跟踪和纪录。

通常 Web 应用的开发者会在开发过程中设置很多的跟踪点,在这些跟踪点向日志系统输出一些应用程序运行的信息,如果这些信息足够全面的话,开发者就可以利用他们猜测出程序如何处理的用户请求,以及可能遇到了什么问题。但不幸的是,如果一个站点在设计阶段没有把用户跟踪作为系统必须解决的一个问题提出的话,这些日志很可能就只是开发者为满足系统调试的需要而设置的一些信息。当用户访问量急剧增加的的时候,就会出现下面的问题。

在一个高访问量的 Web 应用中,经常要在同一时刻处理大量的用户请求。Web 服务器会为每一个请求分配一个线程,每一个线程都会向日志系统输入一些信息,通常日志系统都是按照时间顺序而不是用户顺序排列这些信息的,这些线程的交替运行会让所有用户的处理信息交错在一起,让人很难分辨出那些记录是同一个用户产生的。另外,高可用性的网站经常会使用负载均衡系统平衡网络流量,这样一个用户的操作记录很可能会分布在多个 Web 服务器上,如果我们没有一种方法来标示一条记录是哪个用户产生的,从这众多的日志信息中筛选出对我们有用的东西将是一项艰巨的工作。

本文试图探讨的解决方案是建立在 Log4J 的基础上的,如果你的 Web 站点已经使用了 Log4J 作为日志系统的 API 接口,根据本文所介绍的方法,就可以很容易的在每一条日志上保存用户上下文信息,为用户跟踪保存基本的访问数据。为了更清晰地介绍这种方法,我们先对 Log4J 以及 NDC/MDC 做个简单的介绍。

Log4J 简介

Log4J 主要构件

Log4J 是 Apache 组织提供的一个日志组件, 它设计了灵活的配置文件,利用它可以在不更改程序的情况下,通过修改配置文件来调控日志的输出。下面是 Log4J 最主要的三大基本构件:

?记录器(Loger)
对日志信息进行分类筛选。通过指定优先级,控制程序中日志信息的输出:高于优先级的日志可以被输出,低于优先级的日志则被忽略。

?输出源(Appenders)
指定日志信息的输出设备。Log4J 目前支持的输出设备有以下几种:

?org.apache.log4j.ConsoleAppender(控制台)
?org.apache.log4j.FileAppender(文件)
?org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
?org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
?org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
?org.apache.log4j.SocketAppender (Socket)
?org.apache.log4j.NtEventLogAppender (NT的Event Log)
?org.apache.log4j.JMSAppender (电子邮件)
程序员也可以根据自己的需要定制 Appenders,实现更复杂和更为方便实用的日志管理,比如把日志输入数据库,或者传输到统一的日志服务器,等等。

?布局(Layouts)
指定日志输出的格式。Log4J 提供的 Layout 有以下几种:

?org.apache.log4j.HTMLLayout(以 HTML 表格形式布局)
?org.apache.log4j.PatternLayout(可以灵活地指定布局模式)
?org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)
?org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
软件开发人员可以通过这三大构件,根据日志的类型和优先级进行记录,并且可以在程序运行时去控制日志信息输出的格式和往什么地方输出(控制台、日志文件)。

Log4J 使用示例

下面是一个在 Web 应用中使用 Log4J 的简单例子。

第 1 步:修改 Web 应用的 web.xml 文件

在 Web 应用的 web.xml 中指明 Log4J 的配置文件名称。


代码 1. 在 web.xml 中配置 Log4J


1.……
2.    <servlet>
3.        <servlet-name>log4j-init</servlet-name>
4.        <servlet-class>is.dsw.common.base.log4jInit</servlet-class>
5.        <init-param>
6.             <!—下面的初始化参数指定 log4j 的配置文件为 log4j.properties -->
7.            <param-name>log4j</param-name>
8.            <param-value>/WEB-INF/log4j.properties</param-value>
9.        </init-param>
10.        <load-on-startup>1</load-on-startup>
11.    </servlet>
12.    <servlet>
13.        <servlet-name>log4jServlet</servlet-name>
14.        <servlet-class>is.dsw.common.base.log4jServlet</servlet-class>
15.        <load-on-startup>0</load-on-startup>
16.    </servlet>
17.……
18.第 2 步:对 Log4J 进行配置

我们看到,在上面的配置中指定了 Log4J 的配置文件名为 log4j.properties。在这个文件中,我们可以通过对前文所述的 Log4J 的三大控件