An advanced and easy logging functionality is an often underrated topic in software technologies. But you should have a good logging feature when an application runs in a commercial or even in a crucial environment. I tend to say that EVERY software should have a comprehensive logging mechanism to ensure transparency of your system.

This blog post is about the usage of the Sin.Net.Logging library and how to use it in a productive environment and for unit testing the same time.

Requirements

Before you can use the functionality of Sin.Net.Logging you need any kind of .NET project and the NuGet packages

Just add them to your project in your preferred way via CLI or the package manger explorer in Visual Studio. The logging in Sin.Net provides six levels. Trace is the weakest and Fatal the strongest level, like seen below. These are based on the NLog project that is also used as reference implementation.

graph LR A[Trace] --> B[Debug] B --> C[Info] C --> D[Warn] D --> E[Error] E --> F[Fatal]
graph TB A[Trace] --> B[Debug] B --> C[Info] C --> D[Warn] D --> E[Error] E --> F[Fatal]
Logging with Sin.Net.Logging

After your project setup is ready, you have to add one line of code before you are able to log something. In your productive system this should be one the first statements in your Program.cs. If you try to log something without the line shown below, there should nothing happen.

using Sin.Net.Domain.Persistence.Logging;
using Sin.Net.Logging;

public class Program
{
    public static void Main(string[] args)
    {
        Log.Inject(new NLogger());
        Log.Info("Logging runs fine");
    }
}

Here, an instance of a logger is injected into the static class Log that has to implement the ILoggable interface. The static class is now using the functionality of this instance. The Sin.Net.Logging provides two logger classes for you: the NLogger and the TestLogger class. Both rely on the NLog library and are preconfigured within the code so you needn’t to define a config file. Both logger classes are printing on the console. The difference between them is that the TestLogger will not create a file but the NLogger class does.

It is important to notice that all static Log calls are not dependend on any logging implementation so you can exchange your logging library by simply changing the injected object.

Implementing a different Logger

You just need to implement the ILoggable interface from the Sin.Net.Domain assembly and fill its methods with your own behavior. The static Log class will call the implemented methods with the same names anywhere you need it.

So with Sin.Net it becomes pretty lightweight to switch from one concrete logger to another without changing any line of productive code. For example, I start my unit tests with the TestLogger and run my productive code with the NLogger class and get exactliy the logging that I need for each case.

For deeper insights what happens to your logger within the Log class, please take a look into the source code.

using Sin.Net.Domain.Persistence.Logging;

public class MyLogger : ILoggable
{
    public MyLogger()
    {
        Start();
    }

    public void Start()
    {
        // optional start routine
        // call in the constructor
    }

    public void Stop()
    {
        // optional shutdown routine
    }

    public void Trace(string msg) { }
    public void Debug(string msg) { }
    public void Info(string msg) { }
    public void Warn(string msg) { }
    public void Error(string msg) { }
    public void Fatal(Exception ex) { }
}
Conclusion

A good logging is not hard to implement, but it is not simple to make it easy for the programmer to use it. The Sin.Net project provides a solution that is easy to use or to adapt with your own logging when you are not okay with the NLog dependency.

The built-in loggers in Sin.Net.Logging are not the most flexible ones, but in a further version it is likely to ensure that by using the NLog config files as alternative.


Writing this post was supported with music from Gojira - Flying whales.
Have a nice day!

Leave a comment