SpringMVC集成LogBack,相关配置
最近在做项目中需要用到日志,本来选取的是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>
- <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