標籤:
一、背景
前段時間伺服器出了點問題,加上學業愈來愈緊張,寫博文分享的時間越來越少。雖然不是第一次在部落格園上寫經驗,但是近期分享的博文得到了不少的朋友支援和指正,在這裡內心非常感激和開心。希望以後能認真用好時間,把一些有用的經驗分享給需要的人,當然本科階段的我還有許多不懂的,如果在文章中有錯誤,希望大家多多指正,必虛心受教。
今天要分享的是使用c#擷取伺服器CPU、RAM、TCP、磁碟使用方式。前段時間,做了一個幾十人的並發測試,伺服器宕機了,後來上控制管理台檢查測試時間段裡伺服器各項資料,可惜沒有這塊資料的提供。為此,我想在web程式中,加入一個小監控的功能,以方便自己隨時調用和查看我想要的資訊。為了實現這個功能,首先得擷取伺服器上得一些資料:CPU、RAM、TCP、磁碟使用資料。
二、解決思路或過程
首先擷取CPU的使用方式:
- 在mvc目錄下建立類SystemMonitor.cs,引入命名空間:using System.Runtime.InteropServices;//提供各種各樣支援 COM Interop 及平台叫用服務的成員。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 點將台無將
asp.net mvc4 簡單的伺服器監控開發之C#擷取伺服器CPU、RAM、TCP等系統資訊(上)