文章11 | 阅读 5975 | 点赞0
StatusLogger是用来打印Log4J2的信息的,包括加载插件的过程,信息,解析自定义配置的信息,譬如当系统未检测到自定义的配置时:
No log4j2 configuration file found. Using default configuration: logging only errors to the console. Set system property 'log4j2.debug' o show Log4j2 internal initialization logging.
# StatusLogger的队列中保存的最大日志条数,默认200条
log4j2.StatusLogger.entries
# status listeners的日志级别默认是warn
log4j2.StatusLogger.level
# 布尔值,如果配置为true,则会显示所有的status日志
log4j2.debug
<Configuration status="info" monitorInterval="60">
<!--中间部分省略-->
<Configuration/>
status的合法属性在Level类中有定义, 默认level是ERROR,不区分大小写
static {
OFF = new Level("OFF", StandardLevel.OFF.intLevel());
FATAL = new Level("FATAL", StandardLevel.FATAL.intLevel());
ERROR = new Level("ERROR", StandardLevel.ERROR.intLevel());
WARN = new Level("WARN", StandardLevel.WARN.intLevel());
INFO = new Level("INFO", StandardLevel.INFO.intLevel());
DEBUG = new Level("DEBUG", StandardLevel.DEBUG.intLevel());
TRACE = new Level("TRACE", StandardLevel.TRACE.intLevel());
ALL = new Level("ALL", StandardLevel.ALL.intLevel());
}
private StatusLogger(final String name, final MessageFactory messageFactory) {
//调用AbstractLogger的构造方法
super(name, messageFactory);
//真正的底层是依托于SimpleLLogger
this.logger = new SimpleLogger("StatusLogger", Level.ERROR, false, true, false, false, Strings.EMPTY,
messageFactory, PROPS, System.err);
//设置listener的日志等级, 默认是WARN
this.listenersLevel = Level.toLevel(DEFAULT_STATUS_LEVEL, Level.WARN).intLevel();
//如果系统属性log4j2.debug配置为true,则把日志等级设置为TRACE
if (isDebugPropertyEnabled()) {
logger.setLevel(Level.TRACE);
}
}
* 打印日志logMessage
```java
public void logMessage(final String fqcn, final Level level, final Marker marker, final Message msg,
final Throwable t) {
StackTraceElement element = null;
//如果函数名不为null,则打印调用栈信息
if (fqcn != null) {
element = getStackTraceElement(fqcn, Thread.currentThread().getStackTrace());
}
//StatusData是要打印的日志以及相关的调用信息
final StatusData data = new StatusData(element, level, msg, t, null);
msgLock.lock();
try {
messages.add(data);
} finally {
msgLock.unlock();
}
// 如果打开了debug,则直接打印所有信息
if (isDebugPropertyEnabled()) {
logger.logMessage(fqcn, level, marker, msg, t);
} else {
//如果有status listener,则status listener通知listener去处理
if (listeners.size() > 0) {
for (final StatusListener listener : listeners) {
if (data.getLevel().isMoreSpecificThan(listener.getStatusLevel())) {
listener.log(data);
}
}
} else {
//调用SimpleLogger的方法打印日志
logger.logMessage(fqcn, level, marker, msg, t);
}
}
}
注意:
private final Queue<StatusData> messages = new BoundedQueue<>(MAX_ENTRIES);
private class BoundedQueue<E> extends ConcurrentLinkedQueue<E> {
private static final long serialVersionUID = -3945953719763255337L;
private final int size;
BoundedQueue(final int size) {
this.size = size;
}
@Override
public boolean add(final E object) {
super.add(object);
while (messages.size() > size) {
messages.poll();
}
return size > 0;
}
}
public void logMessage(final String fqcn, final Level mgsLevel, final Marker marker, final Message msg,
final Throwable throwable) {
final StringBuilder sb = new StringBuilder();
//格式化时间日志
if (showDateTime) {
final Date now = new Date();
String dateText;
synchronized (dateFormatter) {
dateText = dateFormatter.format(now);
}
sb.append(dateText);
sb.append(SPACE);
}
//打印日志等级
sb.append(mgsLevel.toString());
sb.append(SPACE);
if (Strings.isNotEmpty(logName)) {
sb.append(logName);
sb.append(SPACE);
}
sb.append(msg.getFormattedMessage());
//格式化mdc
if (showContextMap) {
final Map<String, String> mdc = ThreadContext.getImmutableContext();
if (mdc.size() > 0) {
sb.append(SPACE);
sb.append(mdc.toString());
sb.append(SPACE);
}
}
//处理异常
final Object[] params = msg.getParameters();
Throwable t;
if (throwable == null && params != null && params.length > 0
&& params[params.length - 1] instanceof Throwable) {
t = (Throwable) params[params.length - 1];
} else {
t = throwable;
}
//这里的stream,如果是statusLogger的话,这里默认是System.err, 也就是说打印到错误输出流
stream.println(sb.toString());
if (t != null) {
stream.print(SPACE);
t.printStackTrace(stream);
}
}
本文简单的介绍了一下StatusLogger的参数配置,用途,以及其底层的实现原理。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/sweetyi/article/details/105160591
内容来源于网络,如有侵权,请联系作者删除!