qos-ch / logback

The reliable, generic, fast and flexible logging framework for Java.
http://logback.qos.ch
Other
2.97k stars 1.28k forks source link

AsyncAppender should avoid adding items to queue when log event happens in Worker thread #788

Open ruzovvo opened 5 months ago

ruzovvo commented 5 months ago

Hi, i have the next configuration:

<appender name="file_out" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>/path/to/app.log</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
                <fileNamePattern>...</fileNamePattern>
                <minIndex>1</minIndex>
                <maxIndex>10</maxIndex>
            </rollingPolicy>
            <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
                <maxFileSize>100MB</maxFileSize>
            </triggeringPolicy>
            <encoder class="my.package.SensitiveEncoder"/>
        </appender>
        <appender name="ASYNC_FILE"
                  class="ch.qos.logback.classic.AsyncAppender">
            <appender-ref ref="file_out" />
            <discardingThreshold>${discardingThreshold}</discardingThreshold>
            <queueSize>${queueSize}</queueSize>
            <includeCallerData>${includeCallerData}</includeCallerData>
            <neverBlock>${neverBlock}</neverBlock>
            <maxFlushTime>${maxFlushTime}</maxFlushTime>
        </appender>

        <root level="info">
            <appender-ref ref="ASYNC_FILE"/>
        </root>

My SensitiveEncoder masks some data published to file and sends messages to kafka at the stage of encoding (that's for audit purposes). When kafka fails it logs the error. As everything goes to ASYNC_FILE appender , the message goes to ArrayBlockingQueue in AsyncAppender.

If the log pressure is quite big, then queue is full and no new message can be added to it. Here we come to deadlock.

Inspecting the code i found that AsyncAppender doesn't consider thread calling 'append' method. I do not expect errors happened on Worker thread to be delayed and added to the queue again.

My suggestion is next: in private void put(E eventObject) add check:

if (Thread.currentThread() == worker) then aai.appendLoopOnAppenders(e);