我与日志记录二三事(log4j&logback)

随着时间的流逝,转眼间已经工作了一年有余。这一年的工作让我的开发观念从学生彻底的变成了一个真正的开发人员。很简单的就是这个关于日志的问题,以前自己也写过一些项目,从没想过使用日志来记录程序的运行,可以说之前从来没有在eclipse中输入过log这个单词。但是就是通过这一年的工作,让我深刻的认识到日志记录的重要性,所以现在我把这一年涉及的日志的知识进行一次小的总结,也算是对这一年工作的一个纪念吧。

 

说到日志记录,在工作中最常用到的有JDK的Loggerslf4jlogbackApache的log4jcommons-logging。其中,对于这几个日志框架,其实都可以基于slf4j来实现,slf4j定义了一系列的接口,通过对其进行实现,可以对日志进行相应的记录。当然,slf4j自己本身也有相应的实现,这里具体不表。下面来具体说说两个我用到过的日志框架:log4j和logback。

聊聊log4j

关于log4j的历史,在此不必赘述,今天我就聊聊log4j具体在工作中的使用。

高楼万丈平地起,磨刀不误砍柴工,对于一个知识的学习,还是从基础开始最好,所以先了解一些概念,具体的使用在后面的代码中体现。

我觉得日志记录,说到底其实就是由这三个元素组成:输出级别,输出目的地,输出样式。

1.输出级别(level)

对于大多数的日志框架来说其实都有着以下的几个级别:

OFF,FATAL,ERROR,WARN,INFO,DEBUG,ALL

它们表示的意义分别是:

OFF: 最高等级,用于关闭所有日志记录。

FATAL:指出每个严重的错误事件将会导致应用程序的退出。

ERROR:指出虽然发生错误事件,但仍然不影响系统的继续运行。

WARN:表明会出现潜在的错误情形。

INFO:一般和在粗粒度级别上,强调应用程序的运行全程。

DEBUG:一般用于细粒度级别上,对调试应用程序非常有帮助。

ALL:最低等级,用于打开所有日志记录。

日志的输出级别也有优先级的顺序,它们从高到低依次是OFF,FATAL,ERROR,WARN,INFO,DEBUG,ALL。

级别的区分有什么作用呢?日志的级别控制可以很严格,它只会输出当前日志级别及以上级别的日志信息,例如我在程序中定义了某个日志的级别为INFO,那么程序只会输出INFO及高于其优先级的日志信息,对于低于INFO级别的DEBUG级别的日志就不会输出了。所以当引入级别的概念之后,我们就可以根据自己的需要输出自己想要的日志了。

在程序中我们可以使用上述七种级别的任何级别,但是对于log4j而言,官方文档推荐开发人员只使用ERROR,WARN,INFO,DEBUG这四种。

2.输出目的地(appender)

输出目的地指的就是日志最终输出到哪里进行呈现。常用的有输出到控制台,输出到文件,and so on。

对于log4j来说有几种比较常用的appender:

ConsoleAppender:输出到控制台。

FileAppender:输出到文件。

DailyRollingFileAppender:输出到文件,并且每天产生一个新的日志记录文件。

RollingFileAppender:输出到文件,并且每当日志记录文件的大小达到指定大小的时候就产生一个新的日志记录文件。

WriterAppender:将日志信息以流的方式发送到任意指定的地方。在工作中较少使用。

3.输出样式(pattern)

开发人员想以什么格式输出日志信息,想输出什么内容的日志信息,那么就需要输出样式的帮忙了。

说到样式pattern其实应该先说说布局layout。在log4j中,有以下的布局方式:

HTMLLayout:以HTML表格形式布局  

PatternLayout:可以灵活地指定布局模式

SimpleLayout:包含日志信息的级别和信息字符串

TTCCLayout:包含日志产生的时间、线程、类别等等信息

在实际中比较常用的是PatternLayout,开发人员可以自己定义日志内容的输出。所以下面介绍一下PatternLayout。

PatternLayout可以允许开发人员自己定义日志的输出内容,那么除了开发人员在程序中可以使用类似于logger.info("some log message")方法来输出日志外,log4j也自带了一些定义好的pattern参数供开发人员使用,如下:

