Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。比如在这里定义了INFO级别,只有等于及高于这个级别的才进行处理,
一、log4j使用步骤(重点在使用过程和初始化):
1.将log4j.jar相关包放到jsp-examples\WEB-INF\lib下;
2.在classpath下面建立log4j.properties;
3.完善log4j.properties内容:
具体log4j.properties的配置方法参见http://hi.baidu.com/276668688/blog/item/e8d2fc1fdd8818c1a786698d.html
4.初始化log4j的配置文件:有两种方法
方法一:
a.新建一个初始化类,一般用Servlet或过滤器Log4JInit.java
注意:System.setProperty("webappHome", test);”这行代码要出现在“PropertyConfigurator.configure(prefix + file);”这行代码之前;因为这样才给"webappHome"设置值了,log4j.properties文件中的“log4j.appender.A1.file=${webappHome}/logs/tomcat_log_”中的“${webappHome}”这个环境变量才被赋值了,否则无法输出日志文件;
b.配置web.xml文件
注意:上面的load-on-startup应设为1,以便在Web容器启动时即装入该Servlet。log4j.properties文件放在根的properties子目录中,也可以把它放在其它目录中。应该把.properties文件集中存放,这样方便管理。
方法二、使用Spring已经写好的过滤器
a.配置web.xml
5.在webapp中使用log4j
主要建立一个属性private static Logger logger = Logger.getLogger(Log4jTest.class);
public class Hello extends HttpServlet {
private static Logger logger = Logger.getLogger(Hello.class);
@Override
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
System.out.println("Hello world!!");
logger.debug("log4j加载成功!");
}
}
6.在具体使用的时候如果触发了异常,就在生成以日期命名的html日志文件tomcat_log_2007-03-05.html了!
这个日志的格式可以在log4j.properties里面配置.......
====================================================================================================================================================================================================
常用log4j配置
常用log4j配置,一般可以采用两种方式,.properties和.xml,下面举两个简单的例子:
一、 log4j.properties
### 设置org.zblog域对应的级别INFO,DEBUG,WARN,ERROR和输出地A1,A2 ##
log4j.category.org.zblog=ERROR,A1
log4j.category.org.zblog=INFO,A2
log4j.appender.A1=org.apache.log4j.ConsoleAppender
### 设置输出地A1,为ConsoleAppender(控制台) ##
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
### 设置A1的输出布局格式PatterLayout,(可以灵活地指定布局模式)##
log4j.appender.A1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n
### 配置日志输出的格式##
log4j.appender.A2=org.apache.log4j.RollingFileAppender
### 设置输出地A2到文件(文件大小到达指定尺寸的时候产生一个新的文件)##
log4j.appender.A2.File=E:/study/log4j/zhuwei.html
### 文件位置##
log4j.appender.A2.MaxFileSize=500KB
### 文件大小##
log4j.appender.A2.MaxBackupIndex=1
log4j.appender.A2.layout=org.apache.log4j.HTMLLayout
##指定采用html方式输出
二、 log4j.xml
<?xml version="1.0" encoding="GB2312" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="org.zblog.all" class="org.apache.log4j.RollingFileAppender">
<!-- 设置通道ID:org.zblog.all和输出方式:org.apache.log4j.RollingFileAppender -->
<param name="File" value="E:/study/log4j/all.output.log" /><!-- 设置File参数:日志输出文件名 -->
<param name="Append" value="false" /><!-- 设置是否在重新启动服务时,在原有日志的基础添加新日志 -->
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%p (%c:%L)- %m%n" /><!-- 设置输出文件项目和格式 -->
</layout>
</appender>
<appender name="org.zblog.zcw" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="E:/study/log4j/zhuwei.output.log" />
<param name="Append" value="true" />
<param name="MaxFileSize" value="10240" /> <!-- 设置文件大小 -->
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%p (%c:%L)- %m%n" />
</layout>
</appender>
<logger name="zcw.log"> <!-- 设置域名限制,即zcw.log域及以下的日志均输出到下面对应的通道中 -->
<level value="debug" /><!-- 设置级别 -->
<appender-ref ref="org.zblog.zcw" /><!-- 与前面的通道id相对应 -->
</logger>
<root> <!-- 设置接收所有输出的通道 -->
<appender-ref ref="org.zblog.all" /><!-- 与前面的通道id相对应 -->
</root>
</log4j:configuration>
三、 配置文件加载方法:
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.xml.DOMConfigurator;
public class Log4jApp {
public static void main(String[] args) {
DOMConfigurator.configure("E:/study/log4j/log4j.xml");//加载.xml文件
//PropertyConfigurator.configure("E:/study/log4j/log4j.properties");//加载.properties文件
Logger log=Logger.getLogger("org.zblog.test");
log.info("测试");
}
}
四、 项目使用log4j
在web 应用中,可以将配置文件的加载放在一个单独的servlet中,并在web.xml中配置该servlet在应用启动时候加载。对于在多人项目中,可以给每一个人设置一个输出通道,这样在每个人在构建Logger时,用自己的域名称,让调试信息输出到自己的log文件中。
五、 常用输出格式
# -X号:X信息输出时左对齐;
# %p:日志信息级别
# %d{}:日志信息产生时间
# %c:日志信息所在地(类名)
# %m:产生的日志具体信息
# %n:输出日志信息换行
===============================================================================================
修改前:
偶们的做法是在action里记录日志,注意这个日志是面向用户的日志,姑且称它为业务日志,至于后台日志,则在此文章中暂不考虑,基本是通过log4j打印到后台日志文件中。看下面一段代码:
这段代码实际上已经将写日志的过程封装起来,开发者只需要传入3个参数:操作者、是前台系统还是后台系统、以及日志的错误等级,其它的如操作者机器IP, 日志时间等信息由系统统一设定,即使是这样,如果一个action里面有多个操作,代码看起来也非常臃肿,而且给开发者增加了工作量,既然有了aop,为 什么不利用一下?看下面改造的代码:
这段代码应该很清楚了,将logService注入到拦截log的advice里,进行正确操作的日志记录,而afterReturning方法里 的第一行判断是由于logService里的写日志的方法是以save开始的。所以,如果拦截器拦截到此方法,不需要记录日志。
正确的日志记录完,当然如果发生异常,我们需要记录操作的失败日志,当然了,我们也是通过aop来做,但是这次是通过实现exception advice来实现,代码如下:
上面代码已经很好的说明了,如果发生exception的话,日志是怎么记录的,这里要提到的一点的是,异常的处理稍微有一些复杂,就拿本例的代码能看出 来,只要在service层有异常的时候,都会记录失败日志,实际上,很多时候,未必是这样,在某个模块,可能需要定义一种特殊的异常,而一旦这种异常发 生,则需要进入另外一个流程或者做一些特殊的处理,这个时候需要根据具体情况做一些变更,比如在上面代码我们加上:
1.在网上看了不少例子,下面自己实践了一下。由于系统开发的时候忘记了对异常的日志处理,所以现在考虑加上,经过考虑决定使用spring的aop与log4j来做,这样做的好处就是我不用在每个类里面try{}catch或者抛出异常。因为类已经写了好多好多了。要是一个一个弄工作量是很大的 。
下面说下简单的实现过程,首先啊,在项目工程中的src目录中加入log4j.properties,内容如下:
###设置日志级别###
###这部分是将info信息输出到控制台###
log4j.rootLogger = info,stdout,F
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} %5p %c{1}:%L - %m%n
###错误日志配置###
log4j.appender.F = org.apache.log4j.DailyRollingFileAppender
##输出格式为自定义的HTML##
log4j.appender.F.layout = com.yale.sys.log.FormatHTMLLayout
log4j.appender.F.Threshold = ERROR
log4j.appender.F.Append=true
##错误文件存放位置##
log4j.appender.F.File=error.html
##每天滚动一次文件,即每天产生一个新的文件,文件名字eg:error.html.2012-06-18.html##
log4j.appender.F.DatePattern='.'yyyy-MM-dd'.html'
-------------------------------耐心的看下去 -----------------------------------
其次呢,看上面红色那部分,因为是要将输出日志信息存储到html文件中,所以重写了下log4j中HTMLLayout类,代码片段:
----------------------------耐心点往下看,就要没了 --------------------------------------------------
再来就是错误文件error.html的存储位置,想要放在项目的WebRoot下,于是就写了个servlet,代码片段:
注意啦,错误文件存储的路径不允许空格上面乱码七糟的,一定要注意哦。
写完这个servlet,我们不能忘记初始化,您说对不对啊,所以啊,web.xml就像下面这个样子了:
--------------------------------下面就开始和spring aop相关啦,看吧,看吧-----------------------
再一次首先,写一个系统异常日志拦截器类,您看:
上面这个类,主要用到了aspectj中的ProceedingJoinPoint,支持的是<aop:around />。
类写完了,但是spring配置文件applicationContext.xml还没有搞啊,所以搞一下:
小插曲:看见<aop:config>节点中proxy-target-class="true"这个属性了吧,当我不加的时候,启动项目,访问action代码,就比如是LoginAction中的login()方法,不幸的是他报错了,类似于
java.lang.NoSuchMethodException: $Proxy54.login(),可是回去一看,有写过这个login方法啊, $Proxy54又是怎么回事呢?因为你加入aop功能了,可是spring是这么干的,默认啊实现的是接口注入,关联的实现类。这里实现注入类,所以出现了异常。要怎么解决呢,于是就要加上proxy-target-class="true"属性,接下来启动项目吧,你会发现不幸的事情又发生了,又报错了:
org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.
提示的很明显,少jar包了,所以就加吧,但是加jar的时候也要注意了:
需要导入的jar包是cglib-nodep-2.1_3.jar(这里面整合了asm)或者(asm-2.2.3.jar和cglib-2.2.jar 。)因为cglib需要asm的支持。
到此完成。
启动项目开始运行吧,模拟了下一个异常,输出到html最终这样啦: