【Spring】Spring在JavaWeb工程中整合log4j

在《【Spring】Spring3.0.5的下载、配置与Helloworld》(点击打开链接)一文各位已经可能看到了。如果Spring不整合log4j直接启动,则会出现如下关于Spring整合log4j的警告。这个挺烦人的,一方面自己提倡高内聚,低耦合,另一方面,自己没有整合log4j就提出警告。我们程序猿写出来的程序就叫做“耦合”,它Spring就叫做“整合”。好吧!你只能同时搞明白,log4j是个什么鬼东西,Spring怎么整合log4j,两个问题:

log4j:WARN No appenders could be found for logger (org.springframework.web.context.ContextLoader). 
log4j:WARN Please initialize the log4j system properly.
由于此前介绍的都是Spring在Java工程中简单示例,log4j必须在JavaWeb工程中运行才有意义,你同时还要搞明白Spring怎么在JavaWeb工程上面运行,Spring怎么在JavaWeb工程中整合log4j。


一、Spring与Log4j的下载

1、你首先要有这两个JavaWeb组件的jar包吧?不然怎么搞出来?Spring在《【Spring】Spring3.0.5的下载、配置与Helloworld》(点击打开链接)一文中已经讲过怎么下载了。Log4j则打开Apache的官网(点击打开链接)如下图,选择log4j-1.2.17.zip(Windows)或者log4j-1.2.17.tar.gz(Linux)。同样是Apache的东西,在一些高版本的Tomcat中还整合了这个东西,当然,你最好还是在WEB-INF\lib目录下补上这个包,以致于你的工程在所有Tomcat都能跑。

【Spring】Spring在JavaWeb工程中整合log4j_第1张图片

2、在Eclipse for JavaEE中新建一个名为SpringLog4j的Dynamic Web Project,还在解压之后,把spring-framework-3.0.5.RELEASE-dependencies的所有东西与spring-framework-3.0.5.RELEASE\dist中的所有Jar包,不包括那个LIBD文件,apache-log4j-1.2.17下的log4j-1.2.17.jar,拷贝到WEB\lib文件夹。

【Spring】Spring在JavaWeb工程中整合log4j_第2张图片

3、之后你的Eclipse for JavaEE如下所示。WEB-INF目录下的Web.xml、applicationContext.xml、log4j.properties与根目录下的Log4j.jsp是一会儿我们要写的东西。

【Spring】Spring在JavaWeb工程中整合log4j_第3张图片


二、Spring与Log4j的配置

1、Web.xml

首先是这个关于JavaWeb的工程的总配置位置。我们要在里面声明要使用Spring与Log4j。值得注意的Log4j的配置必须在Spring配置之前,否则如果先启动Spring,那个必须整合Log4j才不吐警告的Spring,由于Log4j还没有启动,找不到Spring,又会在任性地吐警告。当然,你设置那些什么优先级也行,不过,先启动的直接放前面,这个文件不是更好看吗?

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	version="3.0">
	<!-- Log4j配置 -->
	<listener>
		<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
	</listener>
	<!-- 指定Log4j的配置文件所在目录。默认配置在WEB-INF目录下 -->
	<context-param>
		<param-name>log4jConfigLocation</param-name>
		<param-value>/WEB-INF/log4j.properties</param-value>
	</context-param>
	
	<!-- Spring配置 -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- 指定Spring Bean的配置文件所在目录。默认配置在WEB-INF目录下 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/applicationContext.xml</param-value>
	</context-param>
	
</web-app>  
2、log4j.properties

这家伙的后缀名是这么长,你有什么办法?必须照打,都是Linux那边带过来的主,你看看人家Windows的配置文件的后缀名仅仅就是ini3个字母!

#log4j.rootLogger = [ level ] , appenderName, appenderName, ...
log4j.rootLogger = all, console, R

#Console
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n

#File
log4j.appender.R = org.apache.log4j.RollingFileAppender
log4j.appender.R.File = c:/log.txt
log4j.appender.R.MaxFileSize = 500KB
log4j.appender.R.MaxBackupIndex = 1
log4j.appender.R.layout = org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] - %m%n
这东西还加不了中文注释,给大家一行一行地讲。#后面还仅能写英文的东西,把我大天朝的程序猿放哪里?我就加个中文注释都不让!

首先第一部分是log4j的总配置部分,all代表debug,info,error,fatal四种类型的信息都会输出。一般不设置为all,这里只是为了让大家看到效果。因为那些debug,info信息对我们半点意义没有,还因为有很多系统内部的文件运行都会输出debug与info信息刷屏、刷版。关键是输出到磁盘的日志文件会极速递增,浪费磁盘空间。玩SQL Server的时候大家又不知道那个.ldb是多么恐怖?

