Logging to Log4j2 MongoDb4 Appender on trace, debug and info log level give the following error ERROR Recursive call to appender but give success result and the log got written to the mongodb database when using warn or error log level. Possibly something recursive call happens with info log level that causing this bug. See this article
Here is the repository that contain the very minimal code to reproduce the error. The configuration is provided in the log4j2-spring.xml file.
Comment From: wilkinsona
Thanks for the sample. This doesn't appear to be a Spring Boot problem. I renamed log4j2-spring.xml
to log4j2.xml
and modify Log4j2Mongodb4AppenderApplication
to remove the use of Spring Boot:
package com.example.demo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Log4j2Mongodb4AppenderApplication {
private static final Logger log = LoggerFactory.getLogger(Log4j2Mongodb4AppenderApplication.class);
public static void main(String[] args) {
log.trace("Trace level message");
log.debug("Debug level message");
log.info("Info level message");
log.warn("Warn level message");
log.error("Error level message");
}
}
The same 2021-07-09 14:26:38,698 main ERROR Recursive call to appender MongoDbAppender
problem occurred.
Here's the stack of the recursive call which may help you to diagnose the problem:
AppenderControl.isRecursiveCall() line: 105
AppenderControl.shouldSkip(LogEvent) line: 88
AppenderControl.callAppender(LogEvent) line: 81
LoggerConfig.callAppenders(LogEvent) line: 540
LoggerConfig.processLogEvent(LogEvent, LoggerConfig$LoggerConfigPredicate) line: 498
LoggerConfig.log(LogEvent, LoggerConfig$LoggerConfigPredicate) line: 481
LoggerConfig.log(String, String, StackTraceElement, Marker, Level, Message, Throwable) line: 456
AwaitCompletionReliabilityStrategy.log(Supplier<LoggerConfig>, String, String, StackTraceElement, Marker, Level, Message, Throwable) line: 82
Logger.log(Level, Marker, String, StackTraceElement, Message, Throwable) line: 161
Logger(AbstractLogger).tryLogMessage(String, StackTraceElement, Level, Marker, Message, Throwable) line: 2205
Logger(AbstractLogger).logMessageTrackRecursion(String, Level, Marker, Message, Throwable) line: 2159
Logger(AbstractLogger).logMessageSafely(String, Level, Marker, Message, Throwable) line: 2142
Logger(AbstractLogger).logMessage(String, Level, Marker, String) line: 2022
Logger(AbstractLogger).logIfEnabled(String, Level, Marker, String) line: 1875
Log4jLogger.info(String) line: 179
SLF4JLogger.info(String) line: 71
SingleServerCluster(BaseCluster).getDescription() line: 188
SingleServerCluster.getDescription() line: 41
MongoClientDelegate.getConnectedClusterDescription() line: 127
MongoClientDelegate.createClientSession(ClientSessionOptions, ReadConcern, WriteConcern, ReadPreference) line: 87
MongoClientDelegate$DelegateOperationExecutor.getClientSession(ClientSession) line: 258
MongoClientDelegate$DelegateOperationExecutor.execute(WriteOperation<T>, ReadConcern, ClientSession) line: 182
MongoCollectionImpl<TDocument>.executeSingleWriteRequest(ClientSession, WriteOperation<BulkWriteResult>, Type) line: 1009
MongoCollectionImpl<TDocument>.executeInsertOne(ClientSession, TDocument, InsertOneOptions) line: 470
MongoCollectionImpl<TDocument>.insertOne(TDocument, InsertOneOptions) line: 453
MongoCollectionImpl<TDocument>.insertOne(TDocument) line: 447
MongoDb4Connection.insertObject(NoSqlObject<Document>) line: 97
NoSqlDatabaseManager<W>.writeInternal(LogEvent, Serializable) line: 83
NoSqlDatabaseManager<W>(AbstractDatabaseManager).writeThrough(LogEvent, Serializable) line: 291
NoSqlDatabaseManager<W>(AbstractDatabaseManager).write(LogEvent, Serializable) line: 264
NoSqlAppender(AbstractDatabaseAppender<T>).append(LogEvent) line: 110
AppenderControl.tryCallAppender(LogEvent) line: 156
AppenderControl.callAppender0(LogEvent) line: 129
AppenderControl.callAppenderPreventRecursion(LogEvent) line: 120
AppenderControl.callAppender(LogEvent) line: 84
LoggerConfig.callAppenders(LogEvent) line: 540
LoggerConfig.processLogEvent(LogEvent, LoggerConfig$LoggerConfigPredicate) line: 498
LoggerConfig.log(LogEvent, LoggerConfig$LoggerConfigPredicate) line: 481
LoggerConfig.log(String, String, StackTraceElement, Marker, Level, Message, Throwable) line: 456
AwaitCompletionReliabilityStrategy.log(Supplier<LoggerConfig>, String, String, StackTraceElement, Marker, Level, Message, Throwable) line: 82
Logger.log(Level, Marker, String, StackTraceElement, Message, Throwable) line: 161
Logger(AbstractLogger).tryLogMessage(String, StackTraceElement, Level, Marker, Message, Throwable) line: 2205
Logger(AbstractLogger).logMessageTrackRecursion(String, Level, Marker, Message, Throwable) line: 2159
Logger(AbstractLogger).logMessageSafely(String, Level, Marker, Message, Throwable) line: 2142
Logger(AbstractLogger).logMessage(String, Level, Marker, String) line: 2022
Logger(AbstractLogger).logIfEnabled(String, Level, Marker, String) line: 1875
Log4jLogger.info(String) line: 179
Log4j2Mongodb4AppenderApplication.main(String[]) line: 13
I suspect it's because Mongo's client is performing some info-level logging while it's being used to log something.