Stop rolling your eyes, I know there are more logging infrastructure libraries out there than there are projects using them. And I won’t say this one is different, it’s not. It’s more or less a little experiment I did to get accustomed to VS2010 and R#5.
Also note that most of the code originated from me writing a logging architecture for a Java OSS project I’m involved with and I wanted to carry the idea over to .NET.
But: I believe it turned out to be quite nice while very very lightweight. So I thought I’d just go ahead and share it.
Usage
Tigraine.Logging has a ILogger interface that exposes the usual suspects:
You just instantiate the appropriate ILogger implementation and are set to go, it will write everything you pass to it.
What makes out most of the code though is the ability to render objects passed into the logger as parameters. This idea came from the Java codebase where there was code like this scattered all over the place:
@Override public String toString() { String ret = this.getClass().getSimpleName();if (Config.logVerbosity >= Log.Verbosity.VERBOSE) { ret += "(" + this.hashCode() + ")"; } if (Config.logVerbosity >= Log.Verbosity.VERBOSE) { ret += " A={" + this.a + "}, B={" + this.b + "}"; }
return ret; }
Now, I hate that sort of code. It’s just noise and it tends to get messy really soon. And so I started implementing my idea of ObjectRenderers (I know this term is already used by other logging frameworks, and the idea is not new either):
You add a renderer to the logger and whenever a object is passed in of the type, the renderer is invoked to transform the object to a string representation of your choosing. So instead of having to rely on .ToString() to give accurate results, you implement a class that takes care of writing all relevant information of your object down.
Here is a sample:
var consoleLogger = new ConsoleLogger(LogLevel.Debug); consoleLogger.AddObjectRenderer<TestClass>(new TestClassRenderer());consoleLogger.Error("Something went wrong with {0}", new TestClass());
The logging framework will call TestClassRenderer.Render to get a string representation of TestClass. This now also means you can have two different renderers, one verbose and one brief, and only hook up the one that’s right for you right now. The calling code does not need to be touched.
You can also define a renderer for a supertype and all subclasses will use that one if no more specific renderer is hooked up. If no renderer is found whatsoever .ToString() will get called.
And since implementing all renderers in their own classes would lead to a lot of code, there is a little helper class that should work for most of you by using some lambda syntax:
var compositeRenderer = new CompositeRenderer<TestClass> (p => p.Firstname + " " + p.Nickname + " " + p.Age);
Where to get
You may have already guessed, Tigraine.Logging can be found on GitHub and is open-source under the Apache License Version 2