雷达智富

首页 > 内容 > 程序笔记 > 正文

程序笔记

C#的网站通过Windows性能计数器监测服务器的性能

2024-08-27 70

背景

使用C#开发的网站,很想知道服务器运行时,相关的各种性能参数。比如:CPU利用率,磁盘读写速度,网络带宽占用,网站链接数等等。如果能够有图表的方式显示就更好了。如果服务器是Windows操作系统,可以通过Windows性能计数器来获取。

用过阿里云的云监控的童鞋,对下面这个界面肯定不会陌生:
image-1657535397207

这是怎么实现的呢?经过一番查找,原来这些数据可以通过读取Windows性能计数器读取到,再将数据做出图表,也可以实现类似的效果。

实现思路

  • 利用C#读取windows性能计数器数据。
  • 将读取到的数据定期写入数据。
  • 根据第2步采集的数据,利用百度EChart制作数据图表。

实施步骤

1.要读取windows性能计数器数据,首先得了解性能计数器是如何存储数据的。每个计数器都是由 分类名称(CategoryName),计数器名称(CounterName),实例名(InstanceName)。
public PerformanceCounter( string categoryName, string counterName, string instanceName )

可以通过控制面板打开性能监视器:
image-1657535414185

image-1657535432861
读取方式:
以读取cpu使用率为例:
var counter=PerformanceCounter(“Processor”, “% Processor Time”, “_Total”);
counter.NextValue();
即可取到当前运行值。

将读取性能计数器的方法可以封装成一个辅助类:

