17

我正在为应用程序创建一些自定义性能计数器。我编写了一个简单的 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);
}
4

6 回答 6

5

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

于 2010-11-10T02:57:13.657 回答
2

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

用法:

WmiSecurity.exe /C="%computername%" /A /N=Root/CIMV2 /M=" DOMAIN\USER:REMOTEACCESS" /R
于 2010-12-09T19:11:24.300 回答
1

自从我查看此内容以来已经有一段时间了,但是您可能想在设置值之前尝试调用 NextValue 并查看它是否有效。它无法解释为什么它可以在某些机器上运行,但在其他机器上却不行。

另一个有趣的事情是您的实例名称中的实际情况。确保其中没有保留字符,否则会发生各种不好的事情。

您可以通过启动另一个实际读取计数器的应用程序来了解这是否是命名问题。如果您可以成功读取它而 perfmon 不能,这意味着您的名称格式设置为阻止 PerfMon 正确解释它。

于 2010-11-23T23:48:19.967 回答
1

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

于 2010-10-19T21:18:15.453 回答
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();
        }
    }
}
于 2010-11-26T02:02:09.213 回答
0

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

lodctr /M:manifest.man

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

于 2010-10-28T16:39:24.663 回答