PRTG (Paessler Router Traffic Grapher) 是德國 Paessler 公司開發的 Windows 網路監控軟體,提 供友善易用的圖表介面,可用來監控各式網路設備,如路由器、交換機、防火牆、伺服器等,同時也能監控各種應用和服務,如網站、資料庫、郵件伺服器等。監控指標涵蓋 CPU 使用率、記憶體用量、頻寬、延遲時間... 等等,也能設定觸發條件,在系統異常時主動發送警報和通知,並有定期報表,該有的功能都有。

講到系統監控,ElasticSearch + Logstach + Kibana (ELK) 跟 Prometheus + Grafana 算是當今主流,其功能及擴充性固然強大,但架設與管理的複雜度也不容小覻。對於監看系統數字 + 異常警報的單純應用,動用牛刀大隆重了。與 ELK 或 Grafana 相比,PRTG 相對簡單易用許多,會是個不錯的替代選擇。它有以下優點:

  • 從安裝設定到開始監控只需幾分鐘,網頁操作介面夠直覺,不難上手
  • 新增設備、加入 Sensor 到產生圖表在網頁上只需幾個步驟即可完成
  • 自帶資料庫,完全不需設定與管理,歷史資料會自動彙整兩天、30 天、365 天統計
  • 若管理的設備及系統不多,100 個 Sensor 以下可使用 Freeware Edition,免費用於私人或商業用途(Free for personal and commercial use)

除了數百種現成 Sensor,PRTG 也支援自訂 Sensor,只要提供符合規格的 XML 或 JSON 格式,我們也可以自訂 Sensor,讓 PRTG 除了監控 CPU、RAM、Disk、網路設備外,還能監控網站線上人數、每分鐘交易筆數... 等各式自訂指標,只要你統計得出來,就能放進 PRTG 監控。

這篇文章就來試玩一下,我用 ASP.NET Core Minimal 寫了一個無聊的統計,統計每分鐘 Button 被按了幾次。用 ConcurrentDictionary 保存目前跟前一分鐘的統計數字,每次按鈕時 POST 讓當下分的鐘計數器加一,監看數字則抓前一分鐘的次數統計(不再變動)。超過兩分鐘的資料理應設排程或定期器清除較有效率,展示用途為求方便,我選擇在讀取資料時順便清除。

using System.Collections.Concurrent;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => Results.Content($@"
<!DOCTYPE html>
<html><head><title>ASP.NET Core</title></head>
<body>
<form method=""post"">
    <button>Click me</button>
    <p>
        DEBUG INFO: <br />
        {Stats.LastKey} = {Stats.GetData()}<br/>
        {Stats.CurrKey} = {Stats.GetRealTimeData()}<br/>
    </p>
</form>
</body></html>
", "text/html"));
app.MapPost("/", () =>
{
    Stats.Increment();
    return Results.Redirect("/");
});

app.Run();

public static class Stats
{
    static string ToHHmm(this DateTime time) => time.ToString("HH:mm");
    //只保留目前與前一分鐘的資料
    static ConcurrentDictionary<string, int> stats = new ConcurrentDictionary<string, int>();
    public static string CurrKey => DateTime.Now.ToHHmm();
    public static string LastKey => DateTime.Now.AddMinutes(-1).ToHHmm();
    public static void Increment() =>
        stats.AddOrUpdate(CurrKey, 1, (key, value) => value + 1);
    public static int GetData()
    {
        //clear old stats
        stats.Keys.Where(o => o != CurrKey && o != LastKey).ToList()
            .ForEach(o => stats.TryRemove(o, out int _));
        return stats.TryGetValue(LastKey, out int value) ? value : 0;
    }
    public static int GetRealTimeData() =>
        (stats.TryGetValue(CurrKey, out int value)) ? value : 0;
}

接著,試著將統計資料轉成 PRTG 所需的格式。要串接 Web API,有個 HTTP Data Advanced Sensor 可呼叫 HTTP 取得 XML/Json,其中可以包含多組計量數字(以 Channel 為單位,而且 Channel 資料只算一個 Sensor),資料格式範例如下:

<prtg>
    <result>
        <channel>First channel</channel>
        <value>10</value>
    </result>
    <result>
        <channel>Second channel</channel>
        <value>20</value>
    </result>
</prtg>
{
  "prtg": {
   "result": [
      {
        "channel": "First channel",
        "value": 10
      },
      {
        "channel": "Second channel",
        "value": 20
      }
    ]
  }
}

為此,我們在 ASP.NET Core 加入一個 Get("/prtg") 傳回 JSON,channel 名稱為 Clicks,由 Stats.GetData() 傳回上一分鐘次數統計,單位則用 Count:

app.MapGet("/prtg", () => new {
    prtg = new {
        result = new [] {
            new {
                channel = "Clicks",
                value = Stats.GetData(),
                unit = "Count"
            }
        }
    }
});

ASP.NET 端備妥,接著在 PRTG 加入 Sensor。新增 Sensor 時用關鍵字找到 HTTP Data Advanced,按 + 新增:

設定 Sensor Name,輸入 URL:

就醬,這個無趣的計量指標便納入 PRTG 的監控範圍囉~

Seimple example to create a custom sensor for PRTG in ASP.NET Core.


Comments

# by 樂透無名

OMG

Post a comment