4
votes

Since there are so many logging frameworks out there, I was looking to write an abstraction per application so that I control which logging framework I can plugin. Meaning that I'm not reliable on for example Log4Net or NLog, but that I provide an interface/abstraction and then plugin frameworks in my own abstraction.

Something along these lines (a bit simplified mayvbe), which I can pass around to any object needing the dependency.

interface ILogger {
    void LogMessage(string message, Severity severity);
    void LogDebug(string message);
    void LogInfo(string message);
    void LogWarning(string message);
    void LogError(string message);
    void LogFatal(string message);
}

Afterwards my plan was to write adapters/implementations for the logging framework that I'd want to use - so I'd be able to plugin any other log framework when it is necessary.

public sealed class Log4NetLogger : ILogger {
   /// Implementation and Log4Net specifics here
}
public sealed class NlogLogger : ILogger {
   /// Implementation and Log4Net specifics here
}

These I'd inject/instantiate then via IoC or a resource locator, depending on the implementation details of the application I'm working on.

Question: I don't know if it would be a good idea? to write this from scratch, considering maybe

  • loss of contextual information that's housed inside logging frameworks
  • reinventing the wheel
  • performance hit

On the other hand, the benefits for me are:

  • If done correctly, I'd be able to switch out, or add a very custom implementation.
  • I wouldn't need to touch the internals afterwards of classes that already exist and are in production, thus complying to solid and especially open/closed principle - introducing less bugs.

Any guidance, remarks, warnings DO's & DONT's - or maybe references to existing abstractions might be handy and are very welcome!

Thanks, Yves

1
LibLog is well worth checking out.Nicholas Blumhardt
Thanks a lot for the tip! Only came across Common.Logging so far, this seems a little more lightweight!Yves Schelpe
You could always ask for a type as a generic parameter (in place of the actual parameters for you interface) or if generic parameters causes you problems, you'd just define an abstract class for it; if the variance of the frameworks is an issue. You would then provide a common LogParameters abstract type that would contain possible common parameters for most of the frameworks, in either cases. One implicitly, one explicitly (like a guide abstract class).welrocken
@welrocken do you mean sth like LogDebug<TClass>() so I can grab the class where it came from. Maybe also add the CallingMemberName attributes + params? That's a really good idea indeed.Yves Schelpe

1 Answers

5
votes

Ok, in my enthusiasm I seemed to have glanced over this. I might have found a library that suits my needs, I'll post this here in case anyone's looking for a similar solution: Common Logging framework.

What is does? Provides a simple logging abstraction to switch between different logging implementations. There is current support for log4net, NLog, Microsoft Enterprise Library logging, Microsoft Application Insights, Microsoft Event Tracing for Windows, and Serilog. Additionally Common.Logging comes with a set of base classes making the integration of any log system a breeze. ~ taken from their official github repo.

References: