org.apache.rocketmq.logging.inner.Appender
public abstract class Appender {
public static final int CODE_WRITE_FAILURE = 1;
public static final int CODE_FLUSH_FAILURE = 2;
public static final int CODE_CLOSE_FAILURE = 3;
public static final int CODE_FILE_OPEN_FAILURE = 4;
public final static String LINE_SEP = System.getProperty("line.separator");
boolean firstTime = true;
protected Layout layout;
protected String name;
protected boolean closed = false;
可以看到Appender内部最重要的就是这个Layout,翻译为分层。
最重要的方法是
doAppend( )
public synchronized void doAppend(LoggingEvent event) {
if (closed) {
SysLogger.error("Attempted to append to closed appender named [" + name + "].");
return;
}
this.append(event);
}
会往Appender内继续追加日志事件LoggingEvent,再看下日志事件LoggingEvent是什么
org.apache.rocketmq.logging.inner.LoggingEvent
可以看到这就是一个比较具体的“日志”了,内部包含了一条日志所应该包含的信息:
public class LoggingEvent implements java.io.Serializable {
transient public final String fqnOfCategoryClass;
transient private Object message;
transient private Level level;
transient private Logger logger;
private String renderedMessage;
private String threadName;
public final long timeStamp;
private Throwable throwable;
比较特别的是日志对象里还包含了打印日志的工具Logger和线程名threadName
从日志体出来,回到Logger,往下走看到两个获取Logger的方法:
static public Logger getLogger(Class clazz) {
return getRepository().getLogger(clazz.getName());
}
public static Logger getRootLogger() {
return getRepository().getRootLogger();
}
也就是说在之前提到的DefaultLoggerRepository中,有两类Logger,除了普通的Logger以外,还有一个根日志器rootLogger,当然进入底层可以看到其实rootLogger也是一个普通的Logger,只不过命名为root
public Logger getRootLogger() {
return root;
}
public static class RootLogger extends Logger {
public RootLogger(Level level) {
super("root");
setLevel(level);
}
}
这里有一个重要的方法:callAppenders
public void callAppenders(LoggingEvent event) {
int writes = 0;
for (Logger logger = this; logger != null; logger = logger.parent) {
synchronized (logger) {
if (logger.appenderPipeline != null) {
writes += logger.appenderPipeline.appendLoopOnAppenders(event);
}
if (!logger.additive) {
break;
}
}
}
if (writes == 0) {
getRepository().emitNoAppenderWarning(this);
}
}
可以看到这个日志,核心是把Logger都塞到管道appenderPipeline里面。而这个起始的变量writes,就是记录appenderPipeline中logger总数的值,当总数为0时会抛出告警。