SpringMVC与LogBack集成

最近在做项目中需要用到日志,本来选取的是Log4j,最后经过对比之后还是发现LogBack在性能上比Log4j有优势。至于有什么好处,请参考下面这篇文章。
从Log4j迁移到LogBack的理由

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

jar包配置

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

<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>

Web.xml
在web项目中需要通过web.xml来加载我们所需要的LogBack.xml具体如下

    <?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>

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

LogbackConfigListener类

    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());
        }
    }

    LogbackConfigurer类


    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());
        }

    }

LogbackWebConfigurer类

    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));
        }

    }

logback.XML配置
下面来看一下这个xml是如何配置的

    <?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>

关于这个XML文件的详细讲解请参考http://blog.csdn.net/haidage/article/details/6794509

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值