Creating custom Counters and monitoring them with Perfmon

I recently had to create some custom counters to monitor some specific code in one of my applications. There were a few learnings along the way. Hence, decided to post them here for anyone who wants to do custom monitoring of your application.

First, build a seperate little console application that will first add the Counter Categories and and The counter definitions to the Counter Repository. The code for this utlity is like this:

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Management.Instrumentation;
using System.Reflection;

namespace PerformanceCounterSetup
{
    class Program
    {
        static void Main(string[] args)
        {

            MonitorSetup monitorSetup = new MonitorSetup();
            Console.WriteLine(“Initializing….”);
            monitorSetup.Init();
            Console.WriteLine(“Performance counters created. Press any key to exit.”);
            Console.ReadLine();
        }
    }

    public class MonitorSetup
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;

        // Performance counters
        private const string PERF_CNT_CATEGORY = “My Application”;
        private const string PERF_CNT_CATEGORY_DESC = “Application Monitored for Performance”;
        private const string PERF_CNT_TOTAL_RQSTS_MADE = “TotalRequestsMade”;
        private const string PERF_CNT_TOTAL_RQSTS_MADE_DESC = “Total number of requests made”;
        private const string PERF_CNT_RQSTS_PER_SCND = “RequestsPerSecond”;
        private const string PERF_CNT_RQSTS_PER_SCND_DESC = “Requests/Sec rate”;
        private const string PERF_CNT_RESPS_PER_SCND = “ResponsesPerSecond”;
        private const string PERF_CNT_RESPS_PER_SCND_DESC = “Responses/Sec rate”;

        // Default service name
        private const string DEFAULT_SERVICE_NAME = “MonitoredService”;

        // Performance counters
        // Name of this instance for performance counters
        private const string m_serviceInstanceName = “Running_Service”;

        public MonitorSetup()
        {

        }
        public void Init()
        {
            //Delete the counters if they already exist
            DeleteCounters();
            // Setup and create performance counters
            SetupPerformanceCounters();

        }

        public void DeleteCounters()
        {
            if (PerformanceCounterCategory.Exists(PERF_CNT_CATEGORY))
                PerformanceCounterCategory.Delete(PERF_CNT_CATEGORY);
        }

        #region Performance Counter setup

        /// <summary>
        /// Set up the performance counters.
        /// </summary>
        protected void SetupPerformanceCounters()
        {
            // Does the category exists?
            if (!PerformanceCounterCategory.Exists(PERF_CNT_CATEGORY))
            {
                // Allways attempt to create the category
                CounterCreationDataCollection CCDC = new CounterCreationDataCollection();

                // Add the standard counters

                // Total requests made
                CounterCreationData totalRequestsMade = new CounterCreationData(PERF_CNT_TOTAL_RQSTS_MADE,
                    PERF_CNT_TOTAL_RQSTS_MADE_DESC, PerformanceCounterType.NumberOfItems32);
                CCDC.Add(totalRequestsMade);

                // Requests per seond
                CounterCreationData requestsPerSecond = new CounterCreationData(PERF_CNT_RQSTS_PER_SCND,
                    PERF_CNT_RQSTS_PER_SCND_DESC, PerformanceCounterType.RateOfCountsPerSecond32);
                CCDC.Add(requestsPerSecond);
                // Requests per seond
                CounterCreationData responsesPerSecond = new CounterCreationData(PERF_CNT_RESPS_PER_SCND,
                    PERF_CNT_RESPS_PER_SCND_DESC, PerformanceCounterType.RateOfCountsPerSecond32);
                CCDC.Add(responsesPerSecond);
                // Create the category.
                PerformanceCounterCategory.Create(PERF_CNT_CATEGORY,
                    PERF_CNT_CATEGORY_DESC, CCDC);
            }
        }

        #endregion

    }
}

 Then add code in your application to create instances of these counters and increment as required. Here is a sample application to increment the counter:

using System;
using System.Collections.Generic;
using System.Text;
using System.Management.Instrumentation;
using System.Diagnostics;
using System.Threading;

namespace PerfIncrTester
{
    class Program
    {
        // Performance counters
        private const string PERF_CNT_CATEGORY = “My Application”;
        private const string PERF_CNT_TOTAL_RQSTS_MADE = “TotalRequestsMade”;
        private const string PERF_CNT_RQSTS_PER_SCND = “RequestsPerSecond”;
        private const string PERF_CNT_RESPS_PER_SCND = “ResponsesPerSecond”;
        private const string PERF_CNT_MSGS_PER_SCND = “MessagesPerSec”;
        // Default service name
        private const string DEFAULT_SERVICE_NAME = “MonitoredService”;

        // Performance counters
        // Name of this instance for performance counters
        private const string m_serviceInstanceName = “Running_Service”;
        private static PerformanceCounter m_totalRequestsMade;
        private static PerformanceCounter m_requestsPerSecond;
        private static PerformanceCounter m_responsesPerSecond;
        private static PerformanceCounter m_messagesPerSecond;

        static void Main(string[] args)
        {
            CreatePerformanceCounters();

            while (true)
            {
                Thread.Sleep(2000);
                m_totalRequestsMade.Increment();
                m_requestsPerSecond.Increment();
            }
        }

        /// <summary>
        /// Create and initialize the standard set of performance counters
        /// </summary>
        private static void CreatePerformanceCounters()
        {

            // Create and initialize
            m_totalRequestsMade = new PerformanceCounter(PERF_CNT_CATEGORY,
                PERF_CNT_TOTAL_RQSTS_MADE, m_serviceInstanceName, false);
            m_totalRequestsMade.RawValue = 0;

            m_requestsPerSecond = new PerformanceCounter(PERF_CNT_CATEGORY,
                PERF_CNT_RQSTS_PER_SCND, m_serviceInstanceName, false);
            m_requestsPerSecond.RawValue = 0;

            m_responsesPerSecond = new PerformanceCounter(PERF_CNT_CATEGORY,
                PERF_CNT_RESPS_PER_SCND, m_serviceInstanceName, false);
            m_responsesPerSecond.RawValue = 0;

            m_messagesPerSecond = new PerformanceCounter(PERF_CNT_CATEGORY,
                PERF_CNT_MSGS_PER_SCND, m_serviceInstanceName, false);
            m_messagesPerSecond.RawValue = 0;

        }

    }
}

After running the above code, the counter category and the counters will show up in the list of Performance Counters. However, there will be no instance running. Hence, adding these counters without an instance will not be useful. Doing so, you will not see any changes to the counters when the application is executed.

Execute your application and revisit the Perfmon Counter log UI. This time around you will see an instance name in the list. Select the instance name and then add the counters to log. Now you will see these counters changing as your application chugs along.

A very simple thing to implement. However, took me some time to figure out the fact that being custom counters, the running instance is required to be able to add them to the Permon logs.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s