17

I'm creating some custom performance counters for an application. I wrote a simple C# tool to create the categories and counters. For example, the code snippet below is basically what I'm running. Then, I run a separate app that endlessly refreshes the raw value of the counter. While that runs, the counter and dummy instance are seen locally in perfmon.

The problem I'm having is that the monitoring system we use can't see the instances in the multi-instance counter I've created when viewing remotely from another server. When using perfmon to browse the counters, I can see the category and counters, but the instances box is grayed out and I can't even select "All instances", nor can I click "Add". Using other access methods, like [typeperf][1] exhibit similar issues.

I'm not sure if this is a server or code issue. This is only reproducible in the production environment where I need it. On my desktop and development servers, it works great. I'm a local admin on all servers.

CounterCreationDataCollection collection = new CounterCreationDataCollection();

var category_name = "My Application";
var counter_name = "My counter name";
CounterCreationData ccd = new CounterCreationData();
ccd.CounterType = PerformanceCounterType.RateOfCountsPerSecond64;
ccd.CounterName = counter_name;
ccd.CounterHelp = counter_name;
collection.Add(ccd);

PerformanceCounterCategory.Create(category_name, category_name, PerformanceCounterCategoryType.MultiInstance, collection);

Then, in a separate app, I run this to generate dummy instance data:

var pc = new PerformanceCounter(category_name, counter_name, instance_name, false);
while (true) {
   pc.RawValue = 0;
   Thread.Sleep(1000);
}
spoulson
  • 20,523
  • 14
  • 72
  • 101

6 Answers6

5

Does your program happen to be a 32-bit program running on Windows 2008 R2 or another 64 bit windows OS? If so you may want to check that the service "Performance Counter DLL Host" is running. This service enables 64-bit and remote processes to query counters provided by 32-bit processes.

kennbrodhagen
  • 3,770
  • 2
  • 22
  • 21
2

You can try to adjust WMI permissions using this tool: http://www.codeproject.com/KB/system/WmiSecurity.aspx

Usage:

WmiSecurity.exe /C="%computername%" /A /N=Root/CIMV2 /M=" DOMAIN\USER:REMOTEACCESS" /R
chown
  • 48,838
  • 16
  • 128
  • 167
1

(scribbles previous text out) I think remote access is the problem(try on the actual computer). If not,do find some way to connect something else to it on test computer(basic simple performance counter on a window with a display). Also edit raw value on dummy app to test.

1

It's been a while since I've looked at this, but you may want to try calling NextValue prior to setting the value and seeing if that works. It wouldn't explain why it works on some machines but not others though.

Another fun thing to look at is what's actually going in your instance name. Make sure no reserved characters are going in there otherwise all sorts of bad things happen.

You might be able to get an idea if it's a naming problem by spinning up another application that actually reads the counter. If you can successfully read it and perfmon can't, it means you have a name formatted in a manner that prevents PerfMon from interpreting it correctly.

dotnetnate
  • 771
  • 4
  • 8
0

Try registering the counters on the remote system, i.e.:

lodctr /M:manifest.man

If that doesn't work, it might be a permissions issue.

bneal
  • 166
  • 5
0

This could be a firewall issue, too.

On the remote computer (the one hosting the multi-instance performance counter app), make sure that the Firewall software allows incoming connections:

  • In Windows Firewall, on workstation class computers, the "Performance Logs and Alerts" exception needs to be enabled.
  • In Windows Firewall with Advanced Security, on server class computers, the "Performance Logs and Alerts (DCOM-In)" and "Performance Logs and Alerts (TCP-In)" inbound rules need to be enabled.

Here's a working C# console example for you to check that you've got the firewall configured correctly...

// Based on the MSDN-supplied C# example from:
// Adding and Removing Performance Counter Instances
// http://msdn.microsoft.com/en-us/library/8t39y5k1%28v=VS.71%29.aspx
using System;
using System.Diagnostics;
using System.Threading;

namespace CustomPerformanceCounters
{
    class Program
    {
        private const string categoryName = "Instance Category";
        private const string categoryHelp = "Instanced counter demonstration for StackOverflow.";
        private const string counterName = "Instance Counter";
        private const string counterHelp = "Instanced counter demonstration for StackOverflow.";

        static void RegisterCounter()
        {
            if (!PerformanceCounterCategory.CounterExists(counterName, categoryName))
            {
                PerformanceCounterCategory.Create(
                    categoryName
                    , categoryHelp
                    , PerformanceCounterCategoryType.MultiInstance
                    , counterName
                    , counterHelp
                    );
            }

        }

        static void RunCounter()
        {
            const string instance1 = "instance1";
            const string instance2 = "instance2";
            const string instance3 = "instance3";

            // Assumes category and counter have been created.
            PerformanceCounter myCounter = new PerformanceCounter(
                categoryName
                ,counterName
                , instance1
                , false
                );

            int currentValue = 0;
            int currentIncrement = 1;
            while (true)
            {
                currentValue += currentIncrement;
                if (currentValue > 99)
                {
                    currentIncrement = -1;
                }
                else if (currentValue < 1)
                {
                    currentIncrement = 1;
                }
                int instance1Value = currentValue;
                int instance2Value = 100 - currentValue;
                int instance3Value = Math.Abs(instance1Value - instance2Value);
                Console.WriteLine("Current values: {0}, {1}, {2}", instance1Value, instance2Value, instance3Value);

                myCounter.InstanceName = instance1;
                myCounter.RawValue = instance1Value;
                myCounter.InstanceName = instance2;
                myCounter.RawValue = instance2Value;
                myCounter.InstanceName = instance3;
                myCounter.RawValue = instance3Value;

                Thread.Sleep(1000);
            }
        }

        static void Main(string[] args)
        {
            RegisterCounter();
            RunCounter();
        }
    }
}
AlwaysLearning
  • 4,396
  • 4
  • 21
  • 28