需求是內在驅動力
要不是項目需要收集系統性能和網絡流量,我這輩子也不會跟collectd打交道;要不是需要采集收集到的數據并以圖形的方式呈現出來,我永遠也不認識rrdtool。
所以需求是內在驅動力,逼著你多學習多實踐。
我的需求是:如何通過這兩個工具生成高顏值的流量圖。
環境
Ubuntu16.04/Ubuntu18.04
介紹
collectd
collectd是一個守護(daemon)進程,用來收集系統性能和提供各種存儲方式來存儲不同值的機制。比如以RRD 文件形式。
任何時候都以官網為主,于是我打開了官網,從上到下瀏覽了一下,發現好像在給RRDtool打廣告。
于是,我就把collectd和RRDtool結合起來使用了,多么的自然!
RRDtool
RRDtool是開放源碼的行業標準、高性能的時間序列數據記錄和繪圖系統。RRDtool可以很容易地集成到shell腳本、perl、python、ruby、lua或tcl應用程序中。這是一種環形數據庫,不用擔心數據越來越多的情況,因為新數據會覆蓋最老的數據。
RRDtool不一定和collectd搭檔,可單獨使用,通過相關命令生成數據庫和圖形。
本文重點是如何通過這兩個工具生成高顏值的流量圖,所以趕快進入正題,其他的有興趣自己看自己動手。
安裝
collectd在線安裝
apt-get install collectd
在線安裝會把依賴庫都安裝上,包括RRDtool。
安裝路徑/etc/collectd,配置文件collectd.conf也在該目錄下。
collectd源碼編譯安裝
下載collectd-5.8.1.tar.bz2:https://www.collectd.org/download.shtml
設置環境變量:
export BUILD_DIR=/tmp/collectd
export INSTALL_DIR=/opt/collectd
mkdir -p /tmp/collectd
cd /tmp/collectd
把官網下載的collectd-version.tar.bz2拷貝到$BUILD_DIR下
編譯安裝:
tar xf collectd-version.tar.bz2
cd collectd-version
./configure --prefix=$INSTALL_DIR && make && make install
自己編譯安裝的缺少RRDtool,所以稍后再安裝RRDtool。
安裝路徑/opt/collectd,配置文件collectd.conf在/opt/collectd/etc/目錄下。
RRDtool在線安裝
apt-get install rrdtool
RRDtool源碼編譯安裝
下載rrdtool.tar.gz: https://oss.oetiker.ch/rrdtool/pub/
設置環境變量:
export BUILD_DIR=/tmp/rrdtool
export INSTALL_DIR=/opt/rrdtool-1.7.2
mkdir -p /tmp/rrdtool
cd /tmp/rrdtool
把官網下載的rrdtool.tar.gz拷貝到$BUILD_DIR下
編譯安裝:
gunzip -c rrdtool-1.7.1.tar.gz | tar xf -
cd rrdtool-1.7.1
./configure --prefix=$INSTALL_DIR && make && make install
遇到的問題:
缺少依賴庫libxml-2.0和pangocairo:
下載的Ubuntu版本下的libpango-1.0-0_1.36.3-1ubuntu1.1_amd64.deb,安裝后重啟黑屏,無法顯示,pangocairo是一個跟顯示圖形有關的軟件,慎重啊,最后只能重裝系統,重頭再來,/(ㄒoㄒ)/~~
我給的建議是,老老實實在線安裝吧。
配置
collectd配置文件:/etc/collectd/collectd.conf增加:
LoadPlugin rrdtool
<Plugin rrdtool>
DataDir "/var/lib/collectd/rrd" # 數據庫存放目錄
StepSize 300 # 每300s更新數據庫
HeartBeat 600 # 若300s沒收集到數據,則過了600s就插入unknown
RRARows 288 # 共288條數據
XFF 0.5
RRASingle true
RRATimespan 3600
RRATimespan 86400
RRATimespan 604800
RRATimespan 2678400
RRATimespan 31622400
</Plugin>
命令
collectd服務
/etc/init.d/collectd start|stop|restart|enable|disable|reload
RRDtool語法
rrdtool info|graph|fetch等
RRD文件
根據配置的路徑"/var/lib/collectd/rrd" ,可以看到/var/lib/collectd/rrd/本機名/有很多目錄,每個目錄下都有xxx.rrd文件記錄收集的數據。看目錄名大概可以猜出是存什么數據的,比如cpu-0,那肯定是cpu數據;memory,那就是內存數據;interface-xxx,就是網絡數據。
流量數據
ifconfig
cd interface-wlx70f11c0d3c16
rrdtool info if_packets.rrd
查看網口名為wlx70f11c0d3c16 ,然后進入interface-wlx70f11c0d3c16目錄:
該目錄下有3個文件,查看if_packets.rrd即可。
看這樣的數據肯定會蒙,沒關系,多查資料,多讀幾遍大概就了解了。
1.配置的是RRARows 288,表示24小時內會產生288組數據,rra[0] rra[1]...就是產生的每組數據;
2.rx:輸入流量,tx:輸出流量;
3.value:表示流量值,單位Byte
顯示圖
RRDtool方便的地方在于可以制圖,通過相關命令就能生成一張圖。
我在python中開發,所以代碼如下:
def graph():
# 定義圖表上方大標題
now = time.localtime()
title = "Traffic statistics (" + str(now.tm_year) + "-" + str(now.tm_mon) + "-" + str(now.tm_mday) + ")"
# 重點解釋"--x-grid","MINUTE:12:HOUR:1:HOUR:1:0:%H"參數的作用(從左往右進行分解)
#"MINUTE:12" # 表示控制每隔12分鐘放置一根次要格線
#"HOUR:1" # 表示控制每隔1小時放置一根主要格線
#"HOUR:1" # 表示控制1個小時輸出一個label標簽
#"0:%H" # 0表示數字對齊格線,%H表示標簽以小時顯示
global rrd_path
command = "rrdtool graph " + prj_path() + "/static/images/flow.png --start -1d --vertical-label=bits/s " \
+ "--x-grid MINUTE:12:HOUR:1:HOUR:1:0:%H --y-grid 25000:2 --units-exponent 3 --width 650 --height 230 " \
+ "--title '" + title + "' DEF:inoctets=" + rrd_path + "/if_packets.rrd:rx:AVERAGE " \
+ "DEF:outoctets=" + rrd_path + "/if_packets.rrd:tx:AVERAGE CDEF:total=inoctets,outoctets,+ " \
+ "LINE1:total#FF8833:total_traffic AREA:inoctets#00FF00:input_traffic LINE1:outoctets#0000FF:output_traffic HRULE:10240#FF0000:'over_value\\r' " \
+ "CDEF:inbits=inoctets,8,* CDEF:outbits=outoctets,8,*, COMMENT:'\\r' COMMENT:'\\r' GPRINT:inbits:AVERAGE:'input_avg_traffic\: %6.2lf %Sbps' " \
+ "COMMENT: GPRINT:inbits:MAX:'max_input_traffic\: %6.2lf %Sbps' COMMENT: GPRINT:inbits:MIN:'min_input_traffic\: %6.2lf %Sbps\\r' COMMENT: " \
+ "GPRINT:outbits:AVERAGE:'out_avg_traffic\: %6.2lf %Sbps' COMMENT: GPRINT:outbits:MAX:'max_output_traffic\: %6.2lf %Sbps' COMMENT: GPRINT:outbits:MIN:'min_out_traffic\: %6.2lf %Sbps\\r'"
execute_command(command)
圖形類似于這樣:
導出數據
若覺得以上圖形不太好看,想自己畫,那首先得獲得數據啊,于是先導出數據。
我在python中開發,所以代碼如下:
def exprot_rrd_dict(rrd_path, date):
start_time = time.strptime(date+' 00:00:00', '%Y-%m-%d %H:%M:%S')
start_time_stamp = int(time.mktime(start_time))
end_time = time.strptime(date+' 23:59:59', '%Y-%m-%d %H:%M:%S')
end_time_stamp = int(time.mktime(end_time))
command = 'rrdtool xport --start ' + str(start_time_stamp) + ' --end ' + str(end_time_stamp)+ ' ' \
+ 'DEF:inoctets=' + rrd_path + '/if_packets.rrd:rx:AVERAGE ' \
+ 'DEF:outoctets=' + rrd_path + '/if_packets.rrd:tx:AVERAGE ' \
+ 'CDEF:inbits=inoctets,8,*,1024,/ CDEF:outbits=outoctets,8,*,1024,/ CDEF:total=inbits,outbits,+ ' \
+ 'XPORT:inbits:input_traffic XPORT:outbits:output_traffic XPORT:total:total_traffic'
p = sysmon.shell_cmd(command)
rrd_dict = xml2json.Xml2Json(p.stdout.strip()).result
return rrd_dict
執行command,得到的p就是導出的數據,轉成json后方便分析,如果顯RRDtool自帶的圖不太好看,可以利用導出的json數據使用d3.js來畫圖。怎么畫就不再贅述了,不是本文重點,畫圖可參考https://observablehq.com/@d3/line-chart
d3.js畫出的圖如下: