今天要分享的是使用c#獲取伺服器CPU、RAM、TCP、磁碟使用情況。在asp.net mvc 程式中,加入一個小監控的功能,獲取伺服器上得一些數據:CPU、RAM、TCP、磁碟使用數據。 ...
一、背景
前段時間伺服器出了點問題,加上學業愈來愈緊張,寫博文分享的時間越來越少。雖然不是第一次在博客園上寫經驗,但是近期分享的博文得到了不少的朋友支持和指正,在這裡內心非常感激和開心。希望以後能認真用好時間,把一些有用的經驗分享給需要的人,當然本科階段的我還有許多不懂的,如果在文章中有錯誤,希望大家多多指正,必虛心受教。
今天要分享的是使用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(1000); 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 / (1024 * 1024 * 1024); } } 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 / (1024 * 1024 * 1024); } } 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 / (1024 * 1024 * 1024); } } 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) { long iter = 1; for (int i = 0; i < iteration; i++) iter *= 1024; return Math.Round((Convert.ToDecimal(b)) / Convert.ToDecimal(iter), 2, MidpointRounding.AwayFromZero); } }
三、總結與看法
上述代碼或許有一些許不全的地方,因為這是我從項目里剝離出來的,所以缺少的一些代碼得補上,如果有疑問請留言吧。如果我思路和方法有誤,懇請各位指正,虛心求教。轉載請註明來源與出處,謝謝合作 By 點將台無將