因此第一部分,一般写成:

log4j.rootLogger = ERROR, console, R
代表仅输出error与fatal错误。

之后的console,R分别代表在控制台与文件输出。同时在之后的代码必须配置好这个两输出。

第二部分控制台#Console
首先要使用log4j特定的包,这个没有什么好说,最后一句指明输出格式。一会儿大招对照输出结果就明白怎么回事了。

第三部分文件#File

log4j.appender.R.File=c:/log.txt是指这个Web工程错误日志皆输出到c:/log.txt。不要像网上那些大神输出一个什么.log后缀,关键是能够直接打开。

之后log4j.appender.R.MaxFileSize = 500KB指明这个log.txt文件大小最多为500KB,如果超过这个大小,自动开一个新文件,而log4j.appender.R.MaxBackupIndex=1指明此工程顶多只能有1个这个的日志文件。多了的话,新内容覆盖旧内容,就像那些闭路电视摄像头一样。

Log4j到这里就搞完了。

3、applicationContext.xml

之后是Spring的部分,由于这次根本就没有用Spring做任何东西,因此,这个applicationContext.xml这样写就行了:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
</beans>
能删的我都删了。

4、Log4j.jsp

最后是在WebContent根目录下的Log4j.jsp。在里面写入如下代码,整个程序的入口就是这个地方。

Servlet我都不搞了,就是为了让大家直接看清楚问题的关键所在。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="org.apache.log4j.Logger"%>
<%
Logger.getLogger(this.getClass()).fatal("致命错误!");
Logger.getLogger(this.getClass()).error("出错信息!");
Logger.getLogger(this.getClass()).info("普通信息!");
Logger.getLogger(this.getClass()).debug("调试信息!");
%>

三、运行结果

把SpringLog4j这个JavaWeb工程挂到Tomcat里面,运行,之后在任意浏览器输入http://localhost:8080/SpringLog4j/Log4j.jsp,待网页成功加载之后,直接回到Eclipse则得到如下的运行结果,你输入一次网址刷新一次,则输出一次以下结果:


同时,你的C盘,则多出一个log.txt,里面的内容如下,可以看到,在程序运行的时候,Spring的运行会吐出很多无意义的DEBUG、INFO、TRACE的信息,对于我们来说,真正有用的最后面的四句话。因此,可以理解,为何在上面的log4j.properties(这个后缀名又难记,又长,再次鄙视之!)的第一部分一般不写all,只写ERROR,这就只输出ERROR以上等级的错误,也就是ERROR与FATAL。或者写成TRACE,输出TRACE、ERROR与FATAL信息。