参数含义
%n换行
%m日志内容
%p日志级别
%r程序启动到现在的毫秒数
%%输出百分号
%t当前线程名 
%d日期和时间,  常用的格式有 %d{DATE},  d{HH:mm:ss,SSS}
%l同 %F%L%C%M
%F java源文件名
%Ljava源码行数  
%Cjava类名,%C{1} 输出最后一个元素
%Mjava方法名

光说不练假把式,光练不说傻把式,又练又说真把式。千言万语不及一个HelloWorld,下面就来看看log4j到底怎么使用。

首先新建一个java的web项目,将log4j的jar包引入到项目中,再将log4j.properties文件也加入到项目中,如下:

log4j.properties文件如下:

#rootLogger定义了根日志记录器,等号后面第一个是输出级别,后面的分别是输出目的地 
log4j.rootLogger = debug,stdout,D,E
log4j.logger.org.springframework=debug,D    #这行配置的作用是将org.springframework包下的类执行时输出日志。这行配置为后续添加,源码包里没有
### 输出信息到控制台 ###
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 = [%p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到=E://logs/log.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]


这样一番准备之后,我们就可以在程序中使用log4j来记录日志了。

public class Log4jTest {
	
	//定义日志记录对象
	private static Logger logger = Logger.getLogger(Log4jTest.class);  

    /** 
     * @param args 
     * @throws FileNotFoundException 
     */  
    public static void main(String[] args) throws FileNotFoundException { 
    	
    	//BasicConfigurator将完成最简单的环境配置,即只输出一些最基本的信息例如启动时间,线程等。
    	//BasicConfigurator.configure();
    	
    	//PropertyConfigurator可以将log4j.properties读入到流里进行加载配置。
//    	PropertyConfigurator.configure(new FileInputStream(new File("src/config/log4j.properties")));
    	PropertyConfigurator.configure(Log4jTest.class.getResourceAsStream("/config/log4j.properties"));

        logger.debug("This is debug message.");  
        logger.info("This is info message.");  
        logger.error("This is error message.");  
        logger.warn("This is warn message.");
    }  
}

运行程序,就可以在控制台打印出我们在log4j.properties文件中配置的stdout的相应样式的日志信息了,并且在E盘的logs目录下也生成了一个log.log的日志记录文件记录的是debug级别以上的日志,以及一个error.log的日志记录文件记录的是error级别以上的日志。

当然,在实际应用中,我们通常需要在web项目中使用日志记录,所以下面就来聊聊如何在web项目中加入log4j。

新建一个Log4jInitServlet,用于在web容器启动时加载log4j的配置文件。

public class Log4jInitServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public Log4jInitServlet() {
        super();
    }

	public void init(ServletConfig config) throws ServletException {
		String propertiesLocation=config.getInitParameter("log4j-properties-location");
		if(propertiesLocation!=null){
			System.out.println("正在初始化日志打印配置文件");
			PropertyConfigurator.configure(Log4jInitServlet.class.getResourceAsStream(propertiesLocation));
		}else{
			System.err.println("未找到日志打印配置文件");
			//使用log4j提供的基本的配置
			BasicConfigurator.configure();
		}
		
	}
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}
}

再模拟创建一个业务层的Log4jServlet,在其中进行日志的输出。

public class Log4jServlet  extends HttpServlet  {
	
	private static final long serialVersionUID = 1L;
	Logger logger=Logger.getLogger(Log4jServlet.class);

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		logger.fatal("This is fatal message");
		logger.error("This is error message");
		logger.warn("This is warn message");
		logger.info("This is info message");
		logger.debug("This is debug message");
		super.doGet(req, resp);
	}
}

打开web.xml文件,将相应的servlet配置添加进去。当然也可以在使用eclipse创建servlet的时候进行添加,那么web.xml就自动的生成了相应的配置。

<?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_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>Log4j</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>log4jServlet</servlet-name>
    <servlet-class>com.earl.log4j.servlet.Log4jServlet</servlet-class>
  </servlet>
  
  <servlet>
    <description></description>
    <display-name>Log4jInitServlet</display-name>
    <servlet-name>Log4jInitServlet</servlet-name>
    <servlet-class>com.earl.log4j.servlet.Log4jInitServlet</servlet-class>
    <init-param>
      <param-name>log4j-properties-location</param-name>
      <param-value>/config/log4j.properties</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>log4jServlet</servlet-name>
    <url-pattern>/log4jServlet</url-pattern>
  </servlet-mapping>
