跳到主要內容
節省工具箱Jason Tools
經驗分享

LibreNMS 啟用 rrdcached 後 Weathermap 不更新

Jason Cheng 發布 瀏覽 1 次
LibreNMS 啟用 rrdcached 後 Weathermap 不更新
本文目錄
  1. 環境
  2. 症狀
  3. 原因
  4. 修改方式
  5. 注意事項
  6. 結論
  7. 參考資料

LibreNMS 的設備一多,輪詢時寫 RRD 檔的磁碟 I/O 會越來越重,官方建議啟用 rrdcached 把寫入集中、批次處理,效果很明顯。但啟用之後,我發現 Weathermap 的流量圖不會更新了,地圖上的連線全部沒有數字。

追下去是 Weathermap 外掛在 rrdcached 模式下的兩個路徑處理問題,改兩個檔案就好了。這篇記錄原因與修改方式。

環境

項目內容
LibreNMS安裝於 /opt/librenms,RRD 目錄 /opt/librenms/rrd
rrdcached與 LibreNMS 同一台,以 TCP 連線 localhost:42217
WeathermapLibreNMS 官方外掛(librenms-plugins/Weathermap),位於 /opt/librenms/html/plugins/Weathermap

LibreNMS 這邊的 rrdcached 設定:

lnms config:set rrdcached "localhost:42217"
lnms config:get rrd_dir

症狀

  • LibreNMS 本身的流量圖正常,代表 rrdcached 運作沒問題
  • Weathermap 的地圖會產生,但連線上的流量都是 0 或沒有數值
  • 手動執行 Weathermap 的輪詢,記錄裡看得到 rrdtool 找不到 RRD 檔案的錯誤

手動執行的方式:

cd /opt/librenms/html/plugins/Weathermap
sudo -u librenms php map-poller.php

要看更詳細的過程,可以直接對單一地圖加上 --debug:

sudo -u librenms php weathermap.php --config configs/core.conf --debug \
    --daemon localhost:42217 --chdir /opt/librenms/rrd

原因

Weathermap 地圖設定裡的資料來源,通常是像這樣的相對路徑:

TARGET ./core-sw01/port-id12.rrd

沒有 rrdcached 時,Weathermap 會先切換到 RRD 目錄(--chdir)再讀檔,相對路徑沒有問題。啟用 rrdcached 後,讀取改由 rrdtool 透過 --daemon 交給 rrdcached 處理,路徑的處理就出了兩個問題。

問題一:--chdir 傳了空字串

map-poller.php 在 rrdcached 走 TCP 連線時,組出來的指令是:

$cmd = $cmd." --daemon ".$config['rrdcached']." --chdir ''";

--chdir '' 等於沒有切換到 RRD 目錄,相對路徑就對不到正確的檔案。

問題二:trim() 的用法錯了

資料來源的程式 WeatherMapDataSource_rrd.php 想把路徑開頭的 ./ 拿掉,寫成:

$rrdfile = trim($rrdfile, "^./");

但 PHP 的 trim() 第二個參數是字元清單,不是正規表示式:它會把字串兩端所有的 ^、.、/ 字元都去掉,^ 在這裡沒有「開頭」的意思。所以只要路徑是絕對路徑,例如 /opt/librenms/rrd/core-sw01/port-id12.rrd,開頭的 / 也會被拿掉,變成錯誤的相對路徑。

修改方式

map-poller.php

cp /opt/librenms/html/plugins/Weathermap/map-poller.php{,.bak}
nano /opt/librenms/html/plugins/Weathermap/map-poller.php

找到 TCP 連線那一段:

$cmd = $cmd." --daemon ".$config['rrdcached']." --chdir ''";

改成切換到 LibreNMS 的 RRD 目錄:

$cmd = $cmd." --daemon ".$config['rrdcached']." --chdir ".$config['rrd_dir'];

同一段上面還有一個判斷:rrdcached 用 unix socket(設定值含 unix:)時走的是另一個分支,這裡改的只影響 TCP 連線的情況。

WeatherMapDataSource_rrd.php

cp /opt/librenms/html/plugins/Weathermap/lib/datasources/WeatherMapDataSource_rrd.php{,.bak}
nano /opt/librenms/html/plugins/Weathermap/lib/datasources/WeatherMapDataSource_rrd.php

找到:

$rrdfile = trim($rrdfile,"^./");

改成用正規表示式,只拿掉開頭的 ./:

$rrdfile = preg_replace('/^\.\//', '', $rrdfile);

這個檔案裡有兩個讀取 RRD 的函式,都有一段「rrdcached Support: strip "./" from Data Source」,兩處都要檢查。我在寫這篇時看了上游最新的程式碼,其中一處已經改成 preg_replace,另一處(wmrrd_read_from_real_rrdtool_aggregate)還是 trim();你手上的版本可能兩處都還是舊寫法。

可以用 grep 確認:

grep -n 'rrdfile = ' /opt/librenms/html/plugins/Weathermap/lib/datasources/WeatherMapDataSource_rrd.php

驗證

cd /opt/librenms/html/plugins/Weathermap
sudo -u librenms php map-poller.php
ls -l output/

output/ 裡的地圖圖檔時間有更新,打開 Weathermap 頁面看到連線上的流量數字,就修好了。Weathermap 的排程一般是放在 cron 每 5 分鐘跑一次:

*/5 * * * * librenms /opt/librenms/html/plugins/Weathermap/map-poller.php >> /dev/null 2>&1

注意事項

  • 外掛更新會蓋掉修改:Weathermap 是用 git 放在 html/plugins/ 底下的,之後 git pull 更新時這兩處修改可能被覆蓋或造成衝突。建議把修改存成 patch,更新後再套用一次:
cd /opt/librenms/html/plugins/Weathermap
git diff > ~/weathermap-rrdcached.patch
# 更新後
git apply ~/weathermap-rrdcached.patch
  • 檔案權限:改完後確認檔案擁有者仍是 librenms,否則網頁或排程讀不到
  • rrdcached 在其他主機時:rrdcached 在遠端主機時,路徑是以遠端 rrdcached 的基底目錄(-b 參數)為準,LibreNMS 這邊的 rrd_dir 不一定適用,要依實際架構調整

結論

rrdcached 對 LibreNMS 的效能幫助很大,但外掛不一定都跟上了。這次的兩個問題,一個是傳了空的工作目錄,一個是把 trim() 當成正規表示式在用,改起來不難,難的是從「圖不會動」找到這兩行。有在用 Weathermap 又想啟用 rrdcached 的朋友,可以先照這篇檢查一下。

參考資料

Jason Cheng

Jason Cheng

企業開源技術顧問,專注架構規劃與實務導入

關於作者 →

延伸閱讀