logback + slf4j + jboss + spring mvc

logbacklog4jlog4j2 全是以同一个人为首的团伙搞出来的(日志专业户!),这几个各有所长,log4j性能相对最差,log4j2性能不错,但是目前跟mybatis有些犯冲(log4j2的当前版本,已经将AbstractLoggerWrapper更名成ExtendedLoggerWrapper,但是mybatis 2.3.7依赖的仍然是旧版本的log4j2,所以mybatis使用log4j2会报错),说到日志,还要注意另一外项目SLF4J( java的世界里,记日志的组件真是多!),SLF4J只一个接口标准,并不提供实现(就好象JSF/JPA 与 RichFaces/Hibernate的关系类似),而LogBack是SLF4J的一个实现,下面介绍logback的基本用法

一、基本用法

1.1 maven依赖项

logback + slf4j + jboss + spring mvc
 1         <!-- log -->

 2         <dependency>

 3             <groupId>org.slf4j</groupId>

 4             <artifactId>slf4j-api</artifactId>

 5             <version>1.7.7</version>

 6         </dependency>

 7 

 8         <dependency>

 9             <groupId>ch.qos.logback</groupId>

10             <artifactId>logback-core</artifactId>

11             <version>1.1.2</version>

12         </dependency>

13 

14         <dependency>

15             <groupId>ch.qos.logback</groupId>

16             <artifactId>logback-classic</artifactId>

17             <version>1.1.2</version>

18         </dependency>
View Code

1.2 配置文件logback.xml

logback + slf4j + jboss + spring mvc
 1 <?xml version="1.0" encoding="UTF-8" ?>

 2 <configuration scan="true" scanPeriod="1800 seconds"

 3     debug="false">

 4 

 5     <property name="USER_HOME" value="logs" />

 6     <property scope="context" name="FILE_NAME" value="mylog-logback" />

 7 

 8     <timestamp key="byDay" datePattern="yyyy-MM-dd" />

 9 

10     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">

11         <encoder>

12             <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n

13             </pattern>

14         </encoder>

15     </appender>

16 

17     <appender name="file"

18         class="ch.qos.logback.core.rolling.RollingFileAppender">

19         <file>${USER_HOME}/${FILE_NAME}.log</file>

20 

21         <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">

22             <fileNamePattern>${USER_HOME}/${byDay}/${FILE_NAME}-${byDay}-%i.log.zip

23             </fileNamePattern>

24             <minIndex>1</minIndex>

25             <maxIndex>10</maxIndex>

26         </rollingPolicy>

27 

28         <triggeringPolicy

29             class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">

30             <maxFileSize>5MB</maxFileSize>

31         </triggeringPolicy>

32         <encoder>

33             <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n

34             </pattern>

35         </encoder>

36 

37     </appender>

38 

39     <logger name="com.cnblogs.yjmyzz.App2" level="debug" additivity="true">

40         <appender-ref ref="file" />

41         <!-- <appender-ref ref="STDOUT" /> -->

42     </logger>

43 

44     <root level="info">

45         <appender-ref ref="STDOUT" />

46     </root>

47 </configuration>
View Code

1.3 示例程序
跟前面log4j2的示例程序几乎完全一样:

logback + slf4j + jboss + spring mvc
 1 package com.cnblogs.yjmyzz;

 2 

 3 import org.slf4j.*;

 4 

 5 public class App2 {

 6 

 7     static Logger logger = LoggerFactory.getLogger(App2.class);

 8     

 9 

10     public static void main(String[] args) {

11         for (int i = 0; i < 100000; i++) {

12             logger.trace("trace message " + i);

13             logger.debug("debug message " + i);

14             logger.info("info message " + i);

15             logger.warn("warn message " + i);

16             logger.error("error message " + i);            

17         }

18         System.out.println("Hello World! 2");

19     }

20 }
View Code

运行后,会在当前目录下创建logs目录,生成名为mylog-logback.log的日志文件,该文件体积>5M后,会自动创建 yyyy-mm-dd的目录,将历史日志打包生成类似:mylog-logback-2014-09-24-1.log.zip 的压缩包,每天最多保留10个

 

