I spotted that NLog have a Windows Performance Counter target and decided to give it a whirl.

I’m currently working heavily with windows performance counters using a framework called PerfIt! and wanted to see if there was an easier to configure solution.

Grab the source code here: https://github.com/alexanderwilliamson/Alexw.NLogPerformanceCountersExample

Install-Package NLog
Install-Package NLog.Config
Install-Package Topshelf

Using the topshelf getting started guide I created a quick example app which would write an INFO level log every second.

public class Program
{
  public static void Main()
  {
    HostFactory.Run(x =>
    {
      x.Service<Service>(s =>
      {
        s.ConstructUsing(name => new Service());
        s.WhenStarted(tc => tc.Start());
        s.WhenStopped(tc => tc.Stop());
      });
      x.RunAsLocalSystem();

      x.SetDescription("Ex Topshelf Host");
      x.SetDisplayName("Stuff");
      x.SetServiceName("Stuff");
    });
  }
}

public class Service
{
  readonly Timer _timer;
  private readonly ILogger _logger = LogManager.GetCurrentClassLogger();
  public Service()
  {
    _timer = new Timer(1000) { AutoReset = true };
    _timer.Elapsed += (sender, eventArgs) => _logger.Info("This is an info log message");
  }
  public void Start() { _timer.Start(); }
  public void Stop() { _timer.Stop(); }
}

The real magic happens in the target file. This is where the counters are created using the autoCreate flag.

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd" autoReload="true" throwExceptions="true" internalLogLevel="Info" internalLogFile=".\nlog-internal.log">

 <targets>
   <target
     xsi:type="PerfCounter"
     name="perf"
     counterName="Alexw.Example"
     instanceName="LogWritten"
     counterHelp="This was created by NLog"
     counterType="NumberOfItems32"
     autoCreate="true"
     categoryName="ExampleCategoryName"
     incrementValue="1" />

   <target xsi:type="Console" name="console" detectConsoleAvailable="true" />
 </targets>

 <rules>
   <logger name="*" minlevel="Debug" writeTo="perf" />
   <logger name="*" minlevel="Debug" writeTo="console" />
 </rules>
</nlog>

When you put this all together, you get automatically created Performance Counters (available after you’ve restarted your console of course).

> Get-Counter -ListSet *example*

CounterSetName     : ExampleCategoryName
MachineName        : .
CounterSetType     : SingleInstance
Description        : Category created by NLog
Paths              : {\ExampleCategoryName(*)\Alexw.Example}
PathsWithInstances : {\ExampleCategoryName(logwritten)\Alexw.Example}
Counter            : {\ExampleCategoryName(*)\Alexw.Example}