官网
Encoder是什么
Encoder负责将事件转化为字节数组,并将该字节数组写出到OutputStream中。 在Logback版本0.9.19中引入了Encoder
。在以前的版本中,大多数Appender
都依赖于layout
将事件转换为字符串并使用java.io.Writer将其写出。在以前的版本中,用户会将PatternLayout嵌套在FileAppender中。从0.9.19开始,FileAppender和子类期望使用Encoder
,并且不再采用layout
。
为什么要进行重大变革?
布局将在下一章中详细讨论,它只能将事件转换为字符串。此外,由于layout
无法控制何时写入事件,因此layout
无法将事件聚合为批处理。与此相比,encoder
不仅可以完全控制要写出的字节的格式,还可以控制何时(以及是否)可以写出这些字节。
目前,PatternLayoutEncoder
是唯一真正有用的Encoder
。它只是包装完成大部分工作的PatternLayout。因此,似乎除了不必要的复杂性之外,Encoder
并没有带来太多好处。但是,我们希望随着新型强大Encoder
的出现,这种印象会改变。
Encoder接口
Encode
r负责将传入事件转换为字节数组,并将结果字节数组写到适当的OutputStream
上。 因此,Encoder
可以完全控制什么字节以及何时将字节写入Appender
所维护的OutputStream
中。
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;
}
LayoutWrappingEncoder
由于在老版本中,存在大量基于Layout
的代码,我们需要一种办法帮助我们使用Encoder
来内部操作Layout
,这就是LayoutWrappingEncoder
存在的原因。它实现了Encoder
接口,并包装了一个Layout
,将事件转换为字符串的工作委派给了该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);
}
}
}
PatternLayoutEncoder
鉴于PatternLayout
是最常用的布局,因此Logback
通过PatternLayoutEncoder
迎合了这种常见用例,PatternLayoutEncoder
是LayoutWrappingEncoder
的扩展(子类),仅限于包装PatternLayout
实例。
示例:
<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>
outputPatternAsHeader
true 表示将pattern格式作为header打印出来,效果如下:
这里只对转化符做简单的说明
%d
表示当前时间,默认时间格式;
%thread
表示线程名;
%-5level
表示应将日志记录事件的级别调整为5个字符的宽度;
%logger{36}
一种简便的方式表达logger name
%msg
日志内容
%n
换行
这些转换符都可以在 Layout中找到。