Product Engineer, CTO & a Beer Enthusiast
Experiments, thoughts and scripts documented for posterity.
May, 2013
Nlog similar to log4net is quite a powerful logging library. Though out of the box it provides logging to text files, windows event log, database, Sentinal etc but how about about custom logging? Extending NLog to write to your own custom target is as quite simple as follows:
using System.ComponentModel.DataAnnotations;
using NLog;
using NLog.Targets;
using Dapper;
[Target("RDSAuditLogger")]
public sealed class RDSAuditLogger : TargetWithLayout
{
public RDSAuditLogger()
{
this.Host = "localhost";
}
[Required]
public string Host { get; set; }
protected override void Write(LogEventInfo logEvent)
{
string logMessage = this.Layout.Render(logEvent);
if(logEvent.Parameters != null && logEvent.Parameters.Count() > 1)
SendTheMessageToRemoteHost(logEvent.Parameters[0] as string, logEvent.Message, logEvent.Parameters[1] as string);
}
//Yours custom logging - Over here I am storing an Id, the message and a custom type
//that my logger is logging
private void SendTheMessageToRemoteHost(string id, string body, string type)
{
//Make the logging async
Task.Factory.StartNew(() =>
{
//Dapper.NET - write to sql using a Stored procedure
using (var connection = DataAccessManager.GetOpenConnection())
{
connection.Execute("AddToLog", new { Id = id, Type = type, Body = body},
commandType: CommandType.StoredProcedure);
}
});
}
}
using NLog;
using NLog.Config;
using NLog.Targets;
public static class Log
{
public static Logger Instance { get; private set; }
static Log()
{
//Register the custom target
ConfigurationItemFactory.Default.Targets.RegisterDefinition("RDSAuditLogger",
typeof(MyLibrary.RDSAuditLogger));
LogManager.ReconfigExistingLoggers();
Instance = LogManager.GetCurrentClassLogger();
}
}
<nlog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extensions>
<add assembly="MyLibrary"/>
</extensions>
<targets>
<target name="eventlog" xsi:type="EventLog" layout="${message}" log="Application" source="SomeName" />
<target name="rdsAuditLogger" type="RDSAuditLogger" host="localhost"/>
</targets>
<rules>
<logger name="*" levels="Error,Fatal,Warn" writeTo="eventlog" />
<logger name="*" levels="Info" writeTo="rdsAuditLogger" />
</rules>
</nlog>
Log.Instance.Info("This is a test log", "123", "AM-Start");
Note that the example above is specific to my custom logger.