[C#] 伺服器監控常用語法 (事件檢視器、CPU 硬碟使用率、程式執行狀況)
如果你有在管理 Windows 伺服器的話,你可能會常常看一下伺服器的狀況,檢查「事件檢視器」是否有異常,檢查 CPU 及硬碟使用率,還有檢查某個程式是否有在執行。
這些都是我平常檢查伺服器會做的事情,其實這些工作都可以讓程式來幫我們執行就好,這樣就可以省下一些遠端登入檢查時間。
我們可以寫一些監控程式放在伺服器上執行,當程式發現有異常時,再立即主動通知我們,讓維護工作更有效率。
要開發這樣的程式,我建議使用 .Net Framework 的架構來寫就好,因為 .Net Framework 與 Windows 的結合較多,可以直接使用 Windows 內建的函式庫來執行工作。
以下我會提供幾個程式範例,這些程式碼可以替我們執行檢查的工作,一起來看看吧。
讀取「事件檢視器」
事件檢視器是 Windows 內建記錄各種訊息的小工具,我們可以在「開始」裡面搜尋「事件檢視器」就會找到這工具了。
通常我會打開「Windows 記錄 > 應用程式」的內容,而裡面我只會看一下「錯誤」的訊息內容,檢查一下這個錯誤訊息,是否有問題要排除,可能有些「錯誤」的內容是可以忽略的,這個要自己判斷了。
這樣的工作,我們可以寫程式,讓程式直接幫我們讀取出有「錯誤」的資料就好了,其他狀態的資料就可以忽略掉。
接著我們回到程式開發環境,我在 Visual Studio 2022 建立一個範例程式,選擇「Windows Forms App (.NET Framework)」,建立新專案。
輸入專案名稱與路徑就可以建立專案了,在文章最下面我會分享今天所建立的範例原始檔。
簡單設計一個介面來執行語法,
在讀取事件檢視器按鈕的語法,可以輸入以下語法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
//讀取事件檢視器 EventLog evLog = new EventLog(); //選取Application 類的 Log evLog.Log = "Application"; //選出 Type 為 Error,且時間為一天內的 Log var AppLogEntries = from EventLogEntry ev in evLog.Entries where ev.EntryType == EventLogEntryType.Error && ev.TimeGenerated > DateTime.Now.AddDays(-1) orderby ev.TimeGenerated descending select new { ev.Source, ev.InstanceId, ev.Message, ev.TimeGenerated, ev.UserName, ev.EntryType, }; //放到DataSource上 dataGridView1.DataSource = AppLogEntries.ToList(); |
在最上面會用到 using System.Diagnostics;
當執行之後,就可以看到以下的結果,從 DataGridView 顯示的都是一天內的錯誤訊息,因為我通常一天檢查一次就行了,如果有資料,我再把資料回傳出來檢查內容就行了。
讀取 CPU 使用率
讀取 CPU 使用率是為了檢查 CPU 是否過於忙碌,如果太忙碌時,就要檢查一下忙碌的原因,可能是正常的狀況,也可能是中毒或木馬執行的問題,所以值得觀察。
接著簡單設計一個介面來執行
讀取 CPU 使用率的語法:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// 取得cpu 效能 PerformanceCounter cpu = new PerformanceCounter( "Processor", "% Processor Time", "_Total"); // 取得近 5 秒的平均值 double cpuAvg = 0; for (int i = 0; i < 5; i++) { cpuAvg += cpu.NextValue(); Thread.Sleep(1000); } cpuAvg = Math.Round(cpuAvg / 5, 0); txtCPU.Text = "CPU 使用率 = " + cpuAvg + " %"; |
這個做法我會取近 5 秒的平均值,你也可以改成 10 秒之類的,因為 CPU 會因為一時的執行而衝高使用率,所以不要單抓一個數值,我會取平均值這樣比較準。
執行後的畫面:
記憶體使用率
如果你需要讀取記憶體使用率,可以使用下列語法:
1 2 3 4 |
// 取得 Memory 使用率 PerformanceCounter memory = new PerformanceCounter( "Memory", "% Committed Bytes in Use"); int memoryUse = Convert.ToInt32(memory.NextValue()); |
讀取硬碟可用容量
讀取硬碟可用容量是觀察硬碟空間是否足夠,如果硬碟容量不夠時,電腦就會當機無法使用,有時候伺服器會因為一些儲存資料太多或是 Log 成長太快,導致容量不夠,所以也值得定時檢查。
接著簡單設計一個介面來執行
讀取硬碟容量的語法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//硬碟可用容量 StringBuilder sb = new StringBuilder(); DriveInfo[] allDrives = DriveInfo.GetDrives(); foreach (DriveInfo d in allDrives) { sb.Append($"裝置 {d.Name}: "); if (d.IsReady == true) { // 可用容量 MB string FreeSpace = (d.TotalFreeSpace / (1024 * 1024)).ToString("N0"); int FreeSpacePercent = Convert.ToInt32(Convert.ToDouble(d.TotalFreeSpace) / Convert.ToDouble(d.TotalSize) * 100); sb.AppendLine($"可用容量: {FreeSpace} MB 使用率: ({FreeSpacePercent} %)"); } } txtHD.Text = sb.ToString(); |
此段語法會用到 using System.IO;
我們可以直接使用 C# 內建函式庫,來取得硬碟的狀態。
執行後的畫面:
檢查程式執行狀況
接著我會檢查幾個重要程式是否有在執行中,通常是一些系統服務,或是自己寫的批次程式,確保伺服器繼續提供服務。
一樣簡單設計介面:
使用的語法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//檢查某程式執行 string[] ProgName = { "w3wp" , "sqlserver", "Batch1" }; //執行程式名稱 StringBuilder sb = new StringBuilder(); foreach (string name in ProgName) { Process[] myProcess = Process.GetProcessesByName(name); if (myProcess.Length == 0) { sb.AppendLine("程式: " + name + " 未執行"); } else { sb.AppendLine("程式: " + name + " 執行中"); } } txtProg.Text = sb.ToString(); |
執行結果:
即時回傳 Line 通知
我已經分享了 4 種我常用的方法,接著分享當監控程式檢查完之後,要即時回報訊息的做法,通常我會立即回傳文字訊息到我的 Line 通知,這樣比較能即時掌握。
要使用 Line 通知,要先去官網 Line Notify 個人頁面 申請一組「發行存取權杖」,請使用電腦瀏覽器開啟。
接著選擇要通知的對象,可以選個人或是群組,個人的話會在第一順位,下面的都是群組。
輸入權杖名稱後就可以按「發行」。
發行後會得到權杖金鑰,先自行儲存此權杖,之後寫程式會用到。
此權杖金鑰關閉後,就查不到了,記得先存起來。
按發行後,這時候個人的 Line 通知也會出現訊息。
如果沒有的話,就是還沒加入官方「LINE Notify」為好友,在好友搜尋欄位輸入「LINE Notify」再加入好友即可。
如果推播對象是群組的話,那就在群組內按「邀請」,將「LINE Notify」加入到群組內就行了。
接著我建立一按鈕來寫程式碼:
發送 Line 通知語法如下:
1 2 3 4 5 6 7 8 9 |
//發送 Line 通知 string message = "測試訊息1\n測試訊息2\n測試訊息3"; HttpClient httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded")); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "{取代你的 Token}"); var content = new Dictionary<string, string>(); content.Add("message", message); httpClient.PostAsync("https://notify-api.line.me/api/notify", new FormUrlEncodedContent(content)); |
此語法會引用
using System.Net.Http;
using System.Net.Http.Headers;
發送前準備好要傳送的訊息,將語法中 {取代你的 Token}
換成你剛剛申請的 Token 就可以了。
執行之後,在 Line 上就會收到此通知了。
以上就是我監控伺服器常用的做法,分享給你,有任何問題都可以與我討論。
範例下載
相關學習文章
- [C#][Line] 如何發送 Line Notify 通知訊息 (開發人員用)
- [WinForm] 如何使用 WebBrowser 顯示 Echarts 圖表
- [ASP.NET Core SignalR] 即時對話聊天室教學 #CH1
如果你在學習上有不懂的地方,需要諮詢服務,可以參考站長服務,我想辨法解決你的問題
如果文章內容有過時、不適用或錯誤的地方,幫我在下方留言通知我一下,謝謝
上面這段line的程式,在.net framework內是可以的,但在.net core 6內則不能運作~~~