您的位置:首页 > 编程语言 > Java开发

SpringMVC与LogBack集成

2015-10-27 17:01 537 查看
     最近在做项目中需要用到日志,本来选取的是Log4j,最后经过对比之后还是发现LogBack在性能上比Log4j有优势。至于有什么好处,请参考下面这篇文章。


从Log4j迁移到LogBack的理由

    下面废话不多说了,就看一下,如何来把LogBack集成到我们的web项目中吧。本人前台用的是SpringMVC。

    jar包配置
   如果要使用LogBack做为日志的插件的话,需要的jar包有如下,直接看一下Maven依赖

<span style="font-family:Comic Sans MS;font-size:18px;"><dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.3</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.3</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>1.1.3</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
<scope>compile</scope>
</dependency></span>

   
    Web.xml
      在web项目中需要通过web.xml来加载我们所需要的LogBack.xml具体如下
<span style="font-family:Comic Sans MS;font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 
<!-- logback-begin -->
<context-param>
<param-name>logbackConfigLocation</param-name>
<param-value> classpath:logback.xml</param-value>
</context-param>
<listener>
<listener-class>com.util.LogbackConfigListener</listener-class>
</listener>
<!-- logback-end -->

<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value> classpath:springMVC-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 这里一定要是/根据Servlet规范来的 -->
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

</web-app></span>


   上面的XML中用到了自定义的监听器,分别是三个类,如下所示

   LogbackConfigListener类
<span style="font-family:Comic Sans MS;font-size:18px;">package com.util;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class LogbackConfigListener implements ServletContextListener {

public void contextInitialized(ServletContextEvent event) {
LogbackWebConfigurer.initLogging(event.getServletContext());
}

public void contextDestroyed(ServletContextEvent event) {
LogbackWebConfigurer.shutdownLogging(event.getServletContext());
}
}
</span>


   LogbackConfigurer类
<span style="font-family:Comic Sans MS;font-size:18px;">package com.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.net.URL;

import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;
import org.springframework.util.SystemPropertyUtils;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;

public abstract class LogbackConfigurer {

/** Pseudo URL prefix for loading from the class path: "classpath:" */
public static final String CLASSPATH_URL_PREFIX = "classpath:";

/** Extension that indicates a logback XML config file: ".xml" */
public static final String XML_FILE_EXTENSION = ".xml";

private static LoggerContext lc = (LoggerContext) LoggerFactory
.getILoggerFactory();
private static JoranConfigurator configurator = new JoranConfigurator();

/**
* Initialize logback from the given file location, with no config file
* refreshing. Assumes an XML file in case of a ".xml" file extension, and a
* properties file otherwise.
*
* @param location
*            the location of the config file: either a "classpath:"
*            location (e.g. "classpath:mylogback.properties"), an absolute
*            file URL (e.g.
*            "file:C:/logback.properties), or a plain absolute path in the file system (e.g. "
*            C:/logback.properties")
* @throws FileNotFoundException
*             if the location specifies an invalid file path
*/
public static void initLogging(String location)
throws FileNotFoundException {
String resolvedLocation = SystemPropertyUtils
.resolvePlaceholders(location);
URL url = ResourceUtils.getURL(resolvedLocation);
if (resolvedLocation.toLowerCase().endsWith(XML_FILE_EXTENSION)) {
// DOMConfigurator.configure(url);
configurator.setContext(lc);
lc.reset();
try {
configurator.doConfigure(url);
} catch (JoranException ex) {
throw new FileNotFoundException(url.getPath());
}
lc.start();
}
// else {
// PropertyConfigurator.configure(url);
// }
}

/**
* Shut down logback, properly releasing all file locks.
* <p>
* This isn't strictly necessary, but recommended for shutting down logback
* in a scenario where the host VM stays alive (for example, when shutting
* down an application in a J2EE environment).
*/
public static void shutdownLogging() {
lc.stop();
}

/**
* Set the specified system property to the current working directory.
* <p>
* This can be used e.g. for test environments, for applications that
* leverage logbackWebConfigurer's "webAppRootKey" support in a web
* environment.
*
* @param key
*            system property key to use, as expected in logback
*            configuration (for example: "demo.root", used as
*            "${demo.root}/WEB-INF/demo.log")
* @see org.springframework.web.util.logbackWebConfigurer
*/
public static void setWorkingDirSystemProperty(String key) {
System.setProperty(key, new File("").getAbsolutePath());
}

}
</span>

  LogbackWebConfigurer类
<span style="font-family:Comic Sans MS;font-size:18px;">package com.util;

import java.io.FileNotFoundException;

import javax.servlet.ServletContext;

import org.springframework.util.ResourceUtils;
import org.springframework.util.SystemPropertyUtils;
import org.springframework.web.util.WebUtils;

