前幾天分享過好用的 CPU/RAM/Disk 效能監視 CLI 工具,並用它 結合 K6 壓力測試在圖表呈現 CPU 使用率(下圖藍線):

這個做法雖然可行,但操作起來頗麻煩。得在測試前登入目標主機執行 typeperf -cf counters.txt -si 1,測試完成按 Ctrl-C 中斷程式,把 CSV 檔帶回來給解析程式以做成圖表。

於是我開始動腦筋優化流程:若 CPU/RAM 等效能數值能透過 WebAPI 查詢,會更容易整合進 K6 測試,壓測時一併蒐集 CPU 數據寫進結果 JSON,產生報表時一起解析畫進圖表,豈不美滋滋?
(註:這個 WebAPI 需放在壓測對象主機執行,過程可能因該主機 CPU 100% 導致無回應或延遲,但考慮這些數據純為參考觀察趨勢用,不需絕對準確,漏拍或延遲幾秒還可被接受)

不囉嗦,捲起袖子我寫了個超簡單的 ASP.NET Core Minimal API。在 Program.cs 中啟動 Process 執行 typeperf,再由 StandardOutput Stream 讀取每秒一次的輸出,更新最近狀態透過 HTTP GET 存取。只用了 36 行就寫好一個提供 HTTP 查詢 CPU/RAM/Disk 即時使用率的 WebAPI (原本想走 UDP 更輕巧,但考慮呼叫方便,最後仍決定用 WebAPI)。要讀取哪些計數器可透過 counters.txt 自訂(細節請參考前文),可視需要彈性擴充調整。另外,針對未來也會測試 Linux,我順手加上偵測 OS 改用 vmstate -1 取代 typeperf 的邏輯,讓程式也能在 Linux 執行。完整程式碼如下:

using System.Diagnostics;
using System.Runtime.InteropServices;
string perfCounters = string.Empty;
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
    throw new NotImplementedException("OSX not supported yet");
var isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
var task = Task.Factory.StartNew(() =>
{
    var proc = new Process
    {
        StartInfo = new ProcessStartInfo
        {
            FileName = isLinux ? "vmstat" : "typeperf.exe",
            Arguments = isLinux ? "1" : "-cf counters.txt",
            RedirectStandardOutput = true,
            CreateNoWindow = true
        }
    };
    proc.Start();
    while (!proc.StandardOutput.EndOfStream)
    {
        var line = proc.StandardOutput.ReadLine();
        if (string.IsNullOrEmpty(line) || line.Contains("s")) continue;
        try
        {
            string[] parts = isLinux ?
                line.Split(' ', StringSplitOptions.RemoveEmptyEntries) :
                line.Split(',').Skip(1).Select(o => o.Trim('"')).ToArray();
            perfCounters = $"{DateTime.Now:HH:mm:ss.fff},{string.Join(",", parts)}";
        } catch { /* ignore */ }
    }
});
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => perfCounters);
app.Run();

在 Windows 執行 OK:

在 Linux 執行也沒問題:

就醬,又用 .NET 輕鬆搞定一件需求。好久沒呼口號了,今天來一下:

.NET 好威呀,C# 真棒!

原始碼已放上 Github,想玩的同學請自取。

The program collects performance counter data using the typeperf command on Windows and the vmstat command on Linux, with a one-second interval. The collected data is used to update the latest status and is provided to the client through HTTP GET for querying.


Comments

# by 57

如果要指定 port 要怎麼改?

# by Jeffrey

to 57,可參考這篇 https://blog.darkthread.net/blog/set-kestrel-port/

Post a comment