</web-app>

当web容器启动时,就会根据log4j-properties-location的参数值加载log4j.properties文件了。与此同时,我们在浏览器地址栏中访问http://ip:port/ProjectName/log4jServlet,就会调用log4jServlet的get方法输出相应的日志信息了。

与springMVC整合使用:

要将log4j与springMVC整合使用,首先需要导入springMVC相应的jar包,再将springMVC的请求分发的servlet配置加入到web.xml中

<?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_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>Log4j</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <!-- spring配置 -->
  
  <servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<description></description>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:config/applicationContext.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>springmvc</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
  
    <context-param>  
        <param-name>log4jConfigLocation</param-name>  
        <param-value>/WEB-INF/classes/config/log4j.properties</param-value>  
    </context-param>  
  
  	<listener>
	  	<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
	 </listener>
  
  <context-param>
  	<param-name>webAppRootKey</param-name>
    <param-value>Log.root</param-value>
  </context-param>

</web-app>


然后创建一个Controller,模拟实际应用中的日志输出,并且在WEB-INF/jsp目录下创建hello.jsp,用于请求处理完后的跳转。

public class HelloController implements Controller {

	Logger logger=Logger.getLogger(HelloController.class);

<span style="white-space:pre">	</span>@Override
<span style="white-space:pre">	</span>public ModelAndView handleRequest(HttpServletRequest arg0,
<span style="white-space:pre">			</span>HttpServletResponse arg1) throws Exception {
<span style="white-space:pre">		</span>logger.info("请求来了");
<span style="white-space:pre">		</span>ModelAndView mv=new ModelAndView("hello");
<span style="white-space:pre">		</span>mv.addObject("message", "hello");
<span style="white-space:pre">		</span>logger.info("处理完成,准备转发");
		return mv;
	}
}


将HelloController配置到springMVC的配置文件applicationContext.xml中,这里不详细解释applicationContext.xml。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation=" http://www.springframework.org/schema/beans
										http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
										http://www.springframework.org/schema/aop
										http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
										http://www.springframework.org/schema/context
										http://www.springframework.org/schema/context/spring-context-3.2.xsd">
	
	<!-- 配置HandlerMapping -->
	<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
	
	<!-- 配置HandlerAdapter -->
	<!-- 表示所有实现了org.springframework.web.servlet.mvc.Controller接口的Bean可以作为Spring Web MVC中的处理器 -->
	<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
	
	<bean id="viewResovler" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
		<property name="prefix" value="/WEB-INF/jsp/"/>
		<property name="suffix" value=".jsp"/>
	</bean>
	
	<bean id="hello" name="/hello" class="com.earl.log4j.controller.HelloController"/>
		
</beans>

这一系列的配置完成之后,启动web容器,在容器启动的过程中,控制台会输出spring的启动日志信息。我使用的是tomcat,访问http://localhost:8080/Log4j/hello,这时在控制台又会输出HelloController中输出的日志内容,并且随后就跳转到了hello.jsp页面。
 

聊聊logback

说起logback,对于它的历史也不赘述,只说一点,logback是由log4j的作者创作的,是为了取代log4j而生的,所以log4j拥有的功能在logback中都能实现。下面就聊聊关于logback的那点事。

不同于log4j的配置是置于log4j.properties文件中,logback的配置是配置在logback-test.xml或logback.xml中,logback会在项目根路径下先寻找logback.groovy文件,如果找不到再寻找logback-test.xml,如果还没有找到,就寻找logback.xml文件。有人问如果还没找到logback.xml文件呢,那我就回你一句:“你使用个毛线的logback啊”。哈哈,不扯淡了,先来看看logback.xml长得哪般俊俏的摸样。

<?xml version="1.0" encoding="UTF-8"?>
<!-- 
scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
 -->
<configuration scan="true" scanPeriod="60000" debug="false">
<!-- 使用property设置属性,使用${}来调用 -->
<property name="LOG_HOME"  value="E:/logs"/>

<!-- 
	输出到控制台:
	encoder:输出格式
-->
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern>
      <charset>UTF-8</charset>
    </encoder>
  </appender>
  
<!-- 
	输出到文件:
	file:日志输出的文件
	encoder:输出格式
	append:是否在文件末尾追加日志,默认为true。如果设为false,会清空之前的文件内容
