为什么不能看到我的自定义性能计数器的实例?

时间:2009-07-30 18:20:30

标签: .net perfmon

我正在为应用程序创建一些自定义性能计数器。我写了一个简单的C#工具来创建类别和计数器。例如,下面的代码片段基本上就是我正在运行的代码片段。然后,我运行一个单独的应用程序,无休止地刷新计数器的原始值。当它运行时,计数器和虚拟实例在perfmon本地可见。

我遇到的问题是我们使用的监控系统无法看到我从另一台服务器远程查看时创建的多实例计数器中的实例。当使用perfmon浏览计数器时,我可以看到类别和计数器,但实例框显示为灰色,我甚至无法选择“所有实例”,也无法单击“添加”。使用其他访问方法(如[typeperf][1])会出现类似问题。

我不确定这是服务器还是代码问题。这只能在我需要的生产环境中重现。在我的桌面和开发服务器上,它运行良好。我是所有服务器上的本地管理员。

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);

然后,在一个单独的应用程序中,我运行它来生成虚拟实例数据:

var pc = new PerformanceCounter(category_name, counter_name, instance_name, false);
while (true) {
   pc.RawValue = 0;
   Thread.Sleep(1000);
}

6 个答案:

答案 0 :(得分:5)

您的程序是否恰好是在Windows 2008 R2或其他64位Windows操作系统上运行的32位程序?如果是这样,您可能需要检查服务“性能计数器DLL主机”是否正在运行。此服务使64位和远程进程能够查询由32位进程提供的计数器。

答案 1 :(得分:2)

您可以尝试使用此工具调整WMI权限: http://www.codeproject.com/KB/system/WmiSecurity.aspx

用法:

WmiSecurity.exe /C="%computername%" /A /N=Root/CIMV2 /M=" DOMAIN\USER:REMOTEACCESS" /R

答案 2 :(得分:1)

(以前的文字涂鸦) 我认为远程访问是问题(尝试在实际的计算机上)。 如果没有,请找一些方法在测试计算机上连接其他东西(带有显示器的窗口上的基本简单性能计数器)。 还要在虚拟应用上编辑原始值以进行测试。

答案 3 :(得分:1)

我已经看了一段时间,但你可能想在设置值之前尝试调用NextValue,看看是否有效。它无法解释为什么它适用于某些机器而不适用于其他机器。

另一个有趣的事情是你的实例名称实际上是什么。确保没有保留字符,否则会发生各种不良事件。

您可以通过启动另一个实际读取计数器的应用程序来了解它是否是命名问题。如果你能成功读取它并且perfmon不能,那就意味着你的名字格式化会阻止PerfMon正确地解释它。

答案 4 :(得分:0)

尝试注册远程系统上的计数器,即:

lodctr /M:manifest.man

如果这不起作用,则可能是权限问题。

答案 5 :(得分:0)

这也可能是防火墙问题。

在远程计算机(托管多实例性能计数器应用程序的计算机)上,确保防火墙软件允许传入连接:

  • 在Windows防火墙中,在工作站类计算机上,需要启用“性能日志和警报”异常。
  • 在具有高级安全性的Windows防火墙中,在服务器类计算机上,需要启用“性能日志和警报(DCOM-In)”和“性能日志和警报(TCP-In)”入站规则。

这是一个有效的C#控制台示例,供您检查是否已正确配置防火墙...

// 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();
        }
    }
}