public class SysParams
    {
        public string NodeName { get; set; }
        public float CPUProcessorTime { get; set; }
        public float CPUPrivilegedTime { get; set; }
        public float CPUInterruptTime { get; set; }
        public float CPUDPCTime { get; set; }
        public float MEMAvailable { get; set; }
        public float MEMCommited { get; set; }
        public float MEMCommitLimit { get; set; }
        public float MEMCommitedPerc { get; set; }
        public float MEMPoolPaged { get; set; }
        private publicfloat MEMPoolNonPaged { get; set; }
        public float MEMCached { get; set; }
        public float PageFile { get; set; }
        public float ProcessorQueueLengh { get; set; }
        public float DISCQueueLengh { get; set; }
        public float DISKRead { get; set; }
        public float DISKWrite { get; set; }
        public float DISKAverageTimeRead { get; set; }
        public float DISKAverageTimeWrite { get; set; }
        public float DISKTime { get; set; }
        public float HANDLECountCounter { get; set; }
        public float THREADCount { get; set; }
        public int CONTENTSwitches { get; set; }
        public int SYSTEMCalls { get; set; }
        public float NetTrafficSend { get; set; }
        public float NetTrafficReceive { get; set; }
        public DateTime SamplingTime { get; set; }
        private PerformanceCounter cpuProcessorTime = new PerformanceCounter(Processor, % Processor Time, _Total);

        private PerformanceCounter cpuPrivilegedTime =
            new PerformanceCounter(Processor, % Privileged Time, _Total);

        private PerformanceCounter cpuInterruptTime = new PerformanceCounter(Processor, % Interrupt Time, _Total);
        private PerformanceCounter cpuDPCTime = new PerformanceCounter(Processor, % DPC Time, _Total);
        private PerformanceCounter memAvailable = new PerformanceCounter(Memory, Available MBytes, null);
        private PerformanceCounter memCommited = new PerformanceCounter(Memory, Committed Bytes, null);
        private PerformanceCounter memCommitLimit = new PerformanceCounter(Memory, Commit Limit, null);
        private PerformanceCounter memCommitedPerc = new PerformanceCounter(Memory, % Committed Bytes In Use, null);
        private PerformanceCounter memPollPaged = new PerformanceCounter(Memory, Pool Paged Bytes, null);
        private PerformanceCounter memPollNonPaged = new PerformanceCounter(Memory, Pool Nonpaged Bytes, null);
        private PerformanceCounter memCached = new PerformanceCounter(Memory, Cache Bytes, null);
        private PerformanceCounter pageFile = new PerformanceCounter(Paging File, % Usage, _Total);

        private PerformanceCounter processorQueueLengh =
            new PerformanceCounter(System, Processor Queue Length, null);

        private PerformanceCounter diskQueueLengh =
            new PerformanceCounter(PhysicalDisk, Avg. Disk Queue Length, _Total);

        private PerformanceCounter diskRead = new PerformanceCounter(PhysicalDisk, Disk Read Bytes/sec, _Total);
        private PerformanceCounter diskWrite = new PerformanceCounter(PhysicalDisk, Disk Write Bytes/sec, _Total);

        private PerformanceCounter diskAverageTimeRead =
            new PerformanceCounter(PhysicalDisk, Avg. Disk sec/Read, _Total);

        private PerformanceCounter diskAverageTimeWrite =
            new PerformanceCounter(PhysicalDisk, Avg. Disk sec/Write, _Total);

        private PerformanceCounter diskTime = new PerformanceCounter(PhysicalDisk, % Disk Time, _Total);
        private PerformanceCounter handleCountCounter = new PerformanceCounter(Process, Handle Count, _Total);
        private PerformanceCounter threadCount = new PerformanceCounter(Process, Thread Count, _Total);
        private PerformanceCounter contentSwitches = new PerformanceCounter(System, Context Switches/sec, null);
        private PerformanceCounter systemCalls = new PerformanceCounter(System, System Calls/sec, null);
        private PerformanceCounterCategory performanceNetCounterCategory;
        private PerformanceCounter[] trafficSentCounters;
        private PerformanceCounter[] trafficReceivedCounters;
        private string[] interfaces;

        public void initNetCounters()
        {
            // PerformanceCounter(CategoryName,CounterName,InstanceName) 
            performanceNetCounterCategory = newPerformanceCounterCategory(Network Interface);
            interfaces = performanceNetCounterCategory.GetInstanceNames();
            var length = interfaces.Length;
            if (length  0)
            {
                trafficSentCounters = newPerformanceCounter[length];
                trafficReceivedCounters = newPerformanceCounter[length];
            }

            for (var i = 0; i  length; i++)
            {
                // Initializes a new, read-only instance of the PerformanceCounter class. 
                //   1st paramenter: categoryName-The name of the performance counter category (performance object) with which this performance counter is associated. 
                //   2nd paramenter: CounterName -The name of the performance counter. 
                //   3rd paramenter: instanceName -The name of the performance counter category instance, or an empty string (), if the category contains a single instance. 
                trafficReceivedCounters[i] =
                    new PerformanceCounter(Network Interface, Bytes Sent/sec, interfaces[i]);
                trafficSentCounters[i] = new PerformanceCounter(Network Interface, Bytes Sent/sec, interfaces[i]);
            }

            // List of all names of the network interfaces 
            for (var i = 0; i  length; i++)
                Console.WriteLine(Name netInterface: {0}, performanceNetCounterCategory.GetInstanceNames()[i]);
        }

        public void getProcessorCpuTime()
        {
            float tmp = cpuProcessorTime.NextValue();
            CPUProcessorTime = (float) Math.Round(tmp, 1);
            // Environment.ProcessorCount: return the total number of cores 
        }

        public void getCpuPrivilegedTime()
        {
            float tmp = cpuPrivilegedTime.NextValue();
            CPUPrivilegedTime = (float) Math.Round(tmp, 1);
        }

        public void getCpuinterruptTime()
        {
            float tmp = cpuInterruptTime.NextValue();
            CPUInterruptTime = (float) Math.Round(tmp, 1);
        }

        public void getcpuDPCTime()
        {
            float tmp = cpuDPCTime.NextValue();
            CPUDPCTime = (float) Math.Round(tmp, 1);
        }

        public void getPageFile()
        {
            PageFile = pageFile.NextValue();
        }

        public void getProcessorQueueLengh()
        {
            ProcessorQueueLengh = processorQueueLengh.NextValue();
        }

        public void getMemAvailable()
        {
            MEMAvailable = memAvailable.NextValue();
        }

        public void getMemCommited()
        {
            MEMCommited = memCommited.NextValue() / (1024 * 1024);
        }

        public void getMemCommitLimit()
        {
            MEMCommitLimit = memCommitLimit.NextValue() / (1024 * 1024);
        }

        public void getMemCommitedPerc()
        {
            float tmp = memCommitedPerc.NextValue();
            // return the value of Memory Commit Limit 
            MEMCommitedPerc = (float) Math.Round(tmp, 1);
        }

        public void getMemPoolPaged()
        {
            float tmp = memPollPaged.NextValue() / (1024 * 1024);
            MEMPoolPaged = (float) Math.Round(tmp, 1);
        }

        public void getMemPoolNonPaged()
        {
            float tmp = memPollNonPaged.NextValue() / (1024 * 1024);
            MEMPoolNonPaged = (float) Math.Round(tmp, 1);
        }

        public void getMemCachedBytes()
        {
            // return the value of Memory Cached in MBytes
            MEMCached = memCached.NextValue() / (1024 * 1024);
        }

        public void getDiskQueueLengh()
        {
            DISCQueueLengh = diskQueueLengh.NextValue();
        }

        public void getDiskRead()
        {
            float tmp = diskRead.NextValue() / 1024;
            DISKRead = (float) Math.Round(tmp, 1);
        }

        public void getDiskWrite()
        {
            float tmp = diskWrite.NextValue() / 1024;
            DISKWrite = (float) Math.Round(tmp, 1); // round 1 digit decimal
        }

        public void getDiskAverageTimeRead()
        {
            float tmp = diskAverageTimeRead.NextValue() * 1000;
            DISKAverageTimeRead = (float) Math.Round(tmp, 1); // round 1 digit decimal
        }

        public void getDiskAverageTimeWrite()
        {
            float tmp = diskAverageTimeWrite.NextValue() * 1000;
            DISKAverageTimeWrite = (float) Math.Round(tmp, 1); // round 1 digit decimal
        }

        public void getDiskTime()
        {
            float tmp = diskTime.NextValue();
            DISKTime = (float) Math.Round(tmp, 1);
        }


        public void getHandleCountCounter()
        {
            HANDLECountCounter = handleCountCounter.NextValue();
        }

        public void getThreadCount()
        {
            THREADCount = threadCount.NextValue();
        }

        public void getContentSwitches()
        {
            CONTENTSwitches = (int) Math.Ceiling(contentSwitches.NextValue());
        }

        public void getsystemCalls()
        {
            SYSTEMCalls = (int) Math.Ceiling(systemCalls.NextValue()); }

        public void getCurretTrafficSent()
        {
            var length = interfaces.Length;
            var sendSum = 0.0F;
            for (var i = 0; i  length; i++) sendSum += trafficSentCounters[i].NextValue();
            var tmp = 8 * (sendSum / 1024);
            NetTrafficSend = (float) Math.Round(tmp, 1);
        }

        public void getCurretTrafficReceived()
        {
            var length = interfaces.Length;
            var receiveSum = 0.0F;
            for (var i = 0; i  length; i++) receiveSum += trafficReceivedCounters[i].NextValue();
            var tmp = 8 * (receiveSum / 1024);
            NetTrafficReceive = (float) Math.Round(tmp, 1);
        }

        public void getSampleTime()
        {
            SamplingTime = DateTime.Now;
        }
    }

百度ECharts的用法可以参考百度 官方的例子。

更多实现细节,可以参考文章:https://blogs.msdn.microsoft.com/faber/2014/11/20/tracking-windows-performance-counters-by-application/

实现效果

在线预览:http://qingshanboke.com/Home/performance
image-1657535778890

原文链接:https://blog.csdn.net/a497785609/article/details/83316165

更新于:2个月前
赞一波!3

文章评论

评论问答