ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

logback_2-Encoder,Layout

2021-12-17 23:31:30  阅读:130  来源: 互联网

标签:Layout String encoder PatternLayoutEncoder LoggingEvent Encoder logback event


文章目录

一 What is an encoder

Encoders就是把 LoggingEvent转化为字节数组并向 OutputStream(输出流)写出的这么个东东.

Layouts 就是能够把 LoggingEvent转换成字符串的东东.

相比较之下, Layouts既不能控制 LoggingEvent何时输出, 也不能把 LoggingEvent聚合成批(batches). 但是 Encoder既能控制 LoggingEvent输出格式,也能控制 LoggingEvent何时输出.

不过PatternLayoutEncoder才是真正有用的encoder. 它是对PatternLayout的包装.

咋说呢, encoder的抽象有点鸡肋,有啥不干脆把 layout的职责也涵盖了算了?

二 Encoder interface

Encoder有2个作用:

  • 转化LoggingEvent为字节数组
  • 将字节数组通过合适的OutputStream输出
public interface Encoder<E> extends ContextAware, LifeCycle {

   /**
   * This method is called when the owning appender starts or whenever output
   * needs to be directed to a new OutputStream, for instance as a result of a
   * rollover.
   */
  void init(OutputStream os) throws IOException;

  /**
   * Encode and write an event to the appropriate {@link OutputStream}.
   * Implementations are free to defer writing out of the encoded event and
   * instead write in batches.
   */
  void doEncode(E event) throws IOException;


  /**
   * This method is called prior to the closing of the underling
   * {@link OutputStream}. Implementations MUST not close the underlying
   * {@link OutputStream} which is the responsibility of the owning appender.
   */
  void close() throws IOException;
}

三 LayoutWrappingEncoder

LayoutWrappingEncoder bridges(桥接) the gap between encoders and layouts. It implements the encoder interface and wraps a layout to which it delegates the work of transforming an event into string.

(注: LayoutWrappingEncoder的出现本质上是历史设计缺陷, 其实 Layout是没有必要单独拎出来的抽象, 而是完全可以作为 Encoder的一部分)

看代码就一目了然:

public class LayoutWrappingEncoder<E> extends EncoderBase<E> {

  protected Layout<E> layout;
  private Charset charset;
 
   // encode a given event as a byte[]
   public byte[] encode(E event) {
     String txt = layout.doLayout(event);
     return convertToBytes(txt);
  }

  private byte[] convertToBytes(String s) {
    if (charset == null) {
      return s.getBytes();
    } else {
      return s.getBytes(charset);
    }
  } 
}

四 PatternLayoutEncoder

PatternLayoutEncoder是应用最为广泛 的layout,也是对 LayoutWrappingEncoder的扩展(扩展了PatternLayout职责). 从 0.9.19 版本的logback 开始, FileAppender及其子类只要配置PatternLayout就一定会使用 PatternLayoutEncoder.

五 Layouts

Layouts就是把 LoggingEvent格式化成字符串的组件(component).
我们看看接口定义:

public interface Layout<E> extends ContextAware, LifeCycle {

  String doLayout(E event);
  String getFileHeader();
  String getPresentationHeader();
  String getFileFooter();
  String getPresentationFooter();
  String getContentType();
}

在logback-classic里实际只会处理 ILoggingEvent 类型的 Event,而不会处理 AccessEvent类型的Event

六 PatternLayout

我们可以自己写一个 Layout,但坦白说, 官方给出来的 Layout已经能够满足日常需要了.往深了想, 打个日志而已, 把格式打出花来,那不也只是日志吗?

logback-classic 有一个很灵活的PatternLayout,当然它的主要职责也是拿到一个logging event,返回一个字符串.只不过这个字符串是被 PatternLayout格式化的. 格式化就是所谓的conversion pattern.

logback的 conversion pattern 和 C语言的printf 很类似.

尽管前面已经提到过, 但 FileAppender及其子类需要一个Encoder.比如常用的ConsoleAppender就使用了PatternLayoutEncoder.

我们看个栗子:

static public void main(String[] args) throws Exception {
    Logger rootLogger = (Logger)LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
    LoggerContext loggerContext = rootLogger.getLoggerContext();
    // we are not interested in auto-configuration
    loggerContext.reset();

    PatternLayoutEncoder encoder = new PatternLayoutEncoder();
    encoder.setContext(loggerContext);
    encoder.setPattern("%-5level [%thread]: %message%n");
    encoder.start();

    ConsoleAppender<ILoggingEvent> appender = new ConsoleAppender<ILoggingEvent>();
    appender.setContext(loggerContext);
    appender.setEncoder(encoder); 
    appender.start();

    rootLogger.addAppender(appender);

    rootLogger.debug("Message 1"); 
    rootLogger.warn("Message 2");
  }

这里的conversion pattern 就是 %-5level [%thread]: %message%n 这一坨.

标签:Layout,String,encoder,PatternLayoutEncoder,LoggingEvent,Encoder,logback,event
来源: https://blog.csdn.net/qq_30118563/article/details/122006358

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有