-->
<!-- 
	pattern:
	%d:时间格式
	%thread:输出日志的线程
	level:日志输出级别
	%logger:输出日志的类的全限定名,后面的数字可以控制全限定名输出长度
	%msg:日志输出内容
	%relative:程序启动到输出日志所用时间,单位ms
 -->
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
  	<file>${LOG_HOME}/test.log</file>
  	<encoder>
  		<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
  	</encoder>
  	<append>true</append>
  </appender>
  
  <!-- 
  		滚动记录日志,先将日志内容记录到某个文件,直到满足某个条件后将日志内容记录到其他文件。
  		file:日志输出的文件,活动文件,即当前记录日志的文件
		encoder:输出格式
		append:是否在文件末尾追加日志,默认为true。如果设为false,会清空之前的文件内容
		rollingPolicy:基于何种方式滚动记录日志,常用的为基于时间来滚动。
   -->
  <appender name="ROLLFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
  	<file>${LOG_HOME}/rolling.log</file>
  	<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  		<fileNamePattern >${LOG_HOME}/rolling.%d{yyyy-MM-dd HH:mm:ss}.log</fileNamePattern>
  		<maxHistory>30</maxHistory>
  	</rollingPolicy>
  	<encoder>
  		<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
  	</encoder>
  	<append>true</append>
  </appender>
  
  	<!-- 
  		logger:用来指定某一个包或者某个具体的类的日志记录
  		name:包名或类的全限定名
  		level:日志级别
  		appender-ref:引用的记录日志的类型
  		additivity:是否向上级loger传递打印信息。默认是true。
  	 -->
  	<logger name="com.earl.logback.test" level="WARN" additivity="false">
		<appender-ref ref="STDOUT"/>
		<appender-ref ref="ROLLFILE"/>
	</logger>
	
	<logger name="com.ibatis" level="DEBUG" additivity="false">
		<appender-ref ref="STDOUT" />
	</logger>
	<logger name="java.sql.Connection" level="DEBUG" additivity="false">
		<appender-ref ref="STDOUT" />
	</logger>
	<logger name="java.sql.Statement" level="DEBUG" additivity="false">
		<appender-ref ref="STDOUT" />
	</logger>
	<logger name="java.sql.ResultSet" level="DEBUG" additivity="false">
		<appender-ref ref="STDOUT" />
	</logger>
	<logger name="java.sql.PreparedStatement" level="DEBUG" additivity="false">
		<appender-ref ref="STDOUT" />
	</logger>

	<logger name="org.springframework" level="DEBUG" additivity="false">
		<appender-ref ref="STDOUT" />
	</logger>
	
<!-- 
	root也是logger的一种,属于根logger
 -->
  <root level="DEBUG">
    <appender-ref ref="ROLLFILE" />
    <appender-ref ref="STDOUT"/>
  </root>
</configuration>

与其他的日志记录框架一样,logback也需要关注三个要素,那就是

1.输出级别

相对于log4j,我认为logback对级别的控制更加精确,logback可以为指定的包甚至是指定的类定义输出级别。就如上面的配置文件里所展示的,在logger标签内配置的name就是你希望输出日志的包或者类,level定义了日志的级别,它的子标签appender-ref就是日志信息输出目的地的引用。上述配置文件中,可以将ibatis的运行日志记录出来,让我们清楚地看到ibatis运行时,对数据库的具体操作。

2.输出目的地

与log4j相似,比较常用的输出目的地是控制台和文件。

ConsoleAppender:输出到控制台

FileAppender:输出到文件

RollingFileAppender:输出到文件,但是当触发某个条件后会新生成一个新的日志文件进行存储。对于这个触发条件,RollingFileAppender有两种方式触发,一种是基于时间的触发,一种是基于文件大小的触发。

3.输出样式
常用的输出样式的参数如下表:

参数含义
%d时间格式,类似于log4j
%thread输出日志的线程
level日志输出级别
%logger输出日志的类的全限定名,后面的数字可以控制全限定名输出长度
%msg日志输出内容
%relative程序启动到输出日志所用时间,单位ms

还是那句话,光说不练假把式,光练不说傻把式,又练又说真把式。下面来看看logback的使用。

新建一个java的web项目,引入相应的jar包,在类路径下添加上面所示的logback.xml文件,如下:

