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<E> extends LifeCycle, ContextAware, FilterAttachable<E> {
    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的父类。

类图:

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、文件唯一命名(使用时间戳)

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

    <property name="LOG_HOME" value="E:/log/" />
    <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss" />
    <appender name="fileAppender" class="ch.qos.logback.core.FileAppender">
        <file>${LOG_HOME}${bySecond}.log</file><!-- 日志文件路径 -->
    </appender>

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

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

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什么时候发生轮转行为。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值