How to write your own Target

Why would I want to write a Target?

If you want to write your trace messages to some non-standard output (for example to some management tool or over the network or using the PPPoP (PPP-over-pigeon protocol) you need to write a custom Target.

How to write a target?

It's really easy. Create a class that inherits from NLog.TargetWithLayout (or NLog.Target if you don't want to use layout) and override the Write(LogEventInfo) method. In the body of the method use CompiledLayout.GetFormattedMessage() to get the message text, then send the text to the destination media.

If your target can optimize for batch writes you should also override the Write(LogEventInfo[]) method.

Example

This is a skeleton target that writes messages to the specified host. Compile using:

csc.exe /t:library /out:MyAssembly.dll /r:NLog.dll MyFirstTarget.cs

using NLog; 
 
namespace MyNamespace 
{ 
    [Target("MyFirst")] 
    public sealed class MyFirstTarget: TargetWithLayout 
    { 
        private string _host = "localhost"; 
 
        public string Host 
        { 
            get { return _host; } 
            set { _host = value; } 
        } 
 
        protected override void Write(LogEventInfo logEvent) 
        { 
            string logMessage = CompiledLayout.GetFormattedMessage(logEvent); 
 
            SendTheMessageToRemoteHost(this.Host, logMessage); 
        } 
 
        private void SendTheMessageToRemoteHost(string host, string message) 
        { 
            // TODO - write me 
        } 
    } 
}
How to use the newly created target?

It's easy. Just put the target in a DLL and reference it from the the config file using the <extensions /> clause as described here.

Configuration file example
<nlog> 
  <extensions> 
    <add assembly="MyAssembly"/> 
  </extensions> 
  <targets> 
    <target name="a1" type="MyFirst" host="localhost"/> 
  </targets> 
  <rules> 
    <logger name="*" minLevel="Info" appendTo="a1"/> 
  </rules> 
</nlog> 
How to pass configuration options to the target?

Consider the above example. There's a property called "Host" that does just that. Having a public property that sets the required configuration parameters is enough for NLog to use it. Each attribute that you put in the <target /> definition gets passed to the appropriate public property. NLog takes care of the appropriate conversions necessary so that you can use integer, string, datetime, boolean parameters.

Do I really need to create a separate DLL?

Not really. You can use TargetFactory.AddTarget() to register your target programmatically. Just be sure to to it at the very beginning of your program before any log messages are written. It should be possible to reference your EXE using the <extensions /> clause.

static void Main(string[] args) 
{ 
    TargetFactory.AddTarget("MyFirst", typeof(MyNamespace.MyFirstTarget)); 
 
    // start logging here 
}