日志问题
日志框架
常见的日志框架主要有
Apache的JCL
Apache Commons Logging - JUL
Apache Commons Logging - Log4j
(其中,JUL是JDK的类,Log4j是Apache提供的实现类)
Gülcü的SLF4J
SLF4J - SLF4J-nop
SLF4J - SLF4J-simple
SLF4J - Logback
Apache的Log4j2
Log4j-API - Log4j-Core
SLF4J和Log4j2的性能都比JCL好。
每一种组合里都有日志Facade和对应的日志Implementation,
有些Mvaen依赖,如spring-core,内部会有个日志Facade,而spring-core提供了自己的实现。
所以不用maven配置SpringMVC项目时,如果只在/WEB-INF/lib放spring-*.jar的话,
启动服务会报错,因为缺少了commons-logging-1.2.jar。 (之前Deolin出现过这个问题)
如果使用maven配置SpringMVC项目的话,可以看到依赖链的末端已经有了commons-logging依赖了,项目单纯加入spring-webmvc就可以跑了。
项目能跑了之后需要选择一个日志框架,Deolin的选择是Log4j2-API - Log4j2-Core,
配置Log4j2
1、pom.xml追加
Log4j-web
由于是个web项目,所以在需要web.xml里面注册日志的<listener />和<filter />,
<listener-class />和<filter-class />用到了Log4j-web依赖,此依赖内部已经有了Log4j-API和Log4j-core了,
所以只需要一个Log4j-web就行了。
2、web.xml追加
<listener> <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class> </listener> <filter> <filter-name>log4jServletFilter</filter-name> <filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class> </filter> <filter-mapping> <filter-name>log4jServletFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping>
3、src/main/resources中新建log4j2.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- OFF < FATAL < ERROR < WARN < INFO < DEBUG < TRACE < ALL --> <configuration status="DEBUG"> <Properties> <Property name="LOG_HOME">logs</Property> <Property name="LOG_NAME">web-integration</Property> </Properties> <appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout charset="UTF-8" pattern="%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread][%file:%line] - %msg%n" /> </Console> <RollingFile name="log" fileName="${LOG_HOME}/${LOG_NAME}.log" filePattern="${LOG_HOME}/${LOG_NAME}.%d{yyyy-MM-dd}.log" append="true"> <PatternLayout charset="UTF-8" pattern="%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread][%file:%line] - %msg%n" /> <Policies> <TimeBasedTriggeringPolicy modulate="true" interval="1" /> </Policies> <DefaultRolloverStrategy max="180" /> </RollingFile> </appenders> <loggers> <root level="info"> <appender-ref ref="Console" /> <appender-ref ref="log" /> </root> </loggers> </configuration>
这个时候项目已经能跑了,开发人员写的日志信息已经能在控制台和log文件中正确打印了,
但是框架的日志,还是不能正确打印。
发生这个现象的原因是spring-core作为一个客户端,他调用的还是JCL的Apache Commons Logging,
并且,用的是自身提供的实现,这部分的代码无法修改,它们显然不认识log4j2.xml,所以依然按照自己的策略打印日志。
被spring-core认识 ----> Apache Commons Logging - spring提供的实现 ----> 不认识log4j2.xml
这个时候需要一个适配器,
被spring-core认识 ----> Apache Commons Logging - 某个适配器 - Log4j-core ----> 认识log4j2.xml
4、pom.xml追加
log4j-jcl
log4j-jcl就是那个适配器依赖,至此为止,服务器启动过程中,spring的日志也按照log4j2.xml中的风格打印出来了。
日志问题解决了。
日志适配器
常用的日志Facade和日志Implementation之间几乎都能组合,有许许多多的日志适配器用于解决
“某个框架所依赖的日志Facade于开发人员选择的日志Implementation无法匹配”的问题。
具体可以参考以下的图
@图片来自 知乎 - Java日志全解析(上) - 源流
TIPS
1、可以用Sublime 3 Text 来打开log文件,内容的增加可以实时反映在这个文本编辑器中,不用重新打开,
某种程度上可以代替eclipse的Consolo。
2、项目的编码一般都会是UTF-8,Deolin也将log4j2.xml的日志编码指定成了UTF-8,
但是Sublime 3 Text需要做如下设置,以保证日志中的中文可以正常显示。
- 安装ConvertToUTF8
- 进入ConvertToUTF8的设置,在"encoding_list"一项中,将["UTF-8", "UTF-8"],移动至最上面
3、默认只显示到INFO级别的日志,有需要的话,可以将在log4j2.xml的
<root level="info">
改为
<root level="debug">