java日志框架之logback详解

一、logback介绍

Logback是流行的log4j项目的继承者,Logback的体系结构足够通用,可以应用于不同的环境。目前,logback分为三个模块,即logback-core、logback-classic和logback-access。

logback-core模块为其他两个模块奠定了基础。

logback-classic模块可以被同化为log4j的显著改进版本。此外,logback-classic本机实现了SLF4J API,这样您就可以随时在logback和其他日志框架(如log4j或java.util)之间来回切换。

logback-access模块与Servlet容器(如Tomcat和Jetty)集成,以提供HTTP-access日志功能。请注意,您可以轻松地在logback-core之上构建自己的模块。

二、logback较log4j的优势

  1. 内核重写、测试充分、初始化内存加载更小,这使得logback性能相比log4j的性能得到了较大的提升。
  2. logback继承了log4j,并且实现了SLF4JAPI,这使得logback能够和其他日志框架相互替换。
  3. logback官方文档比较丰富。
  4. logback支持自动扫描重新加载配置文件,扫描过程比较快,并且安全,它并不需要额外的创建扫描线程。
  5. 自动移除旧的日志文件,比如那些日志文件超过很长时间的都会都当成移除的对象,可以控制已经产生日志文件的最大数量。
  6. 自动压缩已经打印出来的日志信息,压缩的这个过程是一个异步过程,在压缩过中并不受影响。

 三、logback加载

简单的分析一下logback加载的过程,当我们使用logback-classic.jar包时,应用启动后,将会按照如下的顺序进行扫描一些配置文件。

  • 在系统配置文件System Properties中寻找是否有logback.configurationFile对应的value.
  • 如果没有配置以上的属性值,将会在classpath中查找logback.groovy文件。
  • 如果找不到文件,就继续在classpath中查找logback-test.xml文件。
  • 如果找不到文件,就继续在classpath中继续查找logback.xml文件。
  • 如果找不到文件,将自动调用ch.qos.logback.classic.BasicConfigurator在控制台输出日志。

 加载不顺序如下图所示:

java日志框架之logback详解_第1张图片

以上任何一项找到后,就不会再继续向下查找配置文件,如果都没有找到这些文件,就会调用ch.qos.logback.classic.BasicConfigurator的configure方法,构造出一个ConsoleAppender用于向控制台输出默认配置的日志信息,输出的日志信息为"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"。

四、logback配置文件的一些标签及其属性介绍

java日志框架之logback详解_第2张图片

configuration为logback.xml配置文件的根标签,主要含有一下几个属性:

  • scan:当scan被设置为true时,当配置文件发生改变,将会被重新加载,默认值为true。
  • scanPeriod:检测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认为毫秒,只有当scan为true时,这个值才默认生效,默认时间间隔为1分钟。
  • debug:当这个值被设置为true时,将会打印出logback内部日志信息,实时查看logback内部运行的状况,默认为false。

    

接下来看看,他们都是同一种元素,都为元素,但是这个标签只有一个level属性,因为它的name属性就是ROOT。主要有以下几个属性:

  • name:必选属性,用来指定此约束于哪个包或者哪个特定的类。
  • level:可选属性,用来指定打印级别,五个常用的打印级别从低到高分别为TRACE、DEBUG、INFO、WARN、ERROR,如果没有设置次级别,那么当前logger会继承上级的级别。
  • additivity:可选属性,用来指定是否向上级传递打印信息,默认为true。

接下来通过代码来测试几种情况:

logback.xml的配置为:



    
        
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n
        
    

    
        
    


测试代码为:

public class Main {

    public static void main(String[] args) {

        Logger logger = LoggerFactory.getLogger(Object.class);
        logger.trace("-------trace---------");
        logger.debug("-------debug---------");
        logger.info("-------info---------");
        logger.warn("-------warn---------");
        logger.error("-------error---------");

    }
}

打印结果如下:

从logback.xml中,分析出,当main方法运行时,root节点将日志级别大于等于debug的日志信息交给已经配置好的STDOUT的appender进行处理,“STDOUT”将信息打印到控制台上。
再对logback.xml进行修改,增加一个



    
        
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n
        
    

    
    
    
        
    



运行日志信息的情况如下:

