一、背景
前段时间服务器出了点问题,加上学业愈来愈紧张,写博文分享的时间越来越少。虽然不是第一次在博客园上写经验,但是近期分享的博文得到了不少的朋友支持和指正,在这里内心非常感激和开心。希望以后能认真用好时间,把一些有用的经验分享给需要的人,当然本科阶段的我还有许多不懂的,如果在文章中有错误,希望大家多多指正,必虚心受教。
今天要分享的是使用c#获取服务器CPU、RAM、TCP、磁盘使用情况。前段时间,做了一个几十人的并发测试,服务器宕机了,后来上控制管理台检查测试时间段里服务器各项数据,可惜没有这块数据的提供。为此,我想在web程序中,加入一个小监控的功能,以方便自己随时调用和查看我想要的信息。为了实现这个功能,首先得获取服务器上得一些数据:CPU、RAM、TCP、磁盘使用数据。
二、解决思路或过程
首先获取CPU的使用情况:
- 在mvc目录下创建类SystemMonitor.cs,引入命名空间:using System.Runtime.InteropServices;//提供各种各样支持 COM 互操作 及平台调用服务的成员。using System.Diagnostics;//System.Diagnostics 命名空间中,该命名空间提供了用于与事件日志、性能计数器和系统进程进行交互的类。您可以在生产应用程序中保持对此监控代码的启用,并在发生问题时查看相关信息。
添加如下代码:
/// <summary> /// 获取CPU信息 /// </summary> public class CPUInfo { /// <summary> /// 输出CPU信息 /// </summary> /// <returns></returns> public string GetCPUInfo() { StringBuilder sb = new StringBuilder(); int cpuPercent = Convert.ToInt32(GetCPUCounter()); sb.Append(cpuPercent); return sb.ToString(); } /// <summary> /// 获取CPU信息 /// </summary> /// <returns></returns> private static object GetCPUCounter() { PerformanceCounter pc = new PerformanceCounter(); pc.CategoryName = "Processor"; pc.CounterName = "% Processor Time"; pc.InstanceName = "_Total"; dynamic Value_1 = pc.NextValue(); System.Threading.Thread.Sleep(); dynamic Value_2 = pc.NextValue(); return Value_2; } }
再是获取当前服务器内存使用数据:
- 这里需要用到struct和DllImport[""],这里用到的kernel32.dll是Windows9x/Me中非常重要的32位动态链接库文件,属于内核级文件。它控制着系统的内存管理、数据的输入输出操作和中断处理,当Windows启动时,kernel32.dll就驻留在内存中特定的写保护区域,使别的程序无法占用这个内存区域。
代码如下:
/// <summary> /// 获取内存信息 /// </summary> public class MemoryInfo { //定义内存的信息结构 [StructLayout(LayoutKind.Sequential)] public struct MEMORY_INFO { public uint dwLength; public uint dwMemoryLoad; public uint dwTotalPhys; public uint dwAvailPhys; public uint dwTotalPageFile; public uint dwAvailPageFile; public uint dwTotalVirtual; public uint dwAvailVirtual; } /// <summary> /// kernel32.dll是Windows9x/Me中非常重要的32位动态链接库文件,属于内核级文件。
///它控制着系统的内存管理、数据的输入输出操作和中断处理,当Windows启动时,kernel32.dll就驻留在内存中特定的写保护区域,使别的程序无法占用这个内存区域。 /// </summary> [DllImport("kernel32")] private static extern void GetWindowsDirectory(StringBuilder WinDir, int count); [DllImport("kernel32")] private static extern void GetSystemDirectory(StringBuilder SysDir, int count); [DllImport("kernel32")] private static extern void GlobalMemoryStatus(ref MEMORY_INFO meminfo); /// <summary> /// 获取内存信息 /// </summary> /// <returns></returns> public string GetMemInfo() { //调用GlobalMemoryStatus函数获取内存的相关信息 MEMORY_INFO MemInfo = new MEMORY_INFO(); GlobalMemoryStatus(ref MemInfo); //拼接字符串 StringBuilder sb = new StringBuilder(); return MemInfo.dwMemoryLoad.ToString(); } }
接着是磁盘使用数据获取,因为我服务器只有一个C盘,因此这里写死了,有多盘的朋友可以写一个List,同样方法获取总盘的信息:
代码如下:
/// <summary> /// 获取磁盘信息 /// </summary> public class DiskInfo { /// <summary> /// 获取指定驱动器的空间总大小(单位为B) /// 只需输入代表驱动器的字母即可 (大写) /// </summary> /// <param name="str_HardDiskName"></param> /// <returns></returns> public float GetHardDiskSpace(string str_HardDiskName) { float totalSize = new float(); str_HardDiskName = str_HardDiskName + ":\\"; System.IO.DriveInfo[] drives = System.IO.DriveInfo.GetDrives(); foreach (System.IO.DriveInfo drive in drives) { if (drive.Name == str_HardDiskName) { totalSize = drive.TotalSize / ( * * ); } } return totalSize; } public string GetHardDiskSpace() { string str_HardDiskName = "C"; float totalSize = new float(); str_HardDiskName = str_HardDiskName + ":\\"; System.IO.DriveInfo[] drives = System.IO.DriveInfo.GetDrives(); foreach (System.IO.DriveInfo drive in drives) { if (drive.Name == str_HardDiskName) { totalSize = drive.TotalSize / ( * * ); } } string TotalSize = totalSize.ToString(); return TotalSize; } /// <summary> /// 获取指定驱动器的剩余空间总大小(单位为B) /// 只需输入代表驱动器的字母即可 /// </summary> /// <param name="str_HardDiskName"></param> /// <returns></returns> public string GetHardDiskFreeSpace(string str_HardDiskName) { long freeSpace = new long(); string FreeSpace = ""; str_HardDiskName = str_HardDiskName + ":\\"; System.IO.DriveInfo[] drives = System.IO.DriveInfo.GetDrives(); foreach (System.IO.DriveInfo drive in drives) { if (drive.Name == str_HardDiskName) { freeSpace = drive.TotalFreeSpace / ( * * ); } } FreeSpace = freeSpace.ToString(); return FreeSpace; } }
最后是TCP连接数:
代码如下:
/// <summary> /// 获取端口连接数 /// </summary> public class TCPInfo { public string Get_TCP_Count() { string TCPCount = ""; IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties(); TcpConnectionInformation[] connections = properties.GetActiveTcpConnections(); TCPCount = connections.Count().ToString(); return TCPCount; } }
这里还需要补充一个类 Trans,这可以帮助转换格式,如将byte进行转换为GB:
/// <summary> /// 转换 /// </summary> public class Trans { public static decimal ConvertBytes(string b, int iteration) { ; ; i < iteration; i++) iter *= ; , MidpointRounding.AwayFromZero); } }
三、总结与看法
上述代码或许有一些许不全的地方,因为这是我从项目里剥离出来的,所以缺少的一些代码得补上,如果有疑问请留言吧。如果我思路和方法有误,恳请各位指正,虚心求教。转载请注明来源与出处,谢谢合作 By 点将台无将