logback–进阶–05–自定义Appenders
代码位置
https://gitee.com/DanShenGuiZu/learnDemo/tree/master/logback-learn
1、介绍
1.1、继承关系图
可以看到Appender 接口数核心接口
1.2、Appender 接口
Logback 将写日志记录事件的任务委派给appender组件。
Appenders组件必须实现ch.qos.logback.core.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> {
/**
* Get the name of this appender. The name uniquely identifies the appender.
*/
String getName();
/**
* This is where an appender accomplishes its work. Note that the argument is of type Object.
*
* E的实际类型取决于logback模块。
* 在logback-classic模块中,E的类型为ILoggingEvent;
* 在logback-access模块中,类型的E为AccessEvent。
* doAppend()方法是logback框架中比较重要的方法,它负责以合适的格式将日志记录事件输出到合适的输出设备中
* @param event
*/
void doAppend(E event) throws LogbackException;
/**
* Set the name of this appender. The name is used by other components to
* identify this appender.
*
*/
void setName(String name);
}
- Appender接口扩展了FilterAttachable接口。所以可以将一个或多个过滤器关联到appender实例。
- Appender负责输出日志记录事件。但是,他们可以将事件的实际格式委托给Layout或Encoder对象处理。
- 每个layout和encoder都只能与有且一个appender相关联。
- 某些appender具有内置或固定的事件格式。因此,它们不需要Layout或Encoder。
2、通过AppenderBase类实现一个自定义Appenders
2.1、代码
logback.xml
<configuration >
<!--定义变量-->
<property scope="context" name="myHost" value="localhost"/>
<property scope="context" name="myIP" value="127.0.0.1"/>
<appender name="MyAppender" class="fei.zhou.logbacklearn.business.appender.MyAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
<myHost>${myHost}</myHost>
<myIP>${myIP}</myIP>
</appender>
<logger name="fei.zhou.logbacklearn.business.appender.Test1" additivity="false" level="INFO">
<appender-ref ref="MyAppender"/>
</logger>
</configuration>
Test1
public class Test1 {
private static final Logger log = LoggerFactory.getLogger(Test1.class);
public static void main(String[] args) {
log.trace("------trace");
log.debug("------debug");
log.info("------info");
log.warn("------warn");
log.error("------error");
}
}
MyAppender
import ch.qos.logback.core.AppenderBase;
import ch.qos.logback.core.Layout;
import ch.qos.logback.core.encoder.Encoder;
import ch.qos.logback.core.status.ErrorStatus;
/**
*
* 自定义Appender
*
*/
public class MyAppender<E> extends AppenderBase<E> {
private String myHost;
private String myIP;
protected Layout<E> layout;
protected Encoder<E> encoder;
@Override
public void start() {
int errors = 0;
if (this.layout == null && this.encoder == null) {
this.addStatus(
new ErrorStatus("No layout && encoder set for the appender named \"" + this.name + "\".", this));
++errors;
}
if (errors == 0) {
super.start();
}
}
@Override
public void stop() {
super.stop();
System.out.println("停止........");
}
@Override
protected void append(E event) {
// 日志转换
String msg = encodeMessage(event);
// 可以将这里的消息 发送到MQ中
System.out.println("MyAppender-->" + myHost + ":" + myIP + ":处理消息--->" + msg);
}
// 日志转换
private String encodeMessage(E logEvent) {
if (this.encoder != null) {
return new String(this.encoder.encode(logEvent));
}
return this.layout.doLayout(logEvent);
}
// ----------get set----------
public void setMyHost(String myHost) {
this.myHost = myHost;
}
public void setMyIP(String myIP) {
this.myIP = myIP;
}
public Layout<E> getLayout() {
return layout;
}
public void setLayout(Layout<E> layout) {
this.layout = layout;
}
public Encoder<E> getEncoder() {
return encoder;
}
public void setEncoder(Encoder<E> encoder) {
this.encoder = encoder;
}
}