一、什么是Encoder?
Encoder负责转换日志事件为字节数组并将字节数组输出到输出流中,编码器是在logback 0.9.19版本中引入的,以前老版本中大多数appenders依赖layout转换日志事件,然后使用java.io.Writer写入。先前版本中,用户通常会在FileAppender中嵌PatternLayout,从logback 0.9.19版本开始,FileAppender和它的子类只需配置Encoder即可,而不再需要配置Layout。
编码器能完全控制写入什么字节以及什么时候写入到输出流,下面是Encoder接口:
package ch.qos.logback.core.encoder; 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; }
二、Encoder分类
1、LayoutWrappingEncoder
直到logback 0.9.19版本,许多输出源依赖于Layout实例控制日志输出格式。因为基于Layout需要大量的代码,因此logback为编码器提供了一种方式与布局相互操作。LayoutWrappingEncoder缩小了encoders和layouts之间的差距,它实现了Encoder接口并且包装了Layout,并把转换日志事件对象的任务委托给Layout。
下面是LayoutWrappingEncoder类的部分代码,阐述了如何委托给包装的layout。
package ch.qos.logback.core.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); } } }
2、PatternLayoutEncoder
PatternLayout是最常用的布局,logback提供了通用案例:PatternLayoutEncoder,该类对LayoutWrappingEncoder进行了扩展,从Logback 0.9.19版本开始,无论FileAppender及其子类是否配置了PatternLayout,PatternLayoutEncoder都会被使用,请参考logback相关错误代码条目。
2.1 Output pattern string as header(将输出格式字符串作为头部信息)
为了促进日志文件的解析,logback可以在日志文件上插入日志输出格式,该特性默认不可用,通过设置outputPatternAsHeader属性为true可以启用,如下:
<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>
#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
以"#logback.classic pattern"开头的行就是插入的日志格式行。