二、与spring -mvc的集成 

2.1 maven依赖项 

注:${springframework.version},我用的是3.2.8.RELEASE 版本

logback + slf4j + jboss + spring mvc
 1 <!-- Spring -->

 2         <dependency>

 3             <groupId>org.springframework</groupId>

 4             <artifactId>spring-core</artifactId>

 5             <version>${springframework.version}</version>

 6         </dependency>

 7         <dependency>

 8             <groupId>org.springframework</groupId>

 9             <artifactId>spring-beans</artifactId>

10             <version>${springframework.version}</version>

11         </dependency>

12         <dependency>

13             <groupId>org.springframework</groupId>

14             <artifactId>spring-context</artifactId>

15             <version>${springframework.version}</version>

16         </dependency>

17         <dependency>

18             <groupId>org.springframework</groupId>

19             <artifactId>spring-web</artifactId>

20             <version>${springframework.version}</version>

21         </dependency>

22         <dependency>

23             <groupId>org.springframework</groupId>

24             <artifactId>spring-webmvc</artifactId>

25             <version>${springframework.version}</version>

26         </dependency>

27         <dependency>

28             <groupId>org.springframework</groupId>

29             <artifactId>spring-expression</artifactId>

30             <version>${springframework.version}</version>

31         </dependency>

32 

33         <!-- logback -->

34         <dependency>

35             <groupId>org.slf4j</groupId>

36             <artifactId>slf4j-api</artifactId>

37             <version>1.7.7</version>

38         </dependency>        

39 

40         <dependency>

41             <groupId>ch.qos.logback</groupId>

42             <artifactId>logback-core</artifactId>

43             <version>1.1.2</version>

44         </dependency>

45 

46         <dependency>

47             <groupId>ch.qos.logback</groupId>

48             <artifactId>logback-classic</artifactId>

49             <version>1.1.2</version>

50         </dependency>

51 

52         <!-- Servlet -->

53         <dependency>

54             <groupId>javax.servlet</groupId>

55             <artifactId>servlet-api</artifactId>

56             <version>2.5</version>

57             <scope>provided</scope>

58         </dependency>
View Code

2.2 web.xml里增加下面的内容

logback + slf4j + jboss + spring mvc
1 <!-- logback-begin -->

2     <context-param>

3         <param-name>logbackConfigLocation</param-name>

4         <param-value>classpath:logback.xml</param-value>

5     </context-param>

6     <listener>

7         <listener-class>com.cnblogs.yjmyzz.util.LogbackConfigListener</listener-class>

8     </listener>

9     <!-- logback-end -->
View Code

其中com.cnblogs.yjmyzz.util.LogbackConfigListener 是自己开发的类,代码如下:(从网上掏来的)

注:该处理方式同样适用于struts 2.x