2015-05-10 09:54:34 [org.springframework.web.context.ContextLoader]-[INFO] - Root WebApplicationContext: initialization started
2015-05-10 09:54:34 [org.springframework.web.context.support.XmlWebApplicationContext]-[INFO] - Refreshing Root WebApplicationContext: startup date [Sun May 10 09:54:34 CST 2015]; root of context hierarchy
2015-05-10 09:54:34 [org.springframework.beans.factory.xml.XmlBeanDefinitionReader]-[INFO] - Loading XML bean definitions from ServletContext resource [/WEB-INF/applicationContext.xml]
2015-05-10 09:54:34 [org.springframework.beans.factory.xml.DefaultDocumentLoader]-[DEBUG] - Using JAXP provider [com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl]
2015-05-10 09:54:34 [org.springframework.beans.factory.xml.PluggableSchemaResolver]-[TRACE] - Trying to resolve XML entity with public id [null] and system id [http://www.springframework.org/schema/beans/spring-beans-3.0.xsd]
2015-05-10 09:54:34 [org.springframework.beans.factory.xml.PluggableSchemaResolver]-[DEBUG] - Loading schema mappings from [META-INF/spring.schemas]
2015-05-10 09:54:34 [org.springframework.beans.factory.xml.PluggableSchemaResolver]-[DEBUG] - Loaded schema mappings: {http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd=org/springframework/oxm/config/spring-oxm-3.0.xsd, http://www.springframework.org/schema/util/spring-util.xsd=org/springframework/beans/factory/xml/spring-util-3.0.xsd, http://www.springframework.org/schema/jms/spring-jms-3.0.xsd=org/springframework/jms/config/spring-jms-3.0.xsd, http://www.springframework.org/schema/task/spring-task.xsd=org/springframework/scheduling/config/spring-task-3.0.xsd, http://www.springframework.org/schema/aop/spring-aop-3.0.xsd=org/springframework/aop/config/spring-aop-3.0.xsd, http://www.springframework.org/schema/aop/spring-aop-2.0.xsd=org/springframework/aop/config/spring-aop-2.0.xsd, http://www.springframework.org/schema/oxm/spring-oxm.xsd=org/springframework/oxm/config/spring-oxm-3.0.xsd, http://www.springframework.org/schema/tool/spring-tool-2.5.xsd=org/springframework/beans/factory/xml/spring-tool-2.5.xsd, http://www.springframework.org/schema/beans/spring-beans.xsd=org/springframework/beans/factory/xml/spring-beans-3.0.xsd, http://www.springframework.org/schema/jee/spring-jee-2.5.xsd=org/springframework/ejb/config/spring-jee-2.5.xsd, http://www.springframework.org/schema/aop/spring-aop.xsd=org/springframework/aop/config/spring-aop-3.0.xsd, http://www.springframework.org/schema/beans/spring-beans-2.0.xsd=org/springframework/beans/factory/xml/spring-beans-2.0.xsd, http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd=org/springframework/web/servlet/config/spring-mvc-3.0.xsd, http://www.springframework.org/schema/beans/spring-beans-3.0.xsd=org/springframework/beans/factory/xml/spring-beans-3.0.xsd, http://www.springframework.org/schema/task/spring-task-3.0.xsd=org/springframework/scheduling/config/spring-task-3.0.xsd, http://www.springframework.org/schema/tx/spring-tx-2.5.xsd=org/springframework/transaction/config/spring-tx-2.5.xsd, http://www.springframework.org/schema/context/spring-context-2.5.xsd=org/springframework/context/config/spring-context-2.5.xsd, http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd=org/springframework/jdbc/config/spring-jdbc-3.0.xsd, http://www.springframework.org/schema/tool/spring-tool-3.0.xsd=org/springframework/beans/factory/xml/spring-tool-3.0.xsd, http://www.springframework.org/schema/tx/spring-tx.xsd=org/springframework/transaction/config/spring-tx-3.0.xsd, http://www.springframework.org/schema/tool/spring-tool-2.0.xsd=org/springframework/beans/factory/xml/spring-tool-2.0.xsd, http://www.springframework.org/schema/util/spring-util-2.5.xsd=org/springframework/beans/factory/xml/spring-util-2.5.xsd, http://www.springframework.org/schema/lang/spring-lang.xsd=org/springframework/scripting/config/spring-lang-3.0.xsd, http://www.springframework.org/schema/lang/spring-lang-2.5.xsd=org/springframework/scripting/config/spring-lang-2.5.xsd, http://www.springframework.org/schema/jee/spring-jee-3.0.xsd=org/springframework/ejb/config/spring-jee-3.0.xsd, http://www.springframework.org/schema/jee/spring-jee-2.0.xsd=org/springframework/ejb/config/spring-jee-2.0.xsd, http://www.springframework.org/schema/context/spring-context.xsd=org/springframework/context/config/spring-context-3.0.xsd, http://www.springframework.org/schema/jee/spring-jee.xsd=org/springframework/ejb/config/spring-jee-3.0.xsd, http://www.springframework.org/schema/jms/spring-jms-2.5.xsd=org/springframework/jms/config/spring-jms-2.5.xsd, http://www.springframework.org/schema/jms/spring-jms.xsd=org/springframework/jms/config/spring-jms-3.0.xsd, http://www.springframework.org/schema/aop/spring-aop-2.5.xsd=org/springframework/aop/config/spring-aop-2.5.xsd, http://www.springframework.org/schema/mvc/spring-mvc.xsd=org/springframework/web/servlet/config/spring-mvc-3.0.xsd, http://www.springframework.org/schema/jdbc/spring-jdbc.xsd=org/springframework/jdbc/config/spring-jdbc-3.0.xsd, http://www.springframework.org/schema/tx/spring-tx-2.0.xsd=org/springframework/transaction/config/spring-tx-2.0.xsd, http://www.springframework.org/schema/tx/spring-tx-3.0.xsd=org/springframework/transaction/config/spring-tx-3.0.xsd, http://www.springframework.org/schema/context/spring-context-3.0.xsd=org/springframework/context/config/spring-context-3.0.xsd, http://www.springframework.org/schema/tool/spring-tool.xsd=org/springframework/beans/factory/xml/spring-tool-3.0.xsd, http://www.springframework.org/schema/util/spring-util-3.0.xsd=org/springframework/beans/factory/xml/spring-util-3.0.xsd, http://www.springframework.org/schema/lang/spring-lang-3.0.xsd=org/springframework/scripting/config/spring-lang-3.0.xsd, http://www.springframework.org/schema/util/spring-util-2.0.xsd=org/springframework/beans/factory/xml/spring-util-2.0.xsd, http://www.springframework.org/schema/lang/spring-lang-2.0.xsd=org/springframework/scripting/config/spring-lang-2.0.xsd, http://www.springframework.org/schema/beans/spring-beans-2.5.xsd=org/springframework/beans/factory/xml/spring-beans-2.5.xsd}
2015-05-10 09:54:34 [org.springframework.beans.factory.xml.PluggableSchemaResolver]-[DEBUG] - Found XML schema [http://www.springframework.org/schema/beans/spring-beans-3.0.xsd] in classpath: org/springframework/beans/factory/xml/spring-beans-3.0.xsd
2015-05-10 09:54:34 [org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader]-[DEBUG] - Loading bean definitions
2015-05-10 09:54:34 [org.springframework.beans.factory.xml.XmlBeanDefinitionReader]-[DEBUG] - Loaded 0 bean definitions from location pattern [/WEB-INF/applicationContext.xml]
2015-05-10 09:54:34 [org.springframework.web.context.support.XmlWebApplicationContext]-[DEBUG] - Bean factory for Root WebApplicationContext: org.springframework.beans.factory.support.DefaultListableBeanFactory@5eedf162: defining beans []; root of factory hierarchy
2015-05-10 09:54:34 [org.springframework.web.context.support.XmlWebApplicationContext]-[DEBUG] - Unable to locate MessageSource with name 'messageSource': using default [org.springframework.context.support.DelegatingMessageSource@314b0824]
2015-05-10 09:54:34 [org.springframework.web.context.support.XmlWebApplicationContext]-[DEBUG] - Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [org.springframework.context.event.SimpleApplicationEventMulticaster@708a538f]
2015-05-10 09:54:34 [org.springframework.ui.context.support.UiApplicationContextUtils]-[DEBUG] - Unable to locate ThemeSource with name 'themeSource': using default [org.springframework.ui.context.support.ResourceBundleThemeSource@1fce66ba]
2015-05-10 09:54:34 [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[INFO] - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5eedf162: defining beans []; root of factory hierarchy
2015-05-10 09:54:34 [org.springframework.web.context.support.XmlWebApplicationContext]-[DEBUG] - Unable to locate LifecycleProcessor with name 'lifecycleProcessor': using default [org.springframework.context.support.DefaultLifecycleProcessor@7cbc2c83]
2015-05-10 09:54:34 [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] - Returning cached instance of singleton bean 'lifecycleProcessor'
2015-05-10 09:54:34 [org.springframework.web.context.support.XmlWebApplicationContext]-[TRACE] - Publishing event in Root WebApplicationContext: org.springframework.context.event.ContextRefreshedEvent[source=Root WebApplicationContext: startup date [Sun May 10 09:54:34 CST 2015]; root of context hierarchy]
2015-05-10 09:54:34 [org.springframework.web.context.ContextLoader]-[DEBUG] - Published root WebApplicationContext as ServletContext attribute with name [org.springframework.web.context.WebApplicationContext.ROOT]
2015-05-10 09:54:34 [org.springframework.web.context.ContextLoader]-[INFO] - Root WebApplicationContext: initialization completed in 230 ms
2015-05-10 09:54:48 [org.apache.jsp.Log4j_jsp]-[FATAL] - 致命错误!
2015-05-10 09:54:48 [org.apache.jsp.Log4j_jsp]-[ERROR] - 出错信息!
2015-05-10 09:54:48 [org.apache.jsp.Log4j_jsp]-[INFO] - 普通信息!
2015-05-10 09:54:48 [org.apache.jsp.Log4j_jsp]-[DEBUG] - 调试信息!

四、总结

Log4j一般不会像这样直接写在log4j.jsp中。一般处于那些try-catch异常结构中的catch里面,或许一些操作文件、数据库的关键数据之间,直接给程序员看的。程序猿有空看看那个在log.txt,也就像保安有空看看闭路电视,来确定你的WEB工程到底正不正常。可以成为系统运维的一部分。

你可能感兴趣的:(spring,log4j,运维,javaweb,调试)