Logback中文网:Logback学习笔记(五)Logback-core中的Appenders

一、什么是Appender

logback将写入日志事件的任务委托给一个名为 appender 的组件,Appender 必须实现 ch.qos.logback.core.Appender接口。

Appender接口的源码:

package ch.qos.logback.core;

import ch.qos.logback.core.spi.ContextAware;
import ch.qos.logback.core.spi.FilterAttachable;
import ch.qos.logback.core.spi.LifeCycle;

public interface Appender extends LifeCycle, ContextAware, FilterAttachable {
    String getName();

    void doAppend(E var1) throws LogbackException;

    void setName(String var1);
}

doAppender()方法接收一个泛型参数E作为唯一的参数。E的实际参数类型取决于logback模块。在logback-classic模块里面,E的类型是ILoggingEvent。在logback-access模块里面,E的类型是AccessEvent。doAppend()是logback框架里面最重要的模块。它的责任是将日志事件进行格式化,然后输出到对应的设备上。

Appender都是是实体类,这样可以确保他们通过名字被引用。Appender接口继承了FilterAttachable接口。使得一个一个或多个过滤器可以附加到appender实例上。

Appender 最基本的责任是将日志事件进行输出。然而,它们可以委托Layout 或者Encoder对象来对日志事件进行格式化。每一个 layout/encoder 有且只与一个 appender 相关联。例如,SocketAppender 仅仅序列化日志事件,然后再通过线路传输。

AppenderBase

ch.qos.logback.core.AppenderBase 是一个抽象类,实现了 Appender 接口。它提供了基本方法供所有 appender 使用。例如:获取和设置名称的方法、激活状态、布局以及过滤器。它是 logback 中所有appender 的父类。尽管是一个抽象类,但是AppenderBase还实现了Append接口中的doAppend()方法。

AppenderBase源码摘要:

    public synchronized void doAppend(E eventObject) {
        if (!this.guard) {
            try {
                this.guard = true;
                if (this.started) {
                    if (this.getFilterChainDecision(eventObject) == FilterReply.DENY) {
                        return;
                    }

                    this.append(eventObject);
                    return;
                }

                if (this.statusRepeatCount++ < 5) {
                    this.addStatus(new WarnStatus("Attempted to append to non started appender [" + this.name + "].", this));
                }
            } catch (Exception var6) {
                if (this.exceptionCount++ < 5) {
                    this.addError("Appender [" + this.name + "] failed to append.", var6);
                }

                return;
            } finally {
                this.guard = false;
            }
        }
    }

doAppend() 的实现是 synchronized 的。不同的线程通过同一个 appender 打印日志是线程安全的。因为这种同步策略并不总是合适,所以logback提供了ch.logback.core.UnsynchronizedAppenderBase类,跟AppenderBase类十分相似。

二、Logback-core

 Logback-core 为 logback 其他模块的构建奠定了基础。一般来说,logback-core 的组件需要一些定制,尽管很少。接下来我们介绍几种可以开箱即用的 appender。

1、OutputStreamAppender

OutputStreamAppender 将事件附加到java.io.OutputStream上。这个类提供了其它 appender 构建的基础服务。用户通常不会直接实例一个 OutputStreamAppender 实例。因为一般来说 java.io.OutputStream 类型不能方便的转为 String。因为在配置文件中没有方法去直接指定一个OutputStream 目标对象。简单来说,你不能通过配置文件配置一个 OutputStreamAppender。但是这并不意味着 OutputStreamAppender缺少配置属性。

  • encoder:Encoder类型,决定通过哪种方法将事件写入OutputStreamAppender,Encoder后面介绍;
  • immediateFlush:boolean类型,默认为true,立即刷新输出流可以确保日志事件被立即写入,并且可以保证一旦你的应用没有正确关闭appender日志事件也不会丢失。设置为false时,可以提高日志吞吐量,但是不能保证应用不正常关闭时,日志数据不会丢失。

OutputStreamAppender是其他三个appender的父类,分别是 ConsoleAppender、FileAppender以及 RollingFileAppender。FileAppender又是RollingFileAppender的父类。

类图:

Logback中文网:Logback学习笔记(五)Logback-core中的Appenders_第1张图片

2、ConsoleAppender

ConsoleAppender是将日志打印到控制台,更进一步说数通过System.out或System.error来进行输出。默认为System.out。ConsoleAppender通过用户指定的encoder类格式化日志事件。System.out和System.error被包装在OutputStreamWriter中。

  • encoder:同OutputStreamAppender
  • target:String类型,System.out 或 System.error,默认为前者。
  • withJansi:boolean,开启使用ANSI彩色代码,默认为false。依赖jansi这个jar包。

3、FileAppender

FileAppender是OutputStreamAppender的子类,将日志输出到文件中。通过file来指定目标文件。如果该文件存在,根据append的值,要么将日志追加到文件中,要么该文件被截断。

  • qppend:boolean类型,如果为true,日志会被追加到文件中,否则文件会被截断。默认为true。
  • encoder:参见outputStreamAppender;
  • file:String类型,要写入文件的名称,如果文件不存在,则新建。
  • prudent:boolean类型,在严格模式下,FileAppender会将日志安全的写入指定文件。即使在不同的 JVM 或者不同的主机上运行 FileAppender实例。默认的值为false。严格模式可以与RollingFileAppender 结合使用。严格模式也意味着 append 属性被自动设置为 true 。严格模式依赖排他文件锁。
  • immediateFlush:同OutputStreamAppender。

4、文件唯一命名(使用时间戳)

在应用的开发阶段或者短期应用中,例如:批处理程序,在每次应用启动的时候创建一个新的日志文件。通过 元素可以轻易做到这点。

    
    
    
        ${LOG_HOME}${bySecond}.log
    

timestamp元素需要两个强制的属性 key 跟 datePattern 以及可选的属性 timeReference

  • key 属性的值是来区分哪个 timestamp 元素,并且在后续的配置中可以通过 TODO 变量替换来使用。
  • datePattern 属性用于将当前时间格式化成字符串。日期格式必须遵循 SimpleDateFormat 中的规范。
  • timeReference 表示时间戳引用哪个时间。默认为解析配置文件的时间,也就是当前时间。但是,在一些特定的情况下,可以设置为上下文初始化的时间。通过 设置 timeReference 的值为ContextBirth 。

    
    ...

5、RollingFileAppender

RollingFileAppender 继承自 FileAppender,具有轮转日志文件的功能。例如RollingFileAppender将日志输出到log.txt文件,在满足特定的条件之后,将日志输出到另一个文件。

与RollingFileAppenter  进行交互的有两个重要的子组件。第一个是RollingPolicy,它负责日志轮转的功能。另一个是TriggeringPolicy ,它负责日志轮转的时机。所以RollingPolicy 负责怎么轮转,TtiggeringPolicy负责什么时候轮转。

为了让 RollingFileAppender 生效,必须同时设置 RollingPolicy与 TriggeringPolicy 。但是,如果 RollingPolicy也实现了 TriggeringPolicy 接口,那么只需要设置前一个就好了。

RollingFileAppender 可以配置的属性,file、append、encoder和prident等,这些属性参见上面的介绍,除了这还有:

  • rollingPolicy:RollingPolicy类型,当轮转发生是,指定RollingFileAppender的行为。后面详细讲。
  • triggeringPolicy:TriggeringPolicy类型,告诉RollingFileAppender什么时候发生轮转行为。

 

你可能感兴趣的:(Logback,日志)