zoukankan      html  css  js  c++  java
  • 日志问题

    日志框架

    常见的日志框架主要有

    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">
  • 相关阅读:
    判断python字典中key是否存在的两种方法
    @SuppressWarnings("unused")注解的作用
    jsp常见的指令总结
    我们怎么获取数据库中的值或者在数据库中添加值那???
    sql语句中的问号是干什么的???
    第四天:servlet的生命周期和一些细节问题
    第三天:Servlet运行原理
    第二天:tomcat体系结构和第一个Servlet
    第一天:tomcat相关知识和浏览器的访问机制
    在用mvn编译java文件时遇到问题
  • 原文地址:https://www.cnblogs.com/deolin/p/7258244.html
Copyright © 2011-2022 走看看