When should I use Tracing vs Logger.NET, Enterprise Library, log4net or Ukadc.Diagnostics?
There are many similar questions here on SO:
- Logging best practices
- log4net versus TraceSource
- Silverlight Logging framework and/or best practices
- log4net vs. Nlog
- What's the point of a logging facade?
- C# Logging. What should I use?
You missed several commonly used logging frameworks. Here is a list of commonly used frameworks, some of which you listed:
- System.Diagnostics
- log4net
- NLog
- Enterprise Library
- The Object Guy
Logging abstractions:
- Microsoft.Extensions.Logging
- Common.Logging
- SLF
System.Diagnostics addons:
- Ukadc.Dianostics
- Essential.Diagnostics
Other
- Elmah
- Serilog
A couple of other logging frameworks from codeplex (that I have seen mentioned here on SO):
- CuttingEdge.Logging
- SpringTail
Why might you choose one over the other? That's a tough one. A lot of it is personal preference. Some of it is technical (or feature) superiority.
One obvious drawback of any logging framework (particularly third-party ones) is the quality of support. What if you have an issue with log4net, NLog, Common.Logging, etc? Will you be able to get a fix from the developers of those frameworks? This might not be tremendously important as the source code is available for these frameworks. However, you might prefer NOT to "inherit" the source tree just to make a fix or add an enhancement. I will say that the frameworks are so extensible, that many enhancements could be added via normal extension points.
If you read the links that I posted above, I think that it is fair to say, based solely on the volume of favorable mentions, that log4net would be the clear "winner". It will be mentioned more frequently as the historical logging favorite and what many people would choose to use going forward.
NLog has its supporters, it just doesn't seem to have the penetration, or "top of mind" awareness that log4net does, even though they are very similar. NLog's capabilities are very similar to log4net and it has the extra advantage of having gone through a significant development cycle recently.
Enterprise Library is often touted as a good choice, but is almost equally as often touted as a terrible choice. Maybe some of its negative reputation is maybe not so good early versions? Maybe it is better now?
System.Diagnostics is often recommended as a reasonable choice with at least three strong benefits: no third party dependency, many Microsoft components are instrumented with System.Diagnostics, it is easily extendable (presumably to add some capabilities that are already present "for free" in frameworks like log4net and NLog?). If you use System.Diagnostics, I think the consensus would be (as would my recommendation) to use TraceSource objects rather than Trace.WriteLine/Debug.WriteLine.
Note also that System.Diagnostics and WCF work well together. WCF message traffic can be logged with System.Diagnostics and WCF will also propagate System.Diagnostics activity information (System.Diagnostics.CorrelationManager.ActivityId) across WCF service boundary calls.
I'm not so sure that log4net should continue to retain its most favored status. As has been noted elsewhere here on SO, log4net does not seem to be undergoing a lot of development recently (note that I think "log4net is dead" is an exaggeration) while NLog 2.0 is currently out in beta with the final release expected in Q1 2011 (Update: NLog 2.0 was released on Jul 17, 2011). Does this make NLog an obviously better choice than log4net? I don't know, but I think that, relatively speaking, NLog should receive at least equal consideration when choosing between the two and, probably, should be the presumed favorite for new development, at least until log4net development shows more signs of life.
log4net and NLog both offer very flexible configuration options. They allow you to have very fine granularity in the definition of your logging statements (by the "standard" pattern of defining a logger per type). They also allow for easy extension of the libraries by allow you to develop your own "logging destination" objects (log4net Appenders and NLog Targets) and "formatting" objects (log4net pattern converters and NLog LayoutRenderers).
Aside from a logging framework choice, some (many?) advocate for insulating your application code from a hard dependency on a particular logging framework by use of an abstraction layer. This can take the form of your own ILogger interface that you implement, perhaps on top of an existing framework. In the future, you could change frameworks by implementing your ILogger over a different framework. Or, you could use DI/IoC to inject "ILogger" into your code. Many DI/IoC frameworks provide a built-in ILogger abstraction that can be configured to use log4net, NLog, or Enterprise Library or you could write your own ILogger implementation and inject that). Who cares what the implementation is? Another way to insulate your code from having a hard dependency on a specific logging framework is through the use of an existing logging abstraction framework such as Common.Logging or SLF. The benefit is that, again, your application is not dependent on a specific logging framework. However, some would say that you have just traded one dependency (on a logging framework) for another (logging abstraction framework).
Two more notes about logging abstraction:
A good logging abstraction should allow you to capture output from different logging frameworks in the same output file. Common.Logging calls this "bridging". Say that you have written an app using Common.Logging, backed by NLog. Now say that you are using a third party class library that is written using log4net directly. With a bridging system, you can capture the log4net output (via a custom appender) and reroute it through Common.Logging so that the third party class library's logging output can be viewed in the context of your app's logging output.
Using a logging abstraction also allows you to "test drive" logging frameworks during development. You might start out thinking that log4net is that way to go, but you want to leave yourself open to trying NLog. Using a logging abstraction it is relatively easy to switch between the two. Ultimately, you can make the choice of which logging framework, but, in the meantime, you have been able to write mountains of code that is NOT dependent in any way on a specific logging framework.
Another reason that you might choose one framework over another is the environment in which you work. If you are already using part of the Enterprise Library, that might be enough to push you into using Enterprise Library logging.
What if you are developing in Silverlight? You might choose to use something like Clog - part of Calcium. You might also choose to use NLog 2.0, which is Silverlight AND WP7 compatible.
System.Diagnostics addons (Ukadc.Diagnostics, Essential.Diagnostics). These are not logging frameworks per se. Rather, they represent collections of useful objects and extension points that can be used with the existing System.Diagnostics framework. One of the best things, in my opinion, that each of these addons adds is the ability to format your logging output, similar to how you can format it with log4net and NLog. I have not used Essential.Diagnostics, but I have experimented with Ukadc.Diagnostics and think that it is really cool. It is even easy to write your own "formatting tokens".
I don't know if this completely answered your question (which is pretty broad anyway), but I think that there is plenty of food for thought here.
I just started using log4net in VS2010 and discovered that it has a dependency on System.Web... which makes it incompatible with the ".NET x.x Client Profile" framework targets... Considering what someone here has posted about Windows Update using the Client Profile as the .NET redistributable of choice, this means log4net can no longer be the logger of choice if you want to have your code running on the majority of machines...
Thanks for the info on other options - I'll be checking them out...
Just to add a few things learned from Microsoft's Build 2013 conference:
Log4NET under heavy load has writing to a file mainly because this process is synchronous. It is possible to get contention and timeouts in certain conditions. This can be verified using AppDynamics or any other similar tool.
NLog doesn't implement queueing so under load, the IO calls stack up.
According to Microsoft, the ETW uses kernel ring buffers which is highly efficient. .NET 4.5 and the Event Log framework combined with Semantic Logging Application Bock (AKA SLAB) will make this much more efficient.