Skip to main content

log4net - Some fun with appenders

One of the most frequent logger mechanisms that is used in our days is log4net. This is an open source framework that can be found on different programming language, like Java and C#.
I played a little with log4net in the last period of time to see if log4net can become a bottleneck of an application. What I observed until now is the call duration of the appender is the longest call. Even if C# knows about async calls to IO resources, log4net will make all this calls in a sync way.
Usually if we have around 100 messages per second, the default log4net mechanism will be perfect for us. For these cases, if you want to improve the performance we should use the TraceAppender. Yes, the default appended from .NET. It works great and is pretty fast. This is a pretty good option if you don’t want to use a buffer appender. There are a lot of frameworks that used Trace – don’t be afraid of using it.
Another option is to use buffer appender. This is an appender that will not send messages immediately. We will send the messages only in the moment when there will be a specific number of messages in the buffer. The log4net already has this kind of appender defined (“BufferingForwardingAppender”). You should know that even if we are using the buffer the IO calls are still made sync. This means that in the moment when the buffer will be full and need to flush the content, there will be a sync IO call.  
A nice feature of this appender is the lossy option. Using this option you can set the buffer to flush the content in the case when a specific type of message is wrote into the buffer – for example when an error is logged.
What we observed until now is the way how the IO is used – we have only sync calls to the files. Because of this we could have some bottlenecks at this level. Theoretically we could improve the log4net performance if we would use async calls – when writing to files.
I didn’t have time to implement and measure, but I think that it would be pretty interesting. One solution is to make the calls async at the appender level. We could make the calls that write the buffered content to run on a different thread. This solution could cause problems because creating and working with thread is a pretty expensive thing – from resource perspective.
Another option would be to use async write calls to IO. For example we could use IO completion ports. This would be a pretty clever thing to do, but is a little bit complicated. Playing with IO completion ports is not simple.
The last option that I see valid is to use a thread (maybe a background thread) that writes the content to IO. Using this method, our application will be able to send content to the log4net without the need to wait after log4net to append/persist the content. The real action of writing the content to IO (file for example) will be made by the second thread. The drawback is from the second thread. It will need to run all the time. This thread will be created by appender. It is not important how we will append the content (async/sync) way, because we are already on another thread and the log4net calls will don’t need to wait until the content is written.
Until now I didn’t heard people to have problems with log4net – performance problems. If we configure log4net properly, we should not have any kind of problems. This investigation was only for fun, to see if we could improve the performance of log4net.

Comments

Popular posts from this blog

Windows Docker Containers can make WIN32 API calls, use COM and ASP.NET WebForms

After the last post , I received two interesting questions related to Docker and Windows. People were interested if we do Win32 API calls from a Docker container and if there is support for COM. WIN32 Support To test calls to WIN32 API, let’s try to populate SYSTEM_INFO class. [StructLayout(LayoutKind.Sequential)] public struct SYSTEM_INFO { public uint dwOemId; public uint dwPageSize; public uint lpMinimumApplicationAddress; public uint lpMaximumApplicationAddress; public uint dwActiveProcessorMask; public uint dwNumberOfProcessors; public uint dwProcessorType; public uint dwAllocationGranularity; public uint dwProcessorLevel; public uint dwProcessorRevision; } ... [DllImport("kernel32")] static extern void GetSystemInfo(ref SYSTEM_INFO pSI); ... SYSTEM_INFO pSI = new SYSTEM_INFO(

ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded

Today blog post will be started with the following error when running DB tests on the CI machine: threw exception: System.InvalidOperationException: The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information. at System.Data.Entity.Infrastructure.DependencyResolution.ProviderServicesFactory.GetInstance(String providerTypeName, String providerInvariantName) This error happened only on the Continuous Integration machine. On the devs machines, everything has fine. The classic problem – on my machine it’s working. The CI has the following configuration: TeamCity .NET 4.51 EF 6.0.2 VS2013 It see

Navigating Cloud Strategy after Azure Central US Region Outage

 Looking back, July 19, 2024, was challenging for customers using Microsoft Azure or Windows machines. Two major outages affected customers using CrowdStrike Falcon or Microsoft Azure computation resources in the Central US. These two outages affected many people and put many businesses on pause for a few hours or even days. The overlap of these two issues was a nightmare for travellers. In addition to blue screens in the airport terminals, they could not get additional information from the airport website, airline personnel, or the support line because they were affected by the outage in the Central US region or the CrowdStrike outage.   But what happened in reality? A faulty CrowdStrike update affected Windows computers globally, from airports and healthcare to small businesses, affecting over 8.5m computers. Even if the Falson Sensor software defect was identified and a fix deployed shortly after, the recovery took longer. In parallel with CrowdStrike, Microsoft provided a too