This week, I’ve added Log module to LiveUI and I would like to share my experience. I should mention firstly that I was very busy and I did not want to spend more than one hour for the whole thing. It was reasonable deadline because functionality I needed was very simple: I wanted several methods to write arguments they receive to the text file, file name and format should have been configurable. Firstly, I’ve invented syntax I would like to use.
Let’s assume, we need to log MyMethod
calls of MyType
, I wanted code to look like:
public class MyType {
public void MyMethod(int arg1, int arg2) {
Log.Get(this).Message("method call: MyMethod({0}, {1})", arg1, arg2);
...
}
}
After that, I needed some logging framework and adapter to my syntax. Let’s talk about adapter first, I’ve followed the straightforward way and created interface ILogProvider
.
public interface ILogProvider {
Log GetLog<TContext>(TContext context)
}
public abstract class Log
{
public abstract Message(...);
public abstract Warning(...);
public abstract Error(...)
public static Log Get<TContext>(TContext context)
{
ILogProvider logProvider = ...;
returnlogProvider.GetLog<TContext>(context);
}
}
The only thing left is to implement ILogProvider
. I had been choosing between log4net and NLog for implementation (both are open source and popular). Comparing code and configuration samples, I’ve chosen NLog because its samples do not contain ugly words like “NullAppender
” and it has better web site (yes, it does matter) :) That’s how NLog based ILogProvider
implementation looks:
public class NLogProvider : ILogProvider {
public Log GetLog<TContext>(TContext context) {
return NLog<TContext>.Instance;
}
}
public class NLog<T> : Log
{
public static readonly NLog<T> Instance = new NLog<T>();
private Logger logger;
public override Message(string format, args) {
logger.Info(...);
}
public NLog(){
logger = LogManager.GetLogger(typeof(T)));
}
}
That’s it. After that, we can configure logging using Nlog configuration section as follows:
<nlog>
<logger name="MyNamespace.MyType" minlevel="Debug" writeTo="MyLog" />
<target name="MyLog" xsi:type="File" filename="${basepath}/log.txt"/>
</nlog>