1. 程式人生 > >.NET Core 跨平臺資源監控庫及 dotnet tool 小工具

.NET Core 跨平臺資源監控庫及 dotnet tool 小工具

[TOC] ### 簡介 CZGL.SystemInfo 是一個支援 Windows 和 Linux 等平臺的能夠獲取機器硬體資訊、採集機器資源資訊、監控程序資源的庫。 在不引入額外依賴的情況下,使用 .NET Runtime 本身的 API,或通過計算獲得資訊,提供高效能的計算方式以及快取,提高效能,還提供 dotnet tool 工具,通過命令列在終端使用。 由於此庫完全是重寫,因此跟舊版本的 API 完全不同,舊版本地址: 舊版本 GitHub: https://github.com/whuanle/CZGL.SystemInfo/tree/0.1 舊版本使用教程: https://www.cnblogs.com/whuanle/p/12435413.html Nuget 搜尋 `CZGL.SystemInfo` 即可安裝,版本為 1.0 。 類庫中每一個屬性和方法,我都加上了貼心的註釋以及 return 示例。 CZGL.SystemInfo.Linux 優化部分程式碼,其餘無變化。 Windows 可以使用 System.Diagnostics.PerformanceCounter 、System.Management.ManagementObjectSearcher 分別獲得性能計算器以及機器的 CPU型號、磁碟序列化號等資訊。 平臺差異而且很難統一,所以如獲取某些硬體的型號序列化,獲得程序資訊的資源資訊,這些需求呼叫系統相關的API或者使用命令列操作,需要自己定製。 ### dotnet tool 體驗 目前做了個簡單的 dotnet 工具,無需 SDK,runtime 下即可使用。 安裝命令: ```shell dotnet tool install --global csys # or dotnet tool install --global csys --version 1.0.3 ``` ``` You can invoke the tool using the following command: csys Tool 'csys' (version '1.0.2') was successfully installed. ``` 如果在 Linux 下,安裝,還需要設定環境變數: ``` export PATH="$PATH:/home/{你的使用者名稱}/.dotnet/tools" ``` 安裝完畢後,輸入命令進入小工具: ```shell csys ``` ```csharp 請輸入命令 +-------命令參考------------------------------+ | 1. 輸入 netinfo 檢視網路詳情 | | 2. 輸入 nett 監控網路流量 | | 3. 輸入 test ,檢查當前作業系統不相容哪些 API | | 4. 輸入 ps 檢視程序資訊 | +---------------------------------------------+ ``` 注:需要使用超級管理員啟動程式,才能使用 ps 功能; 動圖: ![csys](https://img2020.cnblogs.com/blog/1315495/202011/1315495-20201108193212856-2146550625.gif) 小工具功能不多,有興趣可以下載 Nuget 包,裡面有更多功能。 ### CZGL.SystemInfo CZGL.SystemInfo 目前有四個類:DiskInfo、NetworkInfo、ProcessInfo、SystemPlatformInfo,下面一一介紹。 為了避免資源浪費,DiskInfo、NetworkInfo、ProcessInfo 部分屬性使用懶載入,不使用此 API 的情況下,不需要消耗效能。 ```csharp Install-Package CZGL.SystemInfo -Version 1.0.1 ``` ### SystemPlatformInfo 靜態類,能夠獲取執行環境資訊和有限的硬體資訊,所有資訊在程式啟動前就已經確定。 其 API 說明及獲得的資料示例如下: | 屬性 | 說明 | Windows 示例 | Linux 示例 | | -------------------- | ------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | | FrameworkDescription | 框架平臺(.NET Core、Mono等)資訊 | .NET Core 3.1.9 | .NET Core 3.1.9 | | FrameworkVersion | 執行時資訊版本 | 3.1.9 | 3.1.9 | | OSArchitecture | 作業系統平臺架構 | X64 | X64 | | OSPlatformID | 獲取作業系統的型別 | Win32NT | Unix | | OSVersion | 作業系統核心版本 | Microsoft Windows NT 6.2.9200.0 | Unix 4.4.0.19041 | | OSDescription | 作業系統的版本描述 | Microsoft Windows 10.0.19041 | Linux 4.4.0-19041-Microsoft #488-Microsoft Mon Sep 01 13:43:00 PST 2020 | | ProcessArchitecture | 本程序的架構 | X64 | X64 | | ProcessorCount | 當前計算機上的處理器數 | 8 | 8 | | MachineName | 計算機名稱 | dell-PC | dell-PC | | UserName | 當前登入到此係統的使用者名稱稱 | dell | dell | | UserDomainName | 使用者網路域名稱 | dell-PC | dell-PC | | IsUserInteractive | 是否在互動模式中執行 | True | True | | GetLogicalDrives | 系統的磁碟和分割槽列表 | D:\, E:\, F:\, G:\, H:\, J:\, X:\|/, /dev, /sys, /proc, /dev/pts, /run, /run/lock, /run/shm | | | SystemDirectory | 系統根目錄完全路徑 | X:\WINDOWS\system32 | | | MemoryPageSize | 作業系統記憶體頁一頁的位元組數 | 4096 | 4096 | SystemPlatformInfo 的 API 不會有跨平臺不相容問題,可以大膽使用。 效果演示: ```csharp 系統平臺資訊: 執行框架 : .NET Core 3.1.0 作業系統 : Microsoft Windows 10.0.17763 作業系統版本 : Microsoft Windows NT 6.2.9200.0 平臺架構 : X64 機器名稱 : aaaa-PC 當前關聯使用者名稱 : aaa 使用者網路域名 : aaa-PC 系統已執行時間(毫秒) : 3227500 Web程式核心框架版本 : 3.1.0 是否在互動模式中執行 : True 分割槽磁碟 : D:\, E:\, F:\, G:\, H:\, X:\ 系統目錄 : X:\windows\system32 當前程序已使用實體記憶體 : 20020 當前程序已佔耗CPU時間 : 328.125 系統所有程序各種使用的記憶體 : System.Collections.Generic.KeyValuePair`2[System.String,System.Int64][] 系統已使用記憶體 : 5988340 VisualStudioVersion : 16.0 ``` ### ProcessInfo 需要使用超級管理員啟動程式,才能使用此功能; 記錄某一時刻作業系統的資源資料。此 API 使用時有些地方需要注意,比較監控和重新整理資訊會消耗一些效能資源。 通過兩個靜態方法,可以獲取系統的程序列表: ```csharp Dictionary value = ProcessInfo.GetProcessList(); ProcessInfo[] value = ProcessInfo.GetProcesses(); ``` 或者通過指定的程序 ID 獲取: ```csharp ProcessInfo value = ProcessInfo.GetProcess(666); ``` 獲得 ProcessInfo 物件後,必須使用 `Refresh()` 方法重新整理、擷取當前程序狀態的資訊,才能獲得資訊。 如: ```csharp ProcessInfo thisProcess = ProcessInfo.GetCurrentProcess(); // 獲取當前程序的 ProcessInfo 物件 thisProcess.Refresh(); ``` 只有當你使用 `.Refresh()` 時,才會開始初始化,並生成相應的資訊。 獲得的資訊不是動態的,而且儲存某一個節點時刻的程序狀態資料,所以如果需要動態更新,則需要再次執行 `.Refresh()` 方法。 ProcessInfo 能夠獲得程序使用了多少記憶體以及 CPU 時間,但是無法獲得此程序的實體記憶體使用率以及CPU使用率。如果想獲得使用比率,需要呼叫作業系統 API,或者使用作業系統的其它庫,如 Windows 的 WMI。 如果你想獲得一個程序的 CPU 消耗的比例,可以使用靜態方法: ```csharp decimal value = ProcessInfo.GetCpuPercentage(666); ``` 大約 2 秒會重新整理一次,所以請勿一直等待此 API 返回資料,適合單獨計算,不適合跟其它資料綜合。此 API 監控的 CPU 佔比不是很準確。 CPU 是真的難求,你可以檢視論文: https://www.semanticscholar.org/paper/Late-Breaking%3A-Measuring-Processor-Utilization-in-Friedman/d7e312e32cd6bb6cac4531389c5cc7c80481b9b5?p2df 不斷重新整理 CPU 資料: ```csharp while (true) { var tmp = Convert.ToInt32(Console.ReadLine()); var process = ProcessInfo.GetProcess(tmp); process.Refresh(); // 重新整理程序資料 var cpu = ProcessInfo.GetCpuPercentage(process.ProcessId); Console.WriteLine($"程序 {process.ProcessName} CPU : {cpu * 100}%"); } ``` #### 記憶體監控 PhysicalUsedMemory 屬性值返回的值表示程序使用的可分頁系統記憶體的當前大小(以位元組為單位)。 系統記憶體是作業系統使用的實體記憶體,分為分頁和非分頁的池。 當不可分頁記憶體未使用時,可以將其傳輸到磁碟上的虛擬記憶體分頁檔案中。 | 屬性名稱 | 說明 | 示例 | | ------------------ | -------------------- | -------- | | PhysicalUsedMemory | 已用的實體記憶體位元組數 | 17498112 | ### NetworkInfo NetworkInfo 能夠獲取網路介面資訊。 `NetworkInfo.GetNetworkInfo()` 可以獲取當前你的電腦正在連線網際網路的首選網路裝置。 如使用 wifi,獲取到的就是無線網絡卡;使用網線上網,獲取到的是乙太網卡。 API 使用示例: ```csharp var info = NetworkInfo.GetNetworkInfo(); Console.WriteLine("\r\n+++++++++++"); Console.WriteLine($" 網絡卡名稱 {info.Name}"); Console.WriteLine($" 網路連結速度 {info.Speed / 1000 / 1000} Mbps"); Console.WriteLine($" Ipv6 {info.AddressIpv6.ToString()}"); Console.WriteLine($" Ipv4 {info.AddressIpv4.ToString()}"); Console.WriteLine($" DNS {string.Join(',', info.DNSAddresses.Select(x => x.ToString()).ToArray())}"); Console.WriteLine($" 上行流量統計 {info.SendLength / 1024 / 1024} MB"); Console.WriteLine($" 下行流量統計 {info.ReceivedLength / 1024 / 1024} MB"); Console.WriteLine($" 網路型別 {info.NetworkType}"); Console.WriteLine($" 網絡卡MAC {info.Mac}"); Console.WriteLine($" 網絡卡資訊 {info.Trademark}"); ``` Status 屬性可以獲取此網絡卡的狀態,其列舉說明如下: | Dormant | 5 | 網路介面不處於傳輸資料包的狀態;它正等待外部事件。 | | -------------- | ---- | ------------------------------------------------------------ | | Down | 2 | 網路介面無法傳輸資料包。 | | LowerLayerDown | 7 | 網路介面無法傳輸資料包,因為它執行在一個或多個其他介面之上,而這些“低層”介面中至少有一個已關閉。 | | NotPresent | 6 | 由於缺少元件(通常為硬體元件),網路介面無法傳輸資料包。 | | Testing | 3 | 網路介面正在執行測試。 | | Unknown | 4 | 網路介面的狀態未知。 | | Up | 1 | 網路介面已執行,可以傳輸資料包。 | NetworkType 可以獲得網絡卡介面型別,其列舉比較多,詳細請參考: https://docs.microsoft.com/zh-cn/dotnet/api/system.net.networkinformation.networkinterfacetype?view=netcore-3.1 通常,監控網路,一時檢查網路是否暢通,二是監控流量。 `NetworkInfo.IsAvailable` 靜態屬性可以檢查當前機器是否能夠連線網際網路。符合條件的網絡卡必須是能夠執行可以傳輸資料包,並且不能是本地迴環地址。如果你是內網,則可能不需要此API,可以自己 ping 內網其它機器,確保網路暢通。 實時監控網路速度的使用方法: ```csharp var info = NetworkInfo.GetNetworkInfo(); while (true) { var tmp = info.GetInternetSpeed(1000); Console.WriteLine($"網路上傳速度:{tmp.Send / 1024} kb/s"); Console.WriteLine($"網路下載速度:{tmp.Received / 1024} kb/s"); Thread.Sleep(500); } ``` `(int Received, int Send) GetInternetSpeed(int Milliseconds)` 方法可以監控某個的網路傳輸資料量,時間一般時間設定為 1000 ms。 ``` Received 是下載的流量 Send 是上傳的流量 ``` 一般來說,電腦只有一個網絡卡在連線網際網路進行工作,所以可以使用: ```csharp static (int Received, int send) GetNowInternetSpeed(int Milliseconds) ``` 會自動找到電腦正在用來訪問網際網路的網絡卡,並記錄流量大小。 還有個 `Speed` 屬性,可以查詢到網絡卡最大支援速率。 如果是-1,則說明無法獲取此網絡卡的連結速度;例如 270_000_000 表示是 270MB(一般指 300M 網絡卡) 的連結速度。千兆網絡卡是 1000_000_000(1000M)。 其它 API 就不介紹了。 直接反射檢視: ```csharp NetworkInterface System.Net.NetworkInformation.SystemNetworkInterface Id {43538D18-BB0E-4CE2-8F66-613FAC9467BD} Mac E09D3116D014 Name WLAN Trademark Intel(R) Centrino(R) Advanced-N 6205 PhysicalMac E09D3116D014 Status Up NetworkType Wireless80211 Statistics System.Net.NetworkInformation.SystemIPInterfaceStatistics Ipv4Statistics System.Net.NetworkInformation.SystemIPv4InterfaceStatistics ReceivedLength 103449771 ReceivedLengthIpv4 103449771 SendLength 23753785 SendLengthIpv4 23753785 IsAvailable True Speed 300000000 IsSupportIpv4 True IsSupportIpv6 True DnsSuffix DNSAddresses System.Net.NetworkInformation.InternalIPAddressCollection UnicastIPAddressInformationCollection System.Net.NetworkInformation.UnicastIPAddressInformationCollection AddressIpv6 fe90::adbb:6aa1:2b1f:ae9b%11 AddressIpv4 192.168.3.3 GetPhysicalMac E69D3116D514 ``` 注意,因為有些 API ,Linux 下環境差異比較大,建議使用使用 csys 小工具的 test 命令,檢查有哪些 API 可以在此 Linux 環境中使用。 ### DiskInfo DiskInfo 能夠獲取的資訊不多。 可以使用靜態方法獲取所有磁碟的 DiskInfo 物件: ``` DiskInfo.GetDisks() ``` 直接反射看: ```csharp DriveInfo F:\ Id F:\ Name F:\ DriveType Fixed FileSystem NTFS FreeSpace 76498378752 TotalSize 112718770176 UsedSize 36220391424 ``` ## Linux Nuget 搜尋 `CZGL.SystemInfo.Linux` 安裝。 在這個庫中,Linux 資源資訊包括 程序計量,記憶體計量,CPU計量,虛擬記憶體計量,各種程序執行資訊計量。 要通過例項化 `DynamicInfo` 才能獲取。 有 5 個物件用於對映相應資訊。 Tasks:用於統計程序數量,處於不同狀態下的程序數。 CpuState:CPU 使用情況,CPU 各種負載資訊。 Mem:實體記憶體和快取使用情況。 Swap:虛擬記憶體使用情況。 PidInfo:一個程序的執行資源資訊。 他們都有一個 IsSuccess 屬性,用來判斷是否能正常獲取到 Linux 的資訊。 例項化獲取物件 ```c# DynamicInfo info = new DynamicInfo(); ``` ### 直接使用 可以通過方法獲取到相應的物件。 ```c# var item = info.GetTasks(); Console.WriteLine("系統中共有程序數 :" + item.Total); Console.WriteLine("正在執行的程序數 :" + item.Running); ``` ```c# Console.WriteLine(" 程序Id 程序名稱 所屬使用者 優化級 高低優先順序 虛擬記憶體 實體記憶體 共享記憶體 程序狀態 佔用系統CPU(%) 佔用記憶體(%d) "); ``` 輸出 ```c# 程序統計: Total : 93 Running : 1 Sleeping : 59 Stopped : 0 Zombie : 0 CPU資源統計: UserSpace : 1 Sysctl : 0.6 NI : 0 Idolt : 98.3 WaitIO : 0.1 HardwareIRQ : 0 SoftwareInterrupts : 0 記憶體統計: Total : 1009048 Used : 334040 Free : 85408 Buffers : 589600 CanUsed : 675008 獲取虛擬記憶體統計: Total : 0 Used : 0 Free : 0 AvailMem : 505744 ```