获取 RRD
文件的信息 CODE:
[root@dns1 bob]# rrdtool info eth0.rrd
(由于输出信息较多,截取了一部分) CODE:
[root@dns1 bob]# rrdtool last eth0.rrd CODE:
[root@dns1 bob]# rrdtool last eth0.rrd |xargs -i date -d '1970-01-01 {} sec utc' CODE:
[root@dns1 bob]# rrdtool first eth0.rrd CODE:
[root@dns1 bob]# [root@dns1 bob]# rrdtool first eth0.rrd |xargs -i date -d '1970-01-01 {} sec utc' CODE:
rrdtool {update | updatev} filename CODE:
[root@dns1 bob]# rrdtool update eth0.rrd 1163862980:1:2 CODE:
[root@dns1 bob]# rrdtool last eth0.rrd CODE:
[root@dns1 bob]# date -d '1970-01-01 1163862985 sec utc' CODE:
[root@dns1 bob]# date -d '2006-11-18 23:20' +%s CODE:
[root@dns1 bob]# rrdtool update eth0.rrd 1163863200:1 CODE:
[root@dns1 bob]# rrdtool info eth0.rrd CODE:
[root@dns1 bob]# rrdtool update eth0.rrd 1163863200:1:2 CODE:
[root@dns1 bob]# rrdtool last eth0.rrd CODE:
[root@dns1 bob]# CODE:
[root@dns1 bob]# rrdtool updatev eth0.rrd 1163865600:4000:5000 CODE:
[root@dns1 bob]# date -d '1970-01-01 1163894400 sec utc' CODE:
[root@dns1 bob]# rrdtool first eth0.rrd --rraindex 3 CODE:
[root@dns1 bob]# cat get_eth0_traffic.sh QUOTE:
**********************************************************************************************************************
注 :该教程参考了如下内容 :
A
)官方文档 :http://oss.oetiker.ch/rrdtool/doc/index.en.html
B
)abel
兄的大作 :http://bbs.chinaunix.net/viewthread.php?tid=552224&highlight=rrdtool
http://bbs.chinaunix.net/viewthread.php?tid=552220&highlight=rrdtool
作者 :ailms <ailms{@}263{dot}net>
版本 :v1
最后修改 :2006/11/17 17:35
**********************************************************************************************************************
一)前言
可能你已经颇不亟待的想知道如何往 RRD
文件插入数据、如何绘图了吧?hoho
,先别急,在你做这些事情之前,最好先思考以下几个问题 :
A
)如果给你一个 RRD
文件,你能知道它的第一次/
最后一次 update
的时间是在什么时候吗?
B
)如果你很久之前建立了一个 RRD
文件,现在因为工作原因需要对该 RRD
文件进行一些修改。不过遗憾的是,
你已经不记得得当初设置的具体选项和参数了,
这时候该怎么办呢?
这两个问题就对应今天要讲的两个操作 :first/last
、info
。
first
就是用于查看该 RRD
文件中某个 RRA
的第一个数据是在什么时候插入的(或者说第一次更新);
last
就是查看该 RRD
文件的最近一次更新;
info
就是查看 rrd
文件的结构信息。
下面就以实际例子来看一下该怎么用这三个命令 :
二)如何查询一个 RRD
文件的结构信息
filename = "eth0.rrd"
rrd_version = "0003"
step = 300 # RRDtool
希望每5
分钟收到一个数据
last_update = 1163862985 #
这是最近一次更新的 timestamp
。可以用 date
转换为具体的时间
ds[eth0_in].type = "COUNTER" #
有一个名为 eth0_in
的 DS
,DST
是 COUNTER
ds[eth0_in].minimal_heartbeat = 600 # hearbeat
时间是600
秒
ds[eth0_in].min = 0.0000000000e+00 # eth0_in
的最小值是 0
(bytes
)
ds[eth0_in].max = 1.2500000000e+07 # eth0_in
的最大值是 1250000000
(bytes
)
ds[eth0_in].last_ds = "UNKN"
ds[eth0_in].value = 0.0000000000e+00
ds[eth0_in].unknown_sec = 85
ds[eth0_out].type = "COUNTER"
ds[eth0_out].minimal_heartbeat = 600
ds[eth0_out].min = 0.0000000000e+00
ds[eth0_out].max = 1.2500000000e+07
ds[eth0_out].last_ds = "UNKN"
ds[eth0_out].value = 0.0000000000e+00
ds[eth0_out].unknown_sec = 85
rra[0].cf = "AVERAGE" #
第一个 RRA
的编号是0
,不是1
。
rra[0].rows = 600 #
共保存 600
个记录
rra[0].pdp_per_row = 1 #
每个 CDP
由一个 PDP
统计得出
rra[0].xff = 5.0000000000e-01 #
只要当前interval
的 PDP
为 unknown
,则该 CDP
的值也是unknown
rra[0].cdp_prep[0].value = NaN
rra[0].cdp_prep[0].unknown_datapoints = 0
rra[0].cdp_prep[1].value = NaN
rra[0].cdp_prep[1].unknown_datapoints = 0
rra[1].cf = "AVERAGE" #
第二个 RRA
的编号是 1
。同样也是 AVERAGE
型。
rra[1].rows = 600 #
也是保存 600
个记录
rra[1].pdp_per_row = 4 #
每个 CDP
由4
个 PDP
的求平均值得出
rra[1].xff = 5.0000000000e-01 #
每个 CDP
最多允许2
个 PDP
为 unknown
,超过则该 CDP
为unknown
rra[1].cdp_prep[0].value = NaN
rra[1].cdp_prep[0].unknown_datapoints = 3
rra[1].cdp_prep[1].value = NaN
rra[1].cdp_prep[1].unknown_datapoints = 3
[root@dns1 bob]#
由于信息太长,这里截取了后面2
个 RRA
的信息。
三)第一次更新/
最近一次更新
如果想知道最近一次更新发生在什么时候,除了可以用上面的 info
操作,还可以用 last
操作
1163862985
[root@dns1 bob]#
如果转换成具体的时间就是 :
六 11
月 18 23:16:25 CST 2006
[root@dns1 bob]#
1163683200
[root@dns1 bob]#
如果换成具体的时间就是 :
四 11
月 16 21:20:00 CST 2006
[root@dns1 bob]#
这三个命令的语法都非常简单,但并不可以因此小看它们的功能,尤其是 info
操作。日后如果需要对 RRD
文件进行调整,是经常需要用到的。
更新 RRD
文件
**********************************************************************************************************************
注 :该教程参考了如下内容 :
A
)官方文档 :http://oss.oetiker.ch/rrdtool/doc/index.en.html
B
)abel
兄的大作 :http://bbs.chinaunix.net/viewthread.php?tid=552224&highlight=rrdtool
http://bbs.chinaunix.net/viewthread.php?tid=552220&highlight=rrdtool
作者 :ailms <ailms{@}263{dot}net>
版本 :v1
最后修改 :2006/11/17 17:35
**********************************************************************************************************************
一)前言
写了N
多东东,总算到了 update
部分了。这里有必要比较一下 RRDtool
和 MRTG
在 update
方面的差别。
A
)MRTG
可以通过 SNMP
协议直接访问 SNMP
对象,你只需要在 cfg
文件中的 Target
指定 OID
,MRTG
就可以自动替你取回数据。
例如Target[as1_eth0]: 2:n7css@172.17.64.11:::::1
,表示使用 SNMP v1
协议访问 172.17.64.11
主机上 index
为 2
的那个接口,
默认是取 ifInOctets
和 ifOutOctets
这两个对象的值。RRDtool
则没有这个功能,只能你自己写脚本取数据。
B
)MRTG
只支持 COUNTER
和 GAUGE
类型的 Target
;RRDtool
则还可以使用 DERIVE
、ABSOLUTE
、COMPUTE
C
)由于上面的原因,MRTG
无法识别小数,负数。例如你给 MRTG
一个 -1
的值,它会解释为 1
;这点可以通过 LOG
看出来。
小数也不行。例如 .72
(bc
的输出)会被识别为 72
,而不是 0.72
。
D
)MRTG
每次 update
每次运行只更新一次,或者说只插入一行记录。但 RRDtool
可以在一个 updat
操作中插入多个记录。
E
)MRTG
一次要求2
个值,RRDtool
则没有该方面的限制。
F
)最大的一个区别是, MRTG
在收到一个值后会自动得出 timestamp
,并记录在 log
的第一个字段;而 RRDtool
是需要你给出一个 timestamp
,
表示该数据是什么时间采集的。
二)update
操作的语法格式
[--template|-t ds-name[:ds-name]...]
N|timestamp:value[:value...]
at-timestamp@value[:value...]
[timestamp:value[:value...] ...]
N
表示 now
的意思,会被 RRDtool
替换为当前的 timestamp
,也就是 date +%s
的结果。Timestamp
部分比较灵活,可以是数字形式,也可以是
AT-
风格的时间(参考 at
命令的 manual
),有点类似于自然语言的风格。
三)手工方式 update
数据库
我们先学习一下如何手工 update
数据库。Update
命令分成两部分 :
A
)时间戳 (timestamp
):表示该数据是在那个时间点采集的。Timestamp
的格式可以非常灵活 :
数字形式 :
例如1164419418
,表示 “
六 11
月 25 09:50:18 CST 2006”
。通常用于手工插入的方式。
快捷方式 :
N
。字母N
表示当前时间(Now
)。如果是通过 crontab
的方式来运行 update
操作,这是最实用的方式。
AT-
风格 :
所谓的 AT
风格的时间,可以参考 at
命令的 manual
。例如 now
、yesterday
、now-1hour
、now+5min
都是 AT
风格的时间。
要注意的是,如果使用 AT
风格的时间,则时间和第一个value
之间使用 @
分隔,而不是 “:”
B
)数值部分 :一个 RRD
文件可以有多个 DS
,所以一次 update
可以给出多个 value
。多个 value
之间用 “:”
分隔。不过是不是所有的 DS
都必须
给出值呢?不一定。有时候你只想给出一部分 DS
的值,甚至有时候某些类型的 DS
是不允许赋值的,例如 COMPUTE
型的 DS
就是这样一个例子。
四)实际操作
实例一 :一个错误的例子
ERROR: illegal attempt to update using time 0 when last update time is 1163862985 (minimum one second step)
[root@dns1 bob]#
咦?为什么出错了呢?是语法错误吗?不是的,RRDtool
提示最近一次更新是在1163862985
这个时候。也就是说,update
给出的时间戳必须大于该值。
不能等于或者小于该时刻。因为数据一旦插入到 RRA
中,就不允许再次修改。所以 update
会检查给出的时间戳是否大于最后一次更新的时间戳,如果不是
则报错,不予执行。那如何才能知道最近一次更新的时间戳呢?还记得前一篇“
如何获取RRD
文件的信息
”
中介绍的 last
和 info
命令吗?对了!就是它们。
执行一下看看是什么结果 ?
1163862985
[root@dns1 bob]#
last
操作显示的时间戳和上面的报错信息给出的值一样。这个时间是
六 11
月 18 23:16:25 CST 2006
[root@dns1 bob]#
总之如果要 update
数据库,则 update
操作给出的时间戳必须晚于最后一次 update
的时间。
实例二 :还是一个错误的例子
我们挑 23:16
的下一个5
分钟23:20
作为时间戳吧。
1163863200
[root@dns1 bob]#
所以 update
命令为 :
ERROR: expected 2 data source readings (got 1) from 1163863200:1:...
[root@dns1 bob]#
还是不行?!!
仔细看错误信息,原来是我们给少了一个值。还记得 info
命令吗?这会儿它派上用场了。
filename = "eth0.rrd"
…..(
省略)
last_update = 1163862985
ds[eth0_in].type = "COUNTER"
ds[eth0_out].type = "COUNTER"
原来是2
个 DS
,怪不得 RRDtool
会报错了
实例三 :这次应该成功了吧?
[root@dns1 bob]#
这会倒是没有错误信息,那究竟数据是否别插入到 RRA
中了呢?
对于该问题,有两个方法,一个是通过 fetch
操作,从 RRA
中提取数据;但这个我们下一篇再讲。
还有一种方法就是用 updatev
操作来代替 update
。updatev
的 v
表示 verbose
的意思,现在就来看 updatev
的作用 :
实例四 :updatev
的好处
我们执行多个 update
操作
1163864400
[root@dns1 bob]#
[root@dns1 bob]# rrdtool update eth0.rrd 1163864700:3000:4000
[root@dns1 bob]# rrdtool updatev eth0.rrd 1163865000:3300:4600
return_value = 0
[1163865000]RRA[AVERAGE][1]DS[eth0_in] = 1.0000000000e+00
[1163865000]RRA[AVERAGE][1]DS[eth0_out] = 2.0000000000e+00
可以看到 return value
是 0
,这个 return value
你可以理解为 shell
编程中的 exit status
。updatev
用 0
表示成功,-1
表示失败。
不过我们插入的值明明是 3300
和 4600
,为什么出来的结果是 1
和2
呢?
这是因为 eth0_in
和 eth0_out
都是 COUNTER
型的 DS
,所以 RRDtool
在收到 3300
和 4600
后,会作一个运算,就是
(3300-3000
)/ step
(300
)= 1
,(4600-4000
)/step
(300
)=2
,这就是 1
和 2
这两个值的来源了。还记得前面提到的 PDP
吗?
这两个值 (1
和2
)就是 PDP
了,而不是 3300
和 4600
。这点要搞清楚。
实例五 :另外一个 updatev
的例子
[root@dns1 bob]# rrdtool updatev eth0.rrd 1163865300:3300:4600
return_value = 0
[1163865300]RRA[AVERAGE][1]DS[eth0_in] = 0.0000000000e+00
[1163865300]RRA[AVERAGE][1]DS[eth0_out] = 0.0000000000e+00
[root@dns1 bob]#
在1163865300
这个时刻我们给出的值和上次一样,所以 eth0_in
和 eth0_out
的 PDP
都为 0
搞清楚了 PDP
的概念,现在我们来看什么是 CDP
,以及 CDP
是如何计算的
实例六 :通过 updatev
掌握 CF
的概念
return_value = 0
[1163865600]RRA[AVERAGE][1]DS[eth0_in] = 2.3333333333e+00
[1163865600]RRA[AVERAGE][1]DS[eth0_out] = 1.3333333333e+00
[1163865600]RRA[AVERAGE][4]DS[eth0_in] = 1.6666666667e+00
[1163865600]RRA[AVERAGE][4]DS[eth0_out] = 1.6666666667e+00
[1163865600]RRA[AVERAGE][24]DS[eth0_in] = NaN
[1163865600]RRA[AVERAGE][24]DS[eth0_out] = NaN
[root@dns1 bob]#
这次的输出和上次又不一样了。这次 update
操作影响到几个 RRA
,看到 []
中的 1
,4
,24
了吗?它们就是代表不同的 RRA
中每个 CDP
所包含的 PDP
数量。
1
就是 1
个 CDP
包含1
个 PDP
,4
就是 一个 CDP
包含4
个 PDP
(20
分钟)、24
就是 一个 CDP
包含24
个 PDP
(2
小时)。
不过为什么没有 288
呢?eth0.rrd
的第4
个 RRA
不是规定每288
个 PDP
合并为一个 CDP
吗?
因为这个时候还轮不到它出场。1163865600 / 7200 = 161648 ,
也就是说刚好1163865600
是在 7200
的某个周期上(161648
)。
但1163865600 / 86400 ≈ 13470.66
,说明1163865600
还不到 86400
的周期。
必须等到13471* 86400=1163894400
才会出现 [288]
的 CDP
,那这个时间戳代表的时间是什么时候呢?看下面的 date
命令就知道了 :
日 11
月 19 08:00:00 CST 2006
[root@dns1 bob]#
[root@dns1 root]# date -d '1970-01-01 1163865600 sec utc'
日 11
月 19 00:00:00 CST 2006
[root@dns1 root]#
这样不就是刚好相差1
天的时间了吗?你可能会觉得很奇怪,为什么不是00:00
而是 08:00
呢?
还记得create
操作的语法吗?其中有一个 –-start
参数吗?不记得了?没关系,那就得用 first
操作来重新找出来,
1100822400
[root@dns1 bob]#
[root@dns1 bob]# date -d '1970-01-01 1100822400 sec utc'
五 11
月 19 08:00:00 CST 2004
[root@dns1 bob]#
看到了吗?是 2004
年的 11 月19
日早上8
点正,距离 2006-11-19
刚好是2
年,也就是 730
天,
因为 eth0.rrd
的第4
个RRA
只保存730
个记录。每个记录时间上相差1
天。也就是第一个记录是 2004/11/19 8:00 ,
第二个记录是 2004/11/20 8:00
,
第三个记录代表 2004/11/21 8:00
,依次类推。所以离1163865600
最近的下一个记录是发生在 2006/11/19 8:00
。
所以严格意义上来说,RRDtool
中的一天并不一定是从 0:00
开始的,但可以保证的就是两个记录之间肯定相差86400
秒(1
天)。
四)自动更新数据库
其实这些都只不过是手工 update
时需要注意的一些地方,如果是自动更新数据库,时间戳方面就交给 RRDtool
去处理吧,我们不用操心了。
前面我们已经写好了一个脚本,现在就用它来更新
#!/bin/bash
#
首先取得 eth0
接口的 ifIndex
index=$(snmpwalk -IR localhost RFC1213-MIB::ifDescr |grep eth0|cut -d '=' -f 1|cut -d '.' -f 2)
#
再通过 snmp
协议取得 ififInOctets
和 ifOutOctets
的值
#
由于在 /etc/snmp.conf
中配置了 defVersion
和 defCommunity
,所以 snmpget
命令不用指定这两个参数
eth0_in=$(snmpget -IR -Os localhost ifInOctets.${index}|cut -d ':' -f 2|tr -d '[:blank:]')
eth0_out=$(snmpget -IR -Os localhost ifOutOctets.${index}|cut -d ':' -f 2 |tr -d '[:blank:]')
echo ${eth0_in}
echo ${eth0_out}
#
需要我要用这些数据来更新 eth0.rrd
,注意 update
时的 timestamp
我们用的是 N
/usr/local/rrdtool-1.2.14/bin/rrdtool updatev /home/bob/eth0.rrd N:${eth0_in}:${eth0_out}
[root@dns1 bob]#
五)接下来是什么呢?
有了数据,下面该学什么了呢?是绘图吗?
不是!^_^!!
(估计有人快疯了吧)
在绘图之前,你有没有想过 RRDtool
在绘图时如何取数据的呢?
例如我想画2
小时内的数据,那么我们有4
个 RRA
,其 resolution
分别是 300
,1200
,7200
,86400
(还记得什么是 resolution
吗?就是每个 RRA
中两个 CDP
相隔的时间)。是从第一个 RRA
取出 7200/300=24
个记录,
还是从第二个 RRA
取出 7200/1200=6
个记录呢?或者是从第三个 RRA
中取出1
个记录就可以呢?
这些问题我们就留待下一篇再学习吧。这里给大家留几个问题 :
B
) 如果过了 eth0.rrd
在5
分钟内没有收到脚本返回的值,是否立即就用 UNKNOWN
作为 PDP
的值?
C
) 参考上面的例子,搞清楚 heartbeat
的含义
D
) 在搞清楚 heartbeat
后,再想一下 heartbeat
和 step
之间的关系。
RRDTool 入门攻略(三)
最新推荐文章于 2021-01-27 18:04:44 发布