logback + slf4j + jboss + spring mvc
 1 package com.cnblogs.yjmyzz.util;

 2 

 3 import javax.servlet.ServletContextEvent;

 4 import javax.servlet.ServletContextListener;

 5 

 6 public class LogbackConfigListener implements ServletContextListener {

 7 

 8     public void contextInitialized(ServletContextEvent event) {

 9         LogbackWebConfigurer.initLogging(event.getServletContext());

10     }

11 

12     public void contextDestroyed(ServletContextEvent event) {

13         LogbackWebConfigurer.shutdownLogging(event.getServletContext());

14     }

15 }
LogbackConfigListener
logback + slf4j + jboss + spring mvc
  1 package com.cnblogs.yjmyzz.util;

  2 

  3 import java.io.FileNotFoundException;

  4 

  5 import javax.servlet.ServletContext;

  6 

  7 import org.springframework.util.ResourceUtils;

  8 import org.springframework.util.SystemPropertyUtils;

  9 import org.springframework.web.util.WebUtils;

 10 

 11 public abstract class LogbackWebConfigurer {

 12 

 13     /** Parameter specifying the location of the logback config file */

 14     public static final String CONFIG_LOCATION_PARAM = "logbackConfigLocation";

 15 

 16     /**

 17      * Parameter specifying the refresh interval for checking the logback config

 18      * file

 19      */

 20     public static final String REFRESH_INTERVAL_PARAM = "logbackRefreshInterval";

 21 

 22     /** Parameter specifying whether to expose the web app root system property */

 23     public static final String EXPOSE_WEB_APP_ROOT_PARAM = "logbackExposeWebAppRoot";

 24 

 25     /**

 26      * Initialize logback, including setting the web app root system property.

 27      * 

 28      * @param servletContext

 29      *            the current ServletContext

 30      * @see WebUtils#setWebAppRootSystemProperty

 31      */

 32     public static void initLogging(ServletContext servletContext) {

 33         // Expose the web app root system property.

 34         if (exposeWebAppRoot(servletContext)) {

 35             WebUtils.setWebAppRootSystemProperty(servletContext);

 36         }

 37 

 38         // Only perform custom logback initialization in case of a config file.

 39         String location = servletContext

 40                 .getInitParameter(CONFIG_LOCATION_PARAM);

 41         if (location != null) {

 42             // Perform actual logback initialization; else rely on logback's

 43             // default initialization.

 44             try {

 45                 // Return a URL (e.g. "classpath:" or "file:") as-is;

 46                 // consider a plain file path as relative to the web application

 47                 // root directory.

 48                 if (!ResourceUtils.isUrl(location)) {

 49                     // Resolve system property placeholders before resolving

 50                     // real path.

 51                     location = SystemPropertyUtils

 52                             .resolvePlaceholders(location);

 53                     location = WebUtils.getRealPath(servletContext, location);

 54                 }

 55 

 56                 // Write log message to server log.

 57                 servletContext.log("Initializing logback from [" + location

 58                         + "]");

 59 

 60                 // Initialize without refresh check, i.e. without logback's

 61                 // watchdog thread.

 62                 LogbackConfigurer.initLogging(location);

 63 

 64             } catch (FileNotFoundException ex) {

 65                 throw new IllegalArgumentException(

 66                         "Invalid 'logbackConfigLocation' parameter: "

 67                                 + ex.getMessage());

 68             }

 69         }

 70     }

 71 

 72     /**

 73      * Shut down logback, properly releasing all file locks and resetting the

 74      * web app root system property.

 75      * 

 76      * @param servletContext

 77      *            the current ServletContext

 78      * @see WebUtils#removeWebAppRootSystemProperty

 79      */

 80     public static void shutdownLogging(ServletContext servletContext) {

 81         servletContext.log("Shutting down logback");

 82         try {

 83             LogbackConfigurer.shutdownLogging();

 84         } finally {

 85             // Remove the web app root system property.

 86             if (exposeWebAppRoot(servletContext)) {

 87                 WebUtils.removeWebAppRootSystemProperty(servletContext);

 88             }

 89         }

 90     }

 91 

 92     /**

 93      * Return whether to expose the web app root system property, checking the

 94      * corresponding ServletContext init parameter.

 95      * 

 96      * @see #EXPOSE_WEB_APP_ROOT_PARAM

 97      */

 98     private static boolean exposeWebAppRoot(ServletContext servletContext) {

 99         String exposeWebAppRootParam = servletContext

100                 .getInitParameter(EXPOSE_WEB_APP_ROOT_PARAM);

101         return (exposeWebAppRootParam == null || Boolean

102                 .valueOf(exposeWebAppRootParam));

103     }

104 

105 }
LogbackWebConfigurer
logback + slf4j + jboss + spring mvc
 1 package com.cnblogs.yjmyzz.util;

 2 

 3 import java.io.File;

 4 import java.io.FileNotFoundException;

 5 import java.net.URL;

 6 

 7 import org.slf4j.LoggerFactory;

 8 import org.springframework.util.ResourceUtils;

 9 import org.springframework.util.SystemPropertyUtils;

10 

11 import ch.qos.logback.classic.LoggerContext;

12 import ch.qos.logback.classic.joran.JoranConfigurator;

