需求是内在驱动力
要不是项目需要收集系统性能和网络流量,我这辈子也不会跟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画出的图如下: