系列
背景
?該篇文章主要介紹Log4j2的日志輸出過(guò)程,核心流程包含獲取Logger對(duì)象和通過(guò)Logger輸出日志。
- Logger的獲取過(guò)程主要通過(guò)LoggerContext和LoggerRegistry來(lái)獲取。
- Logger的日志輸出主要通過(guò)Logger、LoggerConfig、AppenderControl、Appender進(jìn)行日志輸出
Logger獲取過(guò)程
Log4j2獲取Logger的過(guò)程主要從LoggerContext、LoggerRegistry處獲取Logger對(duì)象。
public class LogManager {
public static Logger getLogger(final String name) {
return name != null ? getContext(false).getLogger(name) :
getLogger(StackLocatorUtil.getCallerClass(2));
}
}
- LogManager通過(guò)LoggerContext來(lái)獲取Logger對(duì)象。
public class LoggerContext
public Logger getLogger(final String name, final MessageFactory messageFactory) {
// 通過(guò)LoggerRegistry來(lái)獲取Logger對(duì)象
Logger logger = loggerRegistry.getLogger(name, messageFactory);
if (logger != null) {
AbstractLogger.checkMessageFactory(logger, messageFactory);
return logger;
}
logger = newInstance(this, name, messageFactory);
loggerRegistry.putIfAbsent(name, messageFactory, logger);
return loggerRegistry.getLogger(name, messageFactory);
}
}
- LoggerContext通過(guò)LoggerRegistry來(lái)獲取Logger對(duì)象。
public class LoggerRegistry<T extends ExtendedLogger> {
public T getLogger(final String name, final MessageFactory messageFactory) {
return getOrCreateInnerMap(factoryKey(messageFactory)).get(name);
}
private Map<String, T> getOrCreateInnerMap(final String factoryName) {
Map<String, T> inner = map.get(factoryName);
if (inner == null) {
inner = factory.createInnerMap();
map.put(factoryName, inner);
}
return inner;
}
}
- LoggerRegistry內(nèi)部維護(hù)Logger對(duì)象。
日志輸出過(guò)程

- 整體日志輸出流程通過(guò)Logger、LoggerConfig、AppenderControl、Appender進(jìn)行日志輸出。
日志輸出源碼
public abstract class AbstractLogger
public void logIfEnabled(final String fqcn, final Level level, final Marker marker, final String message,final Throwable t) {
// 全局Filter和全局的日志級(jí)別進(jìn)行過(guò)濾
if (isEnabled(level, marker, message, t)) {
// 輸出日志
logMessage(fqcn, level, marker, message, t);
}
}
protected void logMessage(final String fqcn, final Level level,
final Marker marker, final String message,final Throwable t) {
// 通過(guò)ReusableMessageFactory組建消息體
logMessageSafely(fqcn, level, marker,
messageFactory.newMessage(message), t);
}
private void logMessageSafely(final String fqcn, final Level level,
final Marker marker, final Message msg, final Throwable throwable) {
try {
logMessageTrackRecursion(fqcn, level, marker, msg, throwable);
} finally {
ReusableMessageFactory.release(msg);
}
}
private void logMessageTrackRecursion(final String fqcn,
final Level level,
final Marker marker,
final Message msg,
final Throwable throwable) {
try {
incrementRecursionDepth(); // LOG4J2-1518, LOG4J2-2031
tryLogMessage(fqcn, getLocation(fqcn), level,
marker, msg, throwable);
} finally {
decrementRecursionDepth();
}
}
private void tryLogMessage(final String fqcn,
final StackTraceElement location,
final Level level,
final Marker marker,
final Message msg,
final Throwable throwable) {
try {
log(level, marker, fqcn, location, msg, throwable);
} catch (final Exception e) {
handleLogMessageException(e, fqcn, msg);
}
}
protected void log(final Level level, final Marker marker,
final String fqcn, final StackTraceElement location,
final Message message, final Throwable throwable) {
// strategy為AwaitCompletionReliabilityStrategy
final ReliabilityStrategy strategy =
privateConfig.loggerConfig.getReliabilityStrategy();
if (strategy instanceof LocationAwareReliabilityStrategy) {
// 繼續(xù)跟進(jìn)log過(guò)程
((LocationAwareReliabilityStrategy) strategy)
.log(this, getName(), fqcn, location, marker, level,
message, throwable);
} else {
// 省略代碼
}
}
}
- Logger通過(guò)PrivateConfig的isEnabled進(jìn)行過(guò)濾。
- Logger通過(guò)strategy的log方法進(jìn)行日志輸出。
public class Logger extends AbstractLogger implements Supplier<LoggerConfig> {
public boolean isEnabled(final Level level, final Marker marker,
final String message, final Throwable t) {
return privateConfig.filter(level, marker, message, t);
}
protected class PrivateConfig {
boolean filter(final Level level, final Marker marker,
final String msg, final Throwable t) {
// 先通過(guò)全局的Filter進(jìn)行過(guò)濾
final Filter filter = config.getFilter();
if (filter != null) {
final Filter.Result r =
filter.filter(logger, level, marker, (Object) msg, t);
if (r != Filter.Result.NEUTRAL) {
return r == Filter.Result.ACCEPT;
}
}
// 再判斷日志等級(jí)是否滿(mǎn)足要求
return level != null && intLevel >= level.intLevel();
}
}
}
- PrivateConfig的filter負(fù)責(zé)日志輸出過(guò)濾。
public class AwaitCompletionReliabilityStrategy
public void log(final Supplier<LoggerConfig> reconfigured,
final String loggerName, final String fqcn,
final StackTraceElement location, final Marker marker,
final Level level, final Message data, final Throwable t) {
// 通過(guò)LoggerConfig的進(jìn)行日志打印
final LoggerConfig config = getActiveLoggerConfig(reconfigured);
try {
config.log(loggerName, fqcn, location, marker, level, data, t);
} finally {
config.getReliabilityStrategy().afterLogEvent();
}
}
}
- AwaitCompletionReliabilityStrategy通過(guò)LoggerConfig進(jìn)行日志輸出。
public class LoggerConfig extends AbstractFilterable implements LocationAware {
public void log(final String loggerName, final String fqcn,
final StackTraceElement location, final Marker marker,
final Level level, final Message data, final Throwable t) {
List<Property> props = null;
if (!propertiesRequireLookup) {
props = properties;
}
// 創(chuàng)建LogEvent對(duì)象
final LogEvent logEvent =
logEventFactory instanceof LocationAwareLogEventFactory ?
((LocationAwareLogEventFactory) logEventFactory).createEvent(
loggerName, marker, fqcn, location, level, data, props, t) :
logEventFactory.createEvent(
loggerName, marker, fqcn, level, data, props, t);
try {
// 繼續(xù)執(zhí)行
log(logEvent, LoggerConfigPredicate.ALL);
} finally {
ReusableLogEventFactory.release(logEvent);
}
}
protected void log(final LogEvent event,
final LoggerConfigPredicate predicate) {
if (!isFiltered(event)) {
processLogEvent(event, predicate);
}
}
private void processLogEvent(final LogEvent event,
final LoggerConfigPredicate predicate) {
event.setIncludeLocation(isIncludeLocation());
if (predicate.allow(this)) {
callAppenders(event);
}
logParent(event, predicate);
}
protected void callAppenders(final LogEvent event) {
final AppenderControl[] controls = appenders.get();
//noinspection ForLoopReplaceableByForEach
for (int i = 0; i < controls.length; i++) {
controls[i].callAppender(event);
}
}
}
- LoggerConfig通過(guò)AppenderControl的callAppender進(jìn)行日志輸出。
public class AppenderControl extends AbstractFilterable {
public void callAppender(final LogEvent event) {
if (shouldSkip(event)) {
return;
}
callAppenderPreventRecursion(event);
}
private void callAppenderPreventRecursion(final LogEvent event) {
try {
recursive.set(this);
callAppender0(event);
} finally {
recursive.set(null);
}
}
private void callAppender0(final LogEvent event) {
ensureAppenderStarted();
if (!isFilteredByAppender(event)) {
tryCallAppender(event);
}
}
private void tryCallAppender(final LogEvent event) {
try {
appender.append(event);
} catch (final RuntimeException ex) {
handleAppenderError(event, ex);
} catch (final Exception ex) {
handleAppenderError(event, new AppenderLoggingException(ex));
}
}
private boolean shouldSkip(final LogEvent event) {
return isFilteredByAppenderControl(event)
|| isFilteredByLevel(event) || isRecursiveCall();
}
}
- AppenderControl通過(guò)Appender的append進(jìn)行日志輸出。
public abstract class AbstractOutputStreamAppender<
M extends OutputStreamManager> extends AbstractAppender {
public void append(final LogEvent event) {
try {
tryAppend(event);
} catch (final AppenderLoggingException ex) {
throw ex;
}
}
private void tryAppend(final LogEvent event) {
if (Constants.ENABLE_DIRECT_ENCODERS) {
directEncodeEvent(event);
} else {
writeByteArrayToManager(event);
}
}
protected void directEncodeEvent(final LogEvent event) {
getLayout().encode(event, manager);
if (this.immediateFlush || event.isEndOfBatch()) {
manager.flush();
}
}
}
- 具體的Appender進(jìn)行格式化并輸出日志。