当运行的时候,会根据logger的name的属性值找到指定包下或者特定的类。

  1. 此时的logger没有指定打印级别,将继承root的打印级别,即level=DEBUG.
  2. 没有配置additivity的信息,默认为true,表示将日志信息向父传递。
  3. 没有配置,表示此logger不会打印任何信息。

再来一个例子:



    
        
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n
        
    

    
    
        
    
    
        
    



 

 如果上面的例子懂了,那么再来理解一下这个例子:

  • LoggerFactory.getLogger(Object.class)首先会找到name="java.lang"包下的类,并且将日志级别等于或者大于WARN的日志信息用STDOUT的这个appender打印出来。
  • 因为name=java.lang的这个logger没有配置additity,那么additivity=true,默认是将打印信息传递给父级,即name="java"这个logger,但是由于name="java"的这个同样没有设置additivity,默认为true,这个name="java"的将打印信息继续上传,传递到,将由STDOUT的appender将日志信息打印输出。

接下来了解作为的子节点,有两个必要的属性:

  • name:用来指定的名称,标签可以通过来用appender打印日志信息。
  • class:用来指定类的权限定名。

对于有多种,上面演示的ConsoleAppender类用来向控制台打印日志信息的。

 
        
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n
        
    

另一种是将日志信息输出到文件中的FileAppender,其内部的节点主要有以下几个:

  • 表示写入的文件名,可以使用相对目录也可以是绝对目录,如果上级目录不存在,则可以自动创建
  • :表示文件的追加方式,如果为true,则表示直接在文件末尾进行文件的追加,如果是false,表示覆盖的追加方式。
  • :表示日志输出的格式。
  • :默认值为false,如果设置成true,表示日志安全的写入文件,效率较低。

以下是FileAppender类型的配置文件的情况:

  
        
            E:/logback.log
        
        true
        
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n
        
        true 
    

还有一种RollingFileAppender,RollingFileAppender的作用是可以滚动记录日志文件,先将指定的日志文件提交到指定文件,当符合某个条件时再将日志记录到其他文件,当符合某个条件时再将日志记录到其他文件,RollingFileAppender配置更加灵活,因此用得更多。

  • :指定了滚动策略,定义RollingFileAppender的行为,有以下两个主要节点
  • :必要节点,包含文件名及"%d"转换符,%d可以是时间格式,用来设置日志文件名称
     
  • :可选节点,控制保留的归档文件的最大数量,如果超出数量就删除旧文件,如果设置每个月滚动且是6,则只保存最近6个月的文件
 
        
            rolling-file-%d{yyyy-MM-dd}.log
            6
        
        
            
                %-4relative [%thread] %-5level %logger{35} - %msg%n
            
        


    

节点主要的作用有:

  • 把日志信息转换为字节数组
  • 把字节数组写到输出流

其内部有一个节点,用来定义输出日志的格式,使用方式"%+转换符"的方式,如果要输出%,要用\%对%进行转义。

节点

节点是的一个子节点,表示在当前日志给出的日志级别再进行一次过滤,基本用到Filter有ch.qos.logback.classic.filter.LevelFiler和ch.qos.logback.filter.ThreshouldFilter。

针对LevelFilter这个类,它指的是将指定级别日志信息打印输出。来看一下下面的这个例子


        
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n
        

        
            ERROR
            ACCEPT
            DENY
        
    


    
        
    
    
        
    

运行结果:

 

这和前面讲过的例子一样,无非是加了一个过滤了日志的输出,没有加之前,该日志信息输出为WARN和ERROR级别的日志信息,因为加了,并且在标签中明确规定,只有level=ERROR级别的日志才能输出,因此最后只输出了Error级别的日志信息。

 

最后再测试一下ThreshouldFilter,配置文件如下:


        
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n
        

        
            INFO
        
    

 
    
        
    
    
        
    

运行结果:

的name=java.lang的日志级别为DEBUG,additivity默认为true,可以将日志信息传递到父级别name=java的,但是次中没有标签,所以该不打印日志信息,并且此的父级别也不打印,只有name=java.lang的打印,但是增加了的ThresholdFilter就会再次进行过滤,将指定大于特定级别的日志才能打印。

以上仅仅是自己做的一点小小的总结,有不足的地方还请大家指点。

你可能感兴趣的:(java日志框架之logback详解)