13 import ch.qos.logback.core.joran.spi.JoranException;

14 

15 public abstract class LogbackConfigurer {

16 

17     /** Pseudo URL prefix for loading from the class path: "classpath:" */

18     public static final String CLASSPATH_URL_PREFIX = "classpath:";

19 

20     /** Extension that indicates a logback XML config file: ".xml" */

21     public static final String XML_FILE_EXTENSION = ".xml";

22 

23     private static LoggerContext lc = (LoggerContext) LoggerFactory

24             .getILoggerFactory();

25     private static JoranConfigurator configurator = new JoranConfigurator();

26 

27     /**

28      * Initialize logback from the given file location, with no config file

29      * refreshing. Assumes an XML file in case of a ".xml" file extension, and a

30      * properties file otherwise.

31      * 

32      * @param location

33      *            the location of the config file: either a "classpath:"

34      *            location (e.g. "classpath:mylogback.properties"), an absolute

35      *            file URL (e.g.

36      *            "file:C:/logback.properties), or a plain absolute path in the file system (e.g. "

37      *            C:/logback.properties")

38      * @throws FileNotFoundException

39      *             if the location specifies an invalid file path

40      */

41     public static void initLogging(String location)

42             throws FileNotFoundException {

43         String resolvedLocation = SystemPropertyUtils

44                 .resolvePlaceholders(location);

45         URL url = ResourceUtils.getURL(resolvedLocation);

46         if (resolvedLocation.toLowerCase().endsWith(XML_FILE_EXTENSION)) {

47             // DOMConfigurator.configure(url);

48             configurator.setContext(lc);

49             lc.reset();

50             try {

51                 configurator.doConfigure(url);

52             } catch (JoranException ex) {

53                 throw new FileNotFoundException(url.getPath());

54             }

55             lc.start();

56         }

57         // else {

58         // PropertyConfigurator.configure(url);

59         // }

60     }

61 

62     /**

63      * Shut down logback, properly releasing all file locks.

64      * <p>

65      * This isn't strictly necessary, but recommended for shutting down logback

66      * in a scenario where the host VM stays alive (for example, when shutting

67      * down an application in a J2EE environment).

68      */

69     public static void shutdownLogging() {

70         lc.stop();

71     }

72 

73     /**

74      * Set the specified system property to the current working directory.

75      * <p>

76      * This can be used e.g. for test environments, for applications that

77      * leverage logbackWebConfigurer's "webAppRootKey" support in a web

78      * environment.

79      * 

80      * @param key

81      *            system property key to use, as expected in logback

82      *            configuration (for example: "demo.root", used as

83      *            "${demo.root}/WEB-INF/demo.log")

84      * @see org.springframework.web.util.logbackWebConfigurer

85      */

86     public static void setWorkingDirSystemProperty(String key) {

87         System.setProperty(key, new File("").getAbsolutePath());

88     }

89 

90 }
LogbackConfigurer

2.3 JBOSS EAP 6+ 的特殊处理

jboss 默认已经集成了sf4j模块,会与上面新加的3个类有冲突,app启动时会报错:

 java.lang.ClassCastException: org.slf4j.impl.Slf4jLoggerFactory cannot be cast to ch.qos.logback.classic.LoggerContext

所以,需要手动排除掉jboss默认的slf4j模块,在web-inf下创建名为jboss-deployment-structure.xml的文件,内容如下:

logback + slf4j + jboss + spring mvc
 1 <?xml version="1.0" encoding="UTF-8"?>

 2 <jboss-deployment-structure>

 3     <deployment>        

 4         <exclusions>

 5             <module name="org.slf4j" />

 6             <module name="org.slf4j.impl" />

 7             <module name="org.slf4j.jcl-over-slf4j" />

 8             <module name="org.slf4j.ext" />            

 9         </exclusions>

10     </deployment>

11 </jboss-deployment-structure>
View Code

2.4 最后将logback.xml放到resouces目录下即可(打包后,会自动复制到classpath目录下)

 

你可能感兴趣的:(spring mvc)