SpringMVC与LogBack集成
2015-10-27 17:01
537 查看
最近在做项目中需要用到日志,本来选取的是Log4j,最后经过对比之后还是发现LogBack在性能上比Log4j有优势。至于有什么好处,请参考下面这篇文章。
下面废话不多说了,就看一下,如何来把LogBack集成到我们的web项目中吧。本人前台用的是SpringMVC。
jar包配置
如果要使用LogBack做为日志的插件的话,需要的jar包有如下,直接看一下Maven依赖
Web.xml
在web项目中需要通过web.xml来加载我们所需要的LogBack.xml具体如下
上面的XML中用到了自定义的监听器,分别是三个类,如下所示
LogbackConfigListener类
LogbackConfigurer类
LogbackWebConfigurer类
logback.XML配置
下面来看一下这个xml是如何配置的
关于这个XML文件的详细讲解请参考http://blog.csdn.net/haidage/article/details/6794509
从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
相关文章推荐
- Java:进制转换
- Spring MVC 乱码问题
- HashMap实现原理
- 运用java在数组键盘输入的位置加入元素
- Ubuntu 12.04下配置JDK7
- java关键字this使用
- Quartz与Spring的整合-Quartz中的job如何自动注入spring容器托管的对象
- java 线程中unchecked exception处理
- eclipse设置和优化
- Java集合框架总结
- eclipse下使用MultiDex解决65536限制
- 简要总结破解myeclipse10的方法
- eclipse 中git解决冲突
- Java并发编程:Thread类的使用
- Eclipse添加中文语言包与下载
- php eclipse xdebug 配置
- Java类的初始化过程
- spring3.2.0 quartz-2.2.1 整合 实现动态定时任务
- Java 多线程(六) synchronized关键字详解
- java中String的21种用法