Java日志体系

作者: hh23485 | 来源:发表于2018-01-18 10:13 被阅读140次

    对于任何一个编程语言或者框架来说,在编写代码时,日志都是必不可少的内容。日志不仅可以帮助开发者了解系统中出现的问题,也能够帮助开发者了解框架、程序是如何运行的。

    比如,在Spring框架中,基本上大家都会用log日志来跟踪filter的执行顺序、spring的启动顺序等等。

    但是日志并不代表是一种简单的文本输出,在很多场景下,程序对日志的输出目标、格式、位置、色彩、速度都有要求。因此,市面上有很多出名的框架,例如log4jlog4j2logbackjdk log等等。虽然他们当中最出名的几个,都是同一个人写的。。。

    当种类变多功能变强的时候,选择就成为了一个问题。如何选择一个好用的、好记的日志框架,以及如何快速的适配各种系统需要开发人员去考虑。

    此篇将会记录Java的日志体系,一些场景下的选择和常用配置。


    什么是日志体系

    那么什么是日志体系呢?我们都知道面向接口编程,由大佬们定义接口规范,小的们去实现。这样程序跑起来的时候,可以不在意究竟是哪一个实现承担的任务。举个例子。

    就像你拨打别人的手机,你只需要拨出号码,不需要在意对方是电信、移动、联通或者是小米之类的通讯商。这就是他们都符合可拨打的规范带来的好处。

    日志系统也是这样,不需要在意你用了什么日志框架,无论是log4jlogback或者是jdk原生的java.util.logger,都能够被log日志的规范所兼容。

    那么,你想要打印日志的时候,你只需要调用log.info("hello")就可以打印"hello"。**而且,当你需要从一个框架迁移到另外一个日志框架的时候,只需要把依赖的日志框架jar包换进来,就立即生效。

    而这个规范、规范的实现加上日志框架,就成为了日志体系。

    在日常,最常见的和最著名的两种日志体系分别是基于JCL的日志体系和基于Slf4j的日志体系。


    基于jcl日志体系

    jcl日志体系的接口规范由commons-logging提供,这是apache commons系列的工具包之一。Apache commons系列的工具包都非常有用,比如流操作、文件复制、加密解密之类的常用操作,都可以直接找到完善的解决方案。。。具体的操作晚上有很多的介绍,如果你想要知道他一共有多少种,可以直接去Maven仓库中搜索一下org.apache.commons看看。

    commons-logging已经停止更新,最后的状态如下所示:

    jcl architecture

    具体的使用。。。因为我已经不用了,所以可以参考其他的使用教程:

    需要注意的是jcl是存在一定缺陷的,这也是为什么现在大多数都使用slf4j作为接口规范。


    基于slf4j日志体系

    slf4j的历程也是非常的传奇,有兴趣的可以去搜索看看。
    写了log4j、log4j2、slf4j、logback的传奇日志作者。。。Ceki

    slf4j的全称为Simple Logging Facade For Java,从下图可见,slf4j的能耐比jcl大得多,基本上覆盖了所有出名的(自己写的...)日志框架。

    slf4j architecture.png

    slf4j的使用和jcl的使用没有太大的差异,如下所示:

        //声明日志对象,Logger的全限定名为
     org.slf4j.Logger 而不是 java.util.Logger
        static  Logger log = LoggerFactory.getLogger(Log02Application.class);
        //简单的测试方法
        public static void main(String[] args) {
            log.info("hello log");
        }
    

    具体的案例我们通过整合来介绍:

    整合springboot

    在springboot中,默认使用了logback作为日志框架。默认的输出如下所示:

    2017-11-29 12:58:17.757  INFO 47280 --- [  restartedMain] cn.hhchat.log02.Log02Application         : hello log
    

    但是当然你可以自己配置,配置文件放在resources文件目录下即可,springboot会自动按顺序搜寻下列文件。

    • Logback:logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
    • Log4j:log4j-spring.properties, log4j-spring.xml, -
      log4j.properties, log4j.xml
    • Log4j2:log4j2-spring.xml, log4j2.xml
    • JDK (Java Util Logging):logging.properties

    使用log4j2

    由于springboot默认使用了logback,因此当你试图使用log4j2的时候,你需要先剔除logback

    <!--从spring-boot-starter中剔除logging,该依赖如果没有的话,可以直接把整个依赖粘上,如果依赖已经存在,只需要添加<exclustions>中间的内容即可。-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <!--引入log4j2-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>
    

    整合spring

    log4j2配置

    日志的配置一直是一个大麻烦,因为每次都要导出翻博客来找,虽然之前看过官方的文档,但是现在也记不太清了,所以整理一下思路,记录一个普遍可用的方式供以后复制使用。

    下面是配置的基本步骤:

    log4j2配置

    首先,你需要先配置一个Logger,logger定义了该logger配置使用的包和日志级别、输出到什么位置等等内容,之后配置Appender,appender表示的是你需要将日志输出到什么文件以及输出的格式。

    logback配置

    <configuration>
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%d{HH:mm:ss} [%thread] [%-5level] %logger{36} - %msg%n</pattern>
                <charset>utf8</charset>
            </encoder>
        </appender>
        <appender name="fileLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <File>log/base.log</File>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>log/base.log.%d.%i</fileNamePattern>
                <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <!-- or whenever the file size reaches 64 MB -->
                    <maxFileSize>64 MB</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>                       
            </rollingPolicy>
            <encoder>
                <pattern>
                    %d %p (%file:%line\)- %m%n
                </pattern>
                <charset>UTF-8</charset> <!-- 此处设置字符集 -->
            </encoder>
        </appender>
        <root level="info">
            <appender-ref ref="CONSOLE" />  
        </root>
        <!--<logger name="com.example" level="DEBUG">-->
        <!--<appender-ref ref="baselog" />-->
        <!--</logger>-->
    </configuration>
    

    如果后续用到更多的日志需求,再回来补充,最近看到黄勇的架构探险上对于日志体系的分析,有很多很有意思的东西

    相关文章

      网友评论

        本文标题:Java日志体系

        本文链接:https://www.haomeiwen.com/subject/sbfubxtx.html