Logging NLog Messages to a Non-static Method
I’ve used the NLog logging library for .NET for a few projects in the past, and have absolutely loved it. It is extremely easy to configure and extremely flexible.
One thing that I just ran into was that the built-in MethodCallTarget can only send log messages to a static method. In my particular case, I wanted to grab all of the log messages that were occurring in the entire AppDomain, and funnel them into an instance (non-static) method of a class. Thankfully NLog is also very easy to extend, so I just wrote my own log target. More specifically, I just subclassed the MethodCallTargetBase and overrode the DoInvoke method:
public class InstanceMethodCallTarget : MethodCallTargetBase
{
private MethodInfo m_MethodInfo;
public InstanceMethodCallTarget()
: base()
{
}
#region Property - ClassInstance
private object m_ClassInstance;
public object ClassInstance
{
get
{
return m_ClassInstance;
}
set
{
m_ClassInstance = value;
UpdateMethodInfo();
}
}
#endregion
#region Property - MethodName
private string m_MethodName;
public string MethodName
{
get
{
return m_MethodName;
}
set
{
m_MethodName = value;
UpdateMethodInfo();
}
}
#endregion
private void UpdateMethodInfo()
{
if ((this.ClassInstance != null) && (this.MethodName != null))
{
m_MethodInfo = this.ClassInstance.GetType().GetMethod(this.MethodName);
}
else
{
m_MethodInfo = null;
}
}
protected override void DoInvoke(object[] parameters)
{
if (m_MethodInfo != null)
{
m_MethodInfo.Invoke(this.ClassInstance, parameters);
}
}
}
I can understand why such a target doesn’t come with NLog — the ClassInstance property cannot be instantiated from the XML config file and must be programmatically specified.
For example:
LoggingConfiguration config = LogManager.Configuration;
if (config == null)
{
config = new LoggingConfiguration();
}
InstanceMethodCallTarget target = new InstanceMethodCallTarget();
target.ClassInstance = this;
target.MethodName = "LogMessage";
target.Parameters.Add(new MethodCallParameter("${level}"));
target.Parameters.Add(new MethodCallParameter("${message}"));
config.AddTarget("TargetNameHere", target);
config.LoggingRules.Add(new LoggingRule("*", LogLevel.Debug, target));
LogManager.Configuration = config;
Since two MethodCallParameters were added to the Parameters collection, the method that NLog invokes behind-the-scenes must take two string parameters and return void. For example:
public void LogMessage(string level, string message)
{
// Do something here, like fire an event with the log level and log message
}
NLog is a great library with a very well thought-out and flexible API.
You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
Leave a Reply