Description
Log4j2 AsycLogger Implementation with a database appender has an issue.
As i investigated the async logger mechanism works like that.
Messages are put into DistruptorRingBuffer
Than
RingBufferLogEventHandler's onEvent mehtod is called and message is passed to appender asyncronously.
In AbstractDatabaseAppender case
The messages also put into an ArrayList to make batches for bulk insert to table.
@Override public final void append(final LogEvent event) { this.readLock.lock(); try { this.getManager().write(event); } catch (final LoggingException e) { LOGGER.error("Unable to write to database [{}] for appender [{}].", this.getManager().getName(), this.getName(), e); throw e; } catch (final Exception e) { LOGGER.error("Unable to write to database [{}] for appender [{}].", this.getManager().getName(), this.getName(), e); throw new AppenderLoggingException("Unable to write to database in appender: " + e.getMessage(), e); } finally { this.readLock.unlock(); } }
Than Abstract Database Manager puts LogEvent into ArrayList
public final synchronized void write(final LogEvent event) { if (this.bufferSize > 0) { this.buffer.add(event); if (this.buffer.size() >= this.bufferSize || event.isEndOfBatch()) { this.flush(); } } else { this.connectAndStart(); try { this.writeInternal(event); } finally { this.commitAndClose(); } } }
After that correspoding LogEvent object can be re-used in the DistruptorRingBuffer mechanism.
When a delay happens in the database the LogEvent objects are overriden with same referance which causes inconsitency while preparing batches.
I believe this points to a bug or design problem.
I would like to contribute solution if anyone can guide where to start what might be the possible design.
Attachments
Issue Links
- relates to
-
LOG4J2-2140 MutableLogEvent instances get reused before flushing when using a NoSql Appender with a bufferSize
- Resolved