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

发布于 2024-07-29 22:18:19 字数 1135 浏览 9 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

思念满溢 2024-08-05 22:18:23

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

lodctr /M:manifest.man

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

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.

不可一世的女人 2024-08-05 22:18:23

这也可能是防火墙问题。

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

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

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();
        }
    }
}
白况 2024-08-05 22:18:22

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

(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.

等待我真够勒 2024-08-05 22:18:22

我已经有一段时间没有看过这个了,但您可能想在设置值之前尝试调用 NextValue 并看看是否有效。 它无法解释为什么它在某些机器上有效但在其他机器上不起作用。

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

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

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.

书信已泛黄 2024-08-05 22:18:21

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

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.

空城旧梦 2024-08-05 22:18:21

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

用法:

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文