Hi Currently i am studying logback logging framework. I came across Async Appenders which use blocking queue for logging messages in such a way that all the thread enqueue there messages in blocking queues and working thread of async appender is responsible for logging the message from queue to certain destination as decided by appenders it could be file,database,socket etc.
I can see the performance gain in response time as main thread won't perform the I/O it only pushes the messages in queue and in background worker thread for async appender retrieve those message and append them in logs file.
Is my understanding right? i read several configuration attribute related to async appender like Queue size , maxFlushTime,neverBlock,discardingThreshold and includeCallerData.
How i should use these attribute in order to boost performance in logging My current configuration for async Appender is as under.
<appender name="ASYNC500" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="fileAppender"/>
<queueSize>500</queueSize>
<maxFlushTime>1000</maxFlushTime>
</appender>
Can someone suggest me some tweaks in order to gain performance. ? Which is better normal appender or Async Appender ?
The AsyncAppender exposes configuration levers that you can use to address the potential resource leakage. For example: You can increase the buffer capacity. You can instruct Logback to drop events once the buffer reaches maximum capacity.
Logback executes an async appender in a separate thread to decouple the logging overhead from the thread executing your code. Using the async appender is incredibly easy. Refer the appender that should be asynchronously invoked within an <appender> element.
The given logback configuration creates daily rolled-over logs with max log size of 10 MB, keeping 30 days worth of history, but at most 10 GB of total archived logs. Older logs start getting deleted as soon as the size limit is breached.
ConsoleAppender appends log events to System. out or System. err using a layout specified by the user. The default target is System.
Answering the second question first ...
Which is better normal appender or Async Appender?
The answer here is: it depends. To clarify that here the the pros and cons of using an AsyncAppender
:
Pros:
Logger.debug|info|warn|error
call to complete will be lower for an asynchronous logger than it will be for a synchronous logger.Cons:
Depending on your use case you might find that some of these pros and cons have more weight than others. I'd suggest starting without an AsyncAppender
and only using one if you have a demonstrable need to do so.
Back to your first question ...
Can someone suggest me some tweaks in order to gain performance?
This is why I answered the second question first. Without knowing the specifics of your application and it's runtime configuration (memory and CPU on its hosts, the type of appender to be wrapped by the AsyncAppender
and your tolerance for discarding log events) it is impossible to say how you shoud configure it. However, you'll know all these things about your own application so with that knowledge in mind I'd suggest considering the following when deciding if-and-how to configure an AsyncAppender
:
queueSize
: the bigger this is the less blocking there will be on the application threads. If the async appender's queue fills up, then application threads will be blocked from logging new events until the worker thread has had a chance to remove items from the queue. So, increasing the queueSize
will improve throughput if the application tends to produce enough near concurrent log events to fill up the queue. But bear in mind that this gain in throughput is only relevant if the application is capable of swamping the existing queue size and it comes at the cost of heap usage.includeCallerData
: reading caller supplied data from log events can be expensive, you'll typically find that setting this to false
improves performance and unless you have some bespoke caller supplied data in your log events you won't actually lose any dataneverBlock
: setting this to true
will prevent any blocking on your application threads but it comes at the cost of lost log events if the async appender's internal buffer fills up.So ...
If maximising throughput is essential to you and you don't care about losing some events then use neverBlock=true
If maximising throughput is important to you and you have plenty of headroom in your heap and you have no tolerance for losing log events then use: queueSize=_some_number_which exceeds_ the_maximum_queue_size_observed_in_testing_plus_25_percent_
Plenty more details here:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With