I have blogged about application logging in .NET a few times, here and here. It seems that every iteration gets better than the one before - the logging frameworks, not my posts :) Logging has always been important but for some odd reason it is either too complicated to implement or too clunky. In the beginning, we had strongly coupled implementation using one of the established logging frameworks (log4net, nLog etc). Then we learned from our mistakes and moved on to the Common.Logging API which abstracted things quite a bit and made logging more accessible.
The goal behind this evolution was to reach a point where adding logging to our apps was as abstracted and as decoupled as possible. This benefits us in many ways by allowing us to easily plug-and-play different logging providers depending on our needs. Today we may rely on log4net, but tomorrow we may wish to move to a cloud-based solution or use 3rd party API that can log to an external/remote repository. Logging should be transient and easy. At the point of integration, we shouldn’t need to know the underlying concrete implementation. All we should care about is logging something somewhere.
The Common.Logging
library took a first step in allowing us to abstract things, but it is a BIG library relatively to what it has to offer. A couple of days ago I came across LibLog, an open source .NET library that provides a very nice logging API and builds on the abstraction ideas introduced by the Common.Logging
API while still remaining impressively lightweight. After using it for a while on a client project, I have to say that I like it a lot!
Getting started with LibLog
Adding LibLog
to your solution couldn’t be easier. You can use the recommended way i.e. NuGet or integrate the single file to your solution manually, making sure that you change the namespace etc. I’m a big NuGet proponent so here goes:
Or, if you are a fan of the GUI, you can search and install it through the NuGet Package Manager like this:
Once you install it successfully, your solution/project should look like the image below:
Technically, NuGet is required in order to add one file (LibLog.cs) to the solution and change the namespace automatically. That’s why I said earlier that you can achieve the same result easily by adding it manually. With the file in place, you can start logging in your libraries, executables and websites. I have attached a simple console app example that uses LibLog below:
public static void Main(string[] args)
{
var logger = LogProvider.For<Program>();
if (logger.IsDebugEnabled())
{
logger.Debug("hello world");
}
}
The first line initializes the logger for the current class. We then check to see if the logger is configured to log debug messages and then we log it. LibLog also supports the use of lamda expressions to log messages in the same thing as the code above. By doing this, we defer the execution of any code inside the lamda expression until the message is actually logged. So now we can rewrite the above code like this:
public static void Main(string[] args)
{
var logger = LogProvider.For<Program>();
logger.Debug( () => "hello world");
}
Once you add the provider of your choice, don’t forget to initialize it correctly otherwise you may think that the library is broken. In my code, I added log4net and to ensure that things are logged to the configured output, I needed to initialize the log4net configuration. This call is only required once in your application, so make sure you add it at the right location (app start etc)
public static void Main(string[] args)
{
log4net.Config.XmlConfigurator.Configure();
var logger = LogProvider.For<Program>();
logger.Debug( () => "hello world");
}
I’m loving the simplicity and versatility of this little library and to make it even better, it has transparent built-in support for the following logging providers:
- NLog
- Log4Net
- EntLib Logging
- Serilog
- Loupe
- Custom Provider
As soon as you add the configuration for your preferred provider and set up the necessary appender, logging should just work. If you wish to implement your custom provider (not sure why), you just need to ensure that your provider implements the ILogProvider
interface or inherits from the LogProviderBase
. To use it in code, you need to make it available through LibLog:
YourProject.Logging.LogProvider.SetCurrentLogProvider(new CustomLogProvider());
I hope that you will find this little utility as handy as I did and enjoy easy and painless logging in your applications. You can find a sample project that uses LibLog on GitHub.