在需要使用日志输出的类中创建一个log对象,这里依然是使用SLF4J的工厂方法来创建,如下:

public class LogbackTest {
	
	 Logger logger=LoggerFactory.getLogger(this.getClass());

	 @Test
	public void testHelloworld(){
	logger.debug("This is debug message.");  
        logger.info("This is info message.");  
        logger.error("This is error message.");  
        logger.warn("This is warn message.");
	} 

}

那么运行程序后,控制台会只输出warn级别以上的日志,因为这个类我放在了com.earl.logback.test包下,所以根据logback.xml的配置,就只输出warn级别以上的日志了。

当然这是最简单的应用了,下面简单的演示一下如何将logback与springMVC和ibatis整合一起使用。

在上面的工程里加入相应的springMVC和ibatis的jar包,这里说一点点题外的内容,spring3.x里才有与ibatis的整合包,所以最新的spring4.x里是没有与ibatis的整合包,这也与ibatis升级为mybatis有关系。然后如上图所示,在config目录下创建spring的配置文件applicationContext.xml,如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation=" http://www.springframework.org/schema/beans
										http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
										http://www.springframework.org/schema/aop
										http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
										http://www.springframework.org/schema/context
										http://www.springframework.org/schema/context/spring-context-3.2.xsd">
										
	<!-- 配置HandlerMapping -->
	<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
	
	<!-- 配置HandlerAdapter -->
	<!-- 表示所有实现了org.springframework.web.servlet.mvc.Controller接口的Bean可以作为Spring Web MVC中的处理器 -->
	<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
	
	<bean id="viewResovler" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
		<property name="prefix" value="/WEB-INF/jsp/"/>
		<property name="suffix" value=".jsp"/>
	</bean>
	
	<!-- DataSource数据源 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/test"/>
        <property name="username" value="root"/>
        <property name="password" value=""/>
    </bean>
    
    <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
        <property name="configLocation" value="classpath:config/sqlMapConfig.xml" />
        <property name="dataSource" ref="dataSource" />
    </bean>
	
	<bean id="query" name="/query" class="com.earl.logback.controller.QueryController">
		<property name="sqlMapClient" ref="sqlMapClient"/>
	</bean>
		
</beans>


然后再web.xml中进行springMVC的配置,与log4j相似,这里不详述。

接着加入ibatis的相关的配置文件,关于ibatis在这里也不具体说了,源代码里有详细的注释。

创建一个springMVC的controller,用于操作ibatis查询数据库,如下:

public class QueryController implements Controller {
	
	private SqlMapClient sqlMapClient;

	public SqlMapClient getSqlMapClient() {
		return sqlMapClient;
	}

	public void setSqlMapClient(SqlMapClient sqlMapClient) {
		this.sqlMapClient = sqlMapClient;
	}

	@Override
	public ModelAndView handleRequest(HttpServletRequest arg0,
			HttpServletResponse arg1) throws Exception {
		ModelAndView mv=new ModelAndView("studentsInfo");
		List students=sqlMapClient.queryForList("student.queryAllStudent");
		mv.addObject("students", students);
		return mv;
	}

}


当项目启动,logback会把spring的相关的日志打印在控制台。调用这个controller时,logback会把ibatis连接数据库,准备sql,查询过程,返回结果集的相应日志也输出到控制台上,这就非常明确的告诉了我们整个项目在运行过程中经历了什么。当然,最后这个controller会把查询的结果集返回到jsp页面上输出显示。

小插曲:在完成上面这个demo的时候,一开始无论如何都无法输出spring和ibatis的日志信息,最后通过查资料以及和同事探讨后我才明白了,如果需要输出spring,ibatis他们的日志信息的话,还需要将它们所需要的日志扩展包也加入到项目中。例如ibatis使用的就是commons-logging,那么当加入到项目中之后,输出日志时,SLF4J就会将commons-logging的日志信息转换为logback的日志信息了。

至此,就是我最近对日志输出的一点点小了解。总结一下吧,日志的输出对程序的调试以及程序的运行都有很大的帮助。虽然日志框架有很多,但是我认为只要掌握了他们的共性,那就是级别,输出目的地,输出样式。这样就可以根据不同的日志框架的特点很快的学会他们各自具体的使用。

源代码和模板可以点击这里下载

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值