Chapter 5: Encoders

What is an encoder

编码器负责将事件转化为字节数组,并将字节数组转换成一个OutputStream 。

Encoder ---> Byte[] ---> OutputStream

 

在0.9.19版本之前,大多数的appender都依赖layout布局组件将事件转换为字符串String

在使用java.io.Writer将其写入到文件

在0.9.19版本之前,对FileAppender将在内部嵌套PatternLayout进行样式设置

从0.9.19版本开始,FileAppender将通过Encoder设置样式,不再设置layout属性了

 

This appender no longer admits a layout as a sub-component, set an encoder instead.

to (GOOD)

<appender name="FILE" class="ch.qos.logback.core.FileAppender">
  <file>testFile.log</file>
  ...
  <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    <pattern>%msg%n</pattern>
  </encoder>
</appender>  

or the shorter equivalent (GOOD) 

<appender name="FILE" class="ch.qos.logback.core.FileAppender">
  <file>testFile.log</file>
  ...
  <!-- encoders are assigned the type 
       ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
  <encoder>
    <pattern>%msg%n</pattern>
  </encoder>
</appender> 

 

For layout type other than PatternLayout, for example HTMLLayout, your configuration files need to be changed

to (GOOD)

<appender name="FILE" class="ch.qos.logback.core.FileAppender">
  <file>testFile.log</file>
  ...
  <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
    <layout class="ch.qos.logback.classic.html.HTMLLayout">
      <pattern>%msg%n</pattern>
    </layout>
  </encoder>
</appender> 

 

Layouts仅仅能够将event转换为某种样式的字符串String

此外,鉴于Layout无法控制何时对event进行写出,也没有批处理能力

Encoder不仅提供了写出字节数组的格式,还可以控制何时进行写出操作

Encoder兼备Layout样式和决定日志写出时机的功能

到目前为止,PatternLayoutEncoder是唯一真正使用的Encoder

PatternLayoutEncoder包装了一个LayoutPattern,从而提供了设置样式的功能

 

Encoder负责将event转换为Byte[],并将结果写到合适的OutputStream流中

这样,appender就可以通过Encoder完全控制何时什么bytes进行写出操作

 

LayoutWrappingEncoder

直到logback版本0.9.19 ,许多appender都依赖于布局实例来控制日志输出格式

由于Layout 的接口已经提供了大量的样式设置功能,我们只需要将Encoder与Layout结合在一起即可

LayoutWrappingEncoder作为一个桥梁,有效的将Encoder与Layout两者结合在一起

LayoutWrappingEncoder实现了Encoder接口,并对Layout进行了包装(Layout将event转换为字符串)

 

由此,得到:

Event ---> Layout ---> Formated String ---> Encoder ---> Byte[] ---> OutputStream 

 

LayoutWrappingEncoder

package ch.qos.logback.core.encoder;

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

  protected Layout<E> layout;
  private Charset charset;
  private boolean immediateFlush = true;

  public void doEncode(E event) throws IOException {
    String txt = layout.doLayout(event);
    outputStream.write(convertToBytes(txt));
    if (immediateFlush)
      outputStream.flush();
  }

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

 

 

PatternLayoutEncoder

鉴于PatternLayout是最常用的布局, logback这种常见的用例满足与PatternLayoutEncoder 

immediateFlush property

true: 保证日志及时输出到文件,会影响系统处理日志的吞吐量;

false:可以大大提高日志处理的throughout,大概5倍,但有可能造成日志丢失(appender没有正确关闭);

<appender name="FILE" class="ch.qos.logback.core.FileAppender"> 
  <file>foo.log</file>
  <encoder>
    <pattern>%d %-5level [%thread] %logger{0}: %msg%n</pattern>
    <!-- this quadruples logging throughput -->
    <immediateFlush>false</immediateFlush>
  </encoder> 
</appender>

 

 

Output pattern string as header

在输入日志的上方,输出日志的Pattern

默认为false,不在头部输出样式

<appender name="FILE" class="ch.qos.logback.core.FileAppender"> 
  <file>foo.log</file>
  <encoder>
    <pattern>%d %-5level [%thread] %logger{0}: %msg%n</pattern>
    <outputPatternAsHeader>true</outputPatternAsHeader>
  </encoder> 
</appender>

 

This will result output akin to the following in the log file: 

#logback.classic pattern: %d [%thread] %-5level %logger{36} - %msg%n
2012-04-26 14:54:38,461 [main] DEBUG com.foo.App - Hello world
2012-04-26 14:54:38,461 [main] DEBUG com.foo.App - Hi again

 

%d                   日期:2012-04-26 14:54:38,461

[%thread]         线程:[mian]

%-5level           级别:DEBUG

%logger{36}  类路径:com.foo.App

%msg               消息:Hello world

%n                    换行

 

 

 

 

 

 

 

 

 

猜你喜欢

转载自schy-hqh.iteye.com/blog/2030717