日志问题

Posted Deolin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了日志问题相关的知识,希望对你有一定的参考价值。

日志框架

常见的日志框架主要有

 

Apache的JCL

Apache Commons Logging - JUL

Apache Commons LoggingLog4j

(其中,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">

 

以上是关于日志问题的主要内容,如果未能解决你的问题,请参考以下文章

我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印出C++的函数耗时以及代码片段耗时详情

执行代码时有时不显示对话框片段

webstorm代码片段的创建

python常用代码片段总结

片段内 Spinner 的 Kotlin 问题

日志片段,类中的Logfactory声明