public abstract class LogbackWebConfigurer {

/** Parameter specifying the location of the logback config file */
public static final String CONFIG_LOCATION_PARAM = "logbackConfigLocation";

/**
* Parameter specifying the refresh interval for checking the logback config
* file
*/
public static final String REFRESH_INTERVAL_PARAM = "logbackRefreshInterval";

/** Parameter specifying whether to expose the web app root system property */
public static final String EXPOSE_WEB_APP_ROOT_PARAM = "logbackExposeWebAppRoot";

/**
* Initialize logback, including setting the web app root system property.
*
* @param servletContext
*            the current ServletContext
* @see WebUtils#setWebAppRootSystemProperty
*/
public static void initLogging(ServletContext servletContext) {
// Expose the web app root system property.
if (exposeWebAppRoot(servletContext)) {
WebUtils.setWebAppRootSystemProperty(servletContext);
}

// Only perform custom logback initialization in case of a config file.
String location = servletContext
.getInitParameter(CONFIG_LOCATION_PARAM);
if (location != null) {
// Perform actual logback initialization; else rely on logback's
// default initialization.
try {
// Return a URL (e.g. "classpath:" or "file:") as-is;
// consider a plain file path as relative to the web application
// root directory.
if (!ResourceUtils.isUrl(location)) {
// Resolve system property placeholders before resolving
// real path.
location = SystemPropertyUtils
.resolvePlaceholders(location);
location = WebUtils.getRealPath(servletContext, location);
}

// Write log message to server log.
servletContext.log("Initializing logback from [" + location
+ "]");

// Initialize without refresh check, i.e. without logback's
// watchdog thread.
LogbackConfigurer.initLogging(location);

} catch (FileNotFoundException ex) {
throw new IllegalArgumentException(
"Invalid 'logbackConfigLocation' parameter: "
+ ex.getMessage());
}
}
}

/**
* Shut down logback, properly releasing all file locks and resetting the
* web app root system property.
*
* @param servletContext
*            the current ServletContext
* @see WebUtils#removeWebAppRootSystemProperty
*/
public static void shutdownLogging(ServletContext servletContext) {
servletContext.log("Shutting down logback");
try {
LogbackConfigurer.shutdownLogging();
} finally {
// Remove the web app root system property.
if (exposeWebAppRoot(servletContext)) {
WebUtils.removeWebAppRootSystemProperty(servletContext);
}
}
}

/**
* Return whether to expose the web app root system property, checking the
* corresponding ServletContext init parameter.
*
* @see #EXPOSE_WEB_APP_ROOT_PARAM
*/
private static boolean exposeWebAppRoot(ServletContext servletContext) {
String exposeWebAppRootParam = servletContext
.getInitParameter(EXPOSE_WEB_APP_ROOT_PARAM);
return (exposeWebAppRootParam == null || Boolean
.valueOf(exposeWebAppRootParam));
}

}
</span>


   logback.XML配置
下面来看一下这个xml是如何配置的
<span style="font-family:Comic Sans MS;font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>
<!-- ROOT 节点 -->
<!-- 属性描述 scan:性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 定义日志文件 输入位置,注意此处的/ -->
<property name="log_dir" value="E:/logs" />
<!-- 日志最大的历史 60天 -->
<property name="maxHistory" value="60"></property>

<!-- 控制台输出日志 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger -
%msg%n</pattern>
</encoder>

</appender>

<!-- 出错日志 appender -->
<appender name="ERROR"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 在多数的Log工具中,级别是可以传递,例如如果指定了日志输出级别为DEBUG, 那么INFO、ERROR级别的log也会出现在日志文件。这种默认给程序的调试带来了很多的麻烦
通过配置Filter 来严格控制日志输入级别 <filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR/level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch>
</filter> -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天回滚 daily -->
<fileNamePattern>${log_dir}/error-log-%d{yyyy-MM-dd}.log
</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>${maxHistory}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger -
%msg%n</pattern>
</encoder>
</appender>

<!-- INFO 日志 appender -->
<appender name="INFO"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天回滚 daily -->
<fileNamePattern>${log_dir}/info-log-%d{yyyy-MM-dd}.log
</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>${maxHistory}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger -
%msg%n</pattern>
</encoder>
</appender>

<!-- 访问日志 appender -->
<appender name="ACCESS"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天回滚 daily -->
<fileNamePattern>${log_dir}/access-log-%d{yyyy-MM-dd}.log
</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>${maxHistory}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger -
%msg%n</pattern>
</encoder>
</appender>

<!-- 系统用户操作日志 appender -->
<appender name="SYS-USER"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天回滚 daily -->
<fileNamePattern>${log_dir}/sys_user-log-%d{yyyy-MM-dd}.log
</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>${maxHistory}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger -
%msg%n</pattern>
</encoder>
</appender>

<!-- 打印SQL输出 -->
<logger name="java.sql.Connection" level="DEBUG" />
<logger name="java.sql.Statement" level="DEBUG" />
<logger name="java.sql.PreparedStatement" level="DEBUG" />

<!--error错误日志 additivity="false"表示不向上传递 -->
<!-- <logger name="com.test" level="error" > -->
<!-- <appender-ref ref="ERROR" /> -->
<!-- </logger> -->
<!--info日志 -->
<logger name="com.test" level="info" additivity="false">
<appender-ref ref="INFO" />
</logger>
<!--访问日志 -->
<!-- <logger name="com.test" level="info" additivity="false"> -->
<!-- <appender-ref ref="ACCESS" /> -->
<!-- </logger> -->
<!--系统用户操作日志 -->
<!-- <logger name="com.test" level="info" additivity="false"> -->
<!-- <appender-ref ref="SYS-USER" /> -->
<!-- </logger> -->

<root>
<level value="INFO" />
<appender-ref ref="stdout" />
</root>
</configuration></span>


关于这个XML文件的详细讲解请参考http://blog.csdn.net/haidage/article/details/6794509
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: