[size=4]四)实际例子[/size]

实例一 :默认情况

 

 [root@dns1 bob]# rrdtool fetch eth0.rrd AVERAGE |more                         eth0_in            eth0_out  1164467700: 1.1337243905e+01 9.6323712631e-02 1164468000: 1.7896453039e+01 0.0000000000e+00 1164468300: 1.8469136234e+01 1.2215723119e+00 。。。。(中间省略) 1164553800: 6.9634610564e+01 4.9644415243e+01 1164554100: nan nan  

 


 [root@dns1 bob]# date (当前时间) 日 11月 26 23:11:12 CST 2006  [root@dns1 bob]# date -d '1970-1-1 1164554100 sec utc' (最后一个记录的时间) 日 11月 26 23:15:00 CST 2006 [root@dns1 bob]#  [root@dns1 bob]# date -d '1970-1-1 1164467700 sec utc' (第一个记录的时间) 六 11月 25 23:15:00 CST 2006 [root@dns1 bob]#  


fetch 输出的第一列是 timestamp ,表示后面的数据是在什么时间收到的。”:” 后面就是DS的值。fetch 不能指定只取那个 DS 的数据,

只能一次性取出全部 DS 的值。可以看到,eth0.rrd 有两个 DS :eth0_in 和 eth0_out ,每个 DS 的值用 空格进行分隔,一律采用科学记数法的格式。

如果 fetch 不指定 –-start 和 -–end ,则默认取从当前时刻算起,往前1天的数据(289个记录)。因为现在是 23:11 ,还不到 23:15,所以最后一个记

录的值是 NaN (Not a Number),也就是 UNKNOWN 的意思。可以看到,两个记录之间的时间间隔是300。

 
 实例二:使用 --start 和 --end 指定时间范围

 

 [root@dns1 bob]# rrdtool fetch eth0.rrd AVERAGE --start 1164467700 --end 1164553800 |more                         eth0_in            eth0_out  1164468000: 1.7896453039e+01 0.0000000000e+00 1164468300: 1.8469136234e+01 1.2215723119e+00 1164468600: 1.5988336199e+01 1.4417769382e-01 。。。。。(中间省略很多) 1164553800: 6.9634610564e+01 4.9644415243e+01 1164554100: 1.7481962958e+02 2.3086574912e+02 [root@dns1 bob]# 


可以看到第一个记录和最后一个记录都比 –-start  和 –-end 晚了300秒。


实例三 :使用 AT风格的时间
 


 [root@dns1 bob]# rrdtool fetch eth0.rrd AVERAGE --start end-1day --end 1164553800 |more                         eth0_in            eth0_out  1164467700: 1.1337243905e+01 9.6323712631e-02 1164468000: 1.7896453039e+01 0.0000000000e+00 。。。。。。。(中间省略很多) 1164554100: 1.7481962958e+02 2.3086574912e+02 [root@dns1 bob]# 


注意 --start 的值是 end-1day ,这就是 AT风格的时间。end 就是 --end 中给出的1164553800 。具体的时间范围是表示起始时间从1164553800 往前1天 。

可以看到,现在第一个记录和实例二相比,提前了300秒。和例2中的 –start 一致了。所以能够用 AT风格的时间的时候还是用 AT 风格的时间比较方便。

可以省去计算的麻烦,别人也比较容易看。


实例四 :提取指定 resolution 的数据

 

 [root@dns1 bob]# rrdtool fetch eth0.rrd AVERAGE --start 1164467700 --end start+1day -r 1200 |more                         eth0_in            eth0_out  1164468000: 1.7899370295e+01 3.8782610300e+00 1164469200: 2.0828335735e+01 3.4166666667e-01 1164470400: 1.4581351504e+01 3.5000000000e-02 。。。。。。(中间省略很多) 1164554400: 9.4367707174e+01 9.4866775629e+01 [root@dns1 bob] 


可以看到,现在记录两两之间的时间间隔变成了1200 了。输出的行数为 (86400/1200)+1=73 (72+1)。


实例五:如果指定一个不存在的 resolution 呢?

 

 [root@dns1 bob]# rrdtool fetch eth0.rrd AVERAGE --start 1164467700 --end start+1day -r 1000 |more                          eth0_in            eth0_out  1164468000: 1.7899370295e+01 3.8782610300e+00 1164469200: 2.0828335735e+01 3.4166666667e-01 。。。。。。(中间省略很多) 1164554400: 9.4367707174e+01 9.4866775629e+01 [root@dns1 bob]# 


我们指定的 resolution 是 1000 ,但并没有那个 RRA 的 resolution 为 1000,所以 RRDtool 挑选了第一个合适的 resolution ,

也就是 1200 的那个 RRA 的数据作为结果输出。注意,RRDtool 只会挑选 resolution 比 –r 指定的值相等或者更高的 RRA ,不会挑

选比 –r 指定的值小的 RRA 。例如在该例子中,RRDtool 就不会挑选 resolution=300 的第一个 RRA 。为什么呢?

各位可以自己根据第三部分“fetch 如何提取数据”的两个准则考虑一下


实例六 :再来看一个 –r 的例子

如果我不想指定 –-start 或者 –end ,就想看 resolution 为 1200 呢?

 

 [root@dns1 bob]# rrdtool fetch eth0.rrd AVERAGE -r 1200                         eth0_in            eth0_out  1164470400: 1.4581351504e+01 3.5000000000e-02 1164471600: 1.9312781373e+01 3.5000000000e-02 。。。。。(中间省略很多) 1164555600: 8.5249300043e+01 7.0171152327e+01 1164556800: nan nan [root@dns1 bob]# 


咦?为什么还是使用记录的时间间隔还是 300 秒呢?我们不是指定了 –r 1200 吗?

老实说,这种方法 90% 以上的机率是不会成功吗?那应该怎么办呢?

实例七 :正确使用 –r 的方式

 

 [root@dns1 bob]# rrdtool fetch eth0.rrd AVERAGE -r 1200 --end $((($(date +%s)/1200)*1200)) |more                         eth0_in            eth0_out  1164470400: 1.4581351504e+01 3.5000000000e-02 1164471600: 1.9312781373e+01 3.5000000000e-02 1164472800: 1.7383358822e+01 3.5000000000e-02 1164474000: 1.4781054841e+01 3.3225406191e-01 。。。。。。(中间省略很多) 1164555600: 8.5249300043e+01 7.0171152327e+01 1164556800: nan nan  [root@dns1 bob]# 


现在 resolution 已经变成 1200 的了。同理,如果想看 7200,86400 resolution的 RRA,只要把 end 部分的 ( )中的数字替换为相应的值就可以了。

 

 [root@dns1 bob]# rrdtool fetch eth0.rrd AVERAGE -r 7200 --end $((($(date +%s)/7200)*7200))     [root@dns1 bob]# rrdtool fetch eth0.rrd AVERAGE -r 86400 --end $((($(date +%s)/86400)*86400))  

 
实例八 :关于 fetch 提取数据准则1的测试

 

 [root@dns1 bob]# rrdtool fetch eth0.rrd --start now-3day AVERAGE |more                         eth0_in            eth0_out  1164298800: nan nan 1164300000: nan nan 。。。。。。(中间省略很多) 1164556800: 6.4118014239e+01 1.8871145267e+01 1164558000: nan nan [root@dns1 bob]# 


和第一个例子不同,这次的 resolution 是 1200 了?为什么呢?因为我们指定的时间范围是3天,而第一个 RRA只保存2天的数据多一点,所以 RRDtool 不会从

该 RRA 取数据,那么会从那个 RRA 取数据呢?由于我们没有指定 –r 选项,所以 RRDtool 选择1200 的那个 RRA

实例九 :关于 fetch 提取数据准则2的测试

 

 [root@dns1 bob]# rrdtool fetch eth0.rrd --start now-3day AVERAGE -r 7200 |more                         eth0_in            eth0_out  1164304800: nan nan 1164312000: nan nan 1164319200: nan nan 。。。。。。(中间省略很多) 1164549600: 5.1899602485e+01 4.3073128067e-01 1164556800: 7.9766222122e+01 4.0644151093e+01 1164564000: nan nan [root@dns1 bob]# 

 

现在 resolution 不再是 1200 ,而是指定的 7200 了。

因为虽然 resolution=1200 的 RRA 就可以满足 --start 和 --end 的需求,

但因为 -r 指定 resolution=7200 ,所以从第3个 RRA 中取数据

[size=4]五)总结[/size]

从上面我们可以看出,fetch 实际上是非常复杂的一个命令,如果想要输出你所要的数据,就必须考虑好几个因素 :

A)[color=blue]第一是具体想输出的时间范围?[/color]

B)[color=blue]第二是计算好 –-start 和 –end。建议至少给出一个,最好2个都给出[/color]

C)[color=blue]第三是如果有多个RRA符合条件,则使用 –r 指定具体的 resolution[/color]


--------------------------------------------------------------------------------
 ailms 回复于:2006-12-04 09:25:49

使用RRDtool 进行绘图(一)
[color=blue]
**********************************************************************************************************************
注 :该教程参考了如下内容 :
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
**********************************************************************************************************************
[/color]

[size=4]一)前言[/size]

使用RRDtool 我们最关心什么?当然是如何把数据画出来了。虽然前面谈了很多,但这些都是基础来的。掌握好了,可以让你在绘图时更加得心应手。

本来还有 RPN (反向波兰表达式)一节的,但考虑一下,觉得还是放到后面,先从基本的绘图讲起。

这一节的内容虽然很多,但基本都是实验性的内容,只要多试几次就可以了。

[size=4]二、graph 操作的语法[/size]

 

 rrdtool graph filename [option ...]     [data definition ...]    [data calculation ...]    [variable definition ...]    [graph element ...]    [print element ...] 


其中的 data definiton、variable definition 、data calculation、分别是下面的格式

 

 DEF:<vname>=<rrdfile>:<ds-name>:<CF>[:step=<step>][:start=<time>][:end=<time>][:reduce=<CF>] VDEF:vname=RPN expression CDEF:vname=RPN expression 


其中 filename 就是你想要生成的图片文件的名称,默认是 png 。你可以通过选项修改图片的类型,可以有 PNG、SVG、EPS、PDF四种。

A)DEF 是 Definition (定义)的意思。定义什么呢?你要绘图,总要有数据源吧?DEF 就是告诉 RRDtool 从那个 RRD 中取出指定

    DS(eth0_in、eth0_out)的某个类型的统计值(还可以指定 resolution、start、end),并把这一切放入到一个变量 <vname>中 。
   
    你可能会感到奇怪,为什么还有一个 CF 字段?因为 RRA 有多种  CF 类型,有些 RRA 可能用来保存平均值、有些 RRA 可能用于统计最大值、
   
    最小值等等。所以你必须同时指定使用什么 CF 类型的 RRA的数据。至于 :start 和 :end 、:reduce 则用得比较少,最常用的就是 :step 了,
   
    它可以让你控制 RRDtool 从那个 RRA 中取数据。

B)VDEF 是 Variable Definition (变量定义)的意思。定义什么呢?记得 MRTG 在图表的下面有一个称之为 Legend 的部分吗?

    那里显示了1个或者2个 DS (MRTG 没有 DS 一说,这里是借用 RRDtool 的)的 “最大值”、“平均值”、“当前值”。这些值是如何
   
    计算的呢?
   
    RRDtool 中用 VDEF 来定义。这个变量专门存放某个 DS 某种类型的值,例如 eth0_in 的最大值、eht0_out 的当前值等。当你需要象
   
     MRTG  一样输出数字报表(Legend) 时,就可以在 GPRINT 子句(sub clause)中调用它。
  
   同样它也需要用一个变量来存放数值。要注意的是,旧版 的 RRDtool 中是用另外一种格式来达到相同的目的。新版的 RRDtool 则推荐使用
  
    VDEF   语句。但在使用过程中,却发现 VDEF 的使用反而造成了困扰。 例如你有5个 DS 要画,每个 DS 你都想输出最大值、最小值、平均值
   
    、当前值。  如果使用 VDEF ,则需要 4 * 5 = 20 个 VDEF 语句,这会造成极大的困扰。具体例子可以看第十一节“数字报表”部分。
  
C)CDEF 是 Calculation Define 的意思。使用过MRTG 的都会体会到一点,MRTG 的计算能力实在太差了。例如你有两个 Target ,

      一个是 eth0_in , 一个是 eth0_out,如果要把它们相加起来,再除以8,得出 bytes 为单位的值,如何计算呢?或者说你只想看
     
      eth0_in 中超过 10Mb/s 的那部分, 其余的不关心,又如何实现呢?因为 MRTG 不能对它从 log 取出来的数据进行修改,只能原
     
      原本本的表现,所以很难满足我们的要求。而使用 CDEF , 这一切都可以很容易的实现。CDEF 支持很多数学运算,甚至还支持简
     
      单的逻辑运算 if-then-else ,可以解决前面提到的第2个问题:如何只绘制你所关 心的数据。不过这一切都需要熟悉 RPN 的语法,
     
      所以我们放到下一节介绍,这一节就介绍如何把 RRDtool 中的数据以图表的方式显示出来。
     
     
[size=4]三)选项分类[/size]

本部分我们按照官方文档的方式,把选项分成几大类,分为  :

A)Time range : 用于控制图表的X轴显示的起始/结束时间,也包括从RRA中提取指定时间的数据。

B)Labels :用于控制 X/Y 轴的说明文字。

C)Size :用于控制图片的大小。

D)Limits :用于控制 Y 轴的上下限。

E)Grid :用于控制 X/Y 轴的刻度如何显示。

F)Miscellaneous :其他选项。例如显示中文、水印效果等等。

G)Report :数字报表

需要说明的是,本篇当中并不是列出了所有选项的用法,只是列出较为常用的选项,如果想查看所有选项的的用法,可以到官方站点下载文档,

这里就不一一列出了,望各位见谅。


[size=4]四)时间范围控制(Time Range)[/size]

 

 [-s|--start time] [-e|--end time] [-S|--step seconds] 


既然要绘图,就应该有一个起始/结束的时间。Graph 操作中有 –s ,-e 选项。这两个选项即可以用于控制图表的 X 轴显示的时间范围,也可以用

于控制 RRDtool 从 RRA 中提取对应时间的数据。如果没有指定 –-end ,默认为 now;如果没有指定 –-start,则默认为1天前。如果两者都没有

指定,则图表默认显示从当前算起1天内的。数
回头看一下 DEF 中,也有 :start ,:end , :step ,这些和 –-start、--end、--step 之间有什么关系呢?

让我们先看 :step 和 –step之间的关系是如何的。

下面以 eth0.rrrd 为例,假设要绘制的时间范围 range 等于 end -start[

A)如果 0 <  ragne < 180000 (第一个 RRA 的时间覆盖范围) ,则默认从第1个RRA中取数据 :

     如果 DEF 中给出的 :step > 300 ,例如 1000 ,则从 resolution= 1000 的或者第一个高于 1000 的RRA 中挑选数据,由于 eth0.rrd 中没有
   
                                                     resolution = 1000 的 RRA,则 RRDtool 会从 resolution = 1200 的第2 RRA 中取数据。

     如果 DEF 中给出的 :step <= 300 ,例如 200 ,则 RRDtool 会忽略该设定,还是从第一个 RRA 中取数据。

B)如果 180000 < range < 720000  ,由于第一个RRA只能保存2天的数据,所以默认从第2个RRA中取数据 :

     如果 DEF 中给出的 :step > 1200 ,例如 1800,则 RRDtool 会从 resolution = 7200 的第3 RRA 中取数据

     如果 DEF 中给出 :step<= 1200,例如 300 ,则 RRDtool 会忽略,还是从第2个 RRA 中取数据

C)如果 720000 < range <  4320000 ,则默认从第三个 RRA 中取数据 :

     如果 DEF 中给出的 :step > 7200 ,例如 10000 ,则从第4个 RRA中取数据

     如果 DEF 中给出的 :step <= 7200 , 例如 1200 ,则忽略该值,并还是从第3 个 RRA 中取数据

D)如果 4320000 < range < 63072000 ,则默认从第4个 RRA 中取数据 :

     如果 DEF 中给出的 :step > 86400 ,则行为未知

     如果 DEF 中给出的 :step <=86400 ,则从第4个 RRA 中取数据

E)-S 选项可以直接控制 RRDtool 如何挑选 RRA 。

    例如 -S 1200 ,即使DEF 中不加 :setp ,则 RRDtool 会从第2个 RRA 中取数据,即使 rang < 180000

    如果 -S 和 :step 同时出现,则 :step 优先。

F)DEF 中的 :start 和 :end 可以覆盖 –-start 和 –-end 的值。

     默认情况下,如果 DEF 中不加 :start 和 :end ,则等于 –-start 和 –end

    如果 DEF 中定义了 :start 和 :end ,则以 :start 和 :end 为准。

实例1 :使用 –-start 指定 X 轴的起始时间

 

 [root@dns1 bob]# rrdtool graph 1.png / > --start now-120000 / # 表示起始时间是当前时间往前 120000 秒,也就是 33 个小时左右 > DEF:value1=eth0.rrd:eth0_in:AVERAGE /  # 从eth0.rrd 中取出 eth0_in 的数据,CF 类型为 AVERAGE > AREA:value1#ff0000 # 用“方块”的形式来绘制 value1 ,注意这里是用 value1 ,不是用 eth0_in 481x154 # 如果 RRDtool 有绘图方面的语句,则这里显示图片大小,否则为 0x0。 [root@dns1 bob]# 

 


可以看到 X 轴的文字有些是乱码,不过不要紧,你可以临时已用 env LANG=C rrdtool xxxx 来解决该问题,或者在后面用

 –n 来设定 RRDtool 使用中文字体,就不会出现这样的情况了


实例2 :使用 :step 从第2个RRA中取数据

 


 [root@dns1 bob]# rrdtool graph 2.png / > --start now-120000 / > DEF:value1=eth0.rrd:eth0_in:AVERAGE:step=1000 / # :step 指定 resolution=1000  > AREA:value1#ff0000 481x154 [root@dns1 bob]#  


这里是 :step=1000,但 RRDtool 会取 :step=1200 的 第2个 RRA 的数据来绘图,可以和上面的 1.png 比较,发现比较平滑。

 


实例3 :使用 –S 从第2个RRA中取数据

 

 [root@dns1 bob]# rrdtool graph 4.png  > -S 1200 / # 使用 –S 控制 RRDtool 从 resolution=1200 的 RRA 中取数据 > --start now-120000 / > DEF:value1=eth0.rrd:eth0_in:AVERAGE / > AREA:value1#ff0000         481x154  [root@dns1 bob]#   

 
 

可以看到和上面的图一样,说明 RRDtool 的确按照 -S 的设置从第2个RRA 中取数据了

使用 –S 可以对 DEF 中所有的 DS 都使用相同的 resolution,等于在每个 DEF后都加上 :step=<value> ,value 是 –S 的值

实例4 :同时使用 –S 和 :step

 

 [root@dns1 bob]# rrdtool graph 5.png  > -S 1200 / # -S 指定 resolution=1200 > --start now-120000 / > DEF:value1=eth0.rrd:eth0_in:AVERAGE:step=300 / # :step 指定 resolution=300 > AREA:value1#ff0000      481x154 [root@dns1 bob]# 

 

 

可以看到 5.png 和 1.png 是一样的,也就是说 –S 1200 并没有起作用,而是 :step=300 起作用了

实例5 :使用 :start 和 :end 只显示指定时间内的数据

 

 [root@dns1 bob]# rrdtool graph 1.png / > --start now-1h / # X 轴显示1个小时的长度 > DEF:value1=eth0.rrd:eth0_in:AVERAGE:start=now-600:end=now-300 / # 但只取10分钟前到5分钟前的这部分 > AREA:value1#00ff00:in   475x168 [root@dns1 bob]# 

 


 如果我们不加 :start 和 :end ,则效果如下 :
 
 

我们甚至可以让两个对象显示不同的时间,例如

实例6 :让两个对象显示不同时间段的数据

 

 [root@dns1 bob]# rrdtool graph 1.png / > --start now-2h / # 规定时间为2小时内 > DEF:value1=eth0.rrd:eth0_in:AVERAGE:end=now:start=end-1h / # 规定时间为1小时内 > DEF:value2=eth0.rrd:eth0_out:AVERAGE / # 没有指定 :start 和 :end,默认和 –-start 一样也是2小时 > AREA:value1#00ff00:in / > LINE2:value2#ff0000:out:STACK  475x168 [root@dns1 bob]# 

 

 

实例7 :把一段时间分为几段分别显示 :

 

 [root@dns1 bob]# rrdtool graph 1.png / > DEF:value1=eth0.rrd:eth0_in:AVERAGE:end=now:start=end-1h / # 当前1小时内 > DEF:value2=eth0.rrd:eth0_in:AVERAGE:end=now-1h:start=now-2h / # 2小时前 > DEF:value3=eth0.rrd:eth0_in:AVERAGE:end=now-2h:start=now-3h / # 3小时前 > LINE1:value1#00ff00:"1 hours ago" / > LINE2:value2#ff0000:"2 hours ago" / > LINE3:value3#000000:"3 hours ago"   475x168 [root@dns1 bob] 

 

 

我们把3个小时内的数据用三种不同粗细、不同颜色的曲线画了出来。

看到了吗,out部分(红色)显示了2个小时内的流量,而in部分(绿色)则只显示了1个小时内的部分

在这里要提一点,虽然我们指定了 –-start 或者 –-end ,或者 :start , :end,但并不意味着曲线就一定会从指定的时间点开始和结束。

例如我们上面指定了 :start=now-600:end=now-300 ,也就是只显示5分钟的数据。但图表出来的效果却是10(10:05-10:15)分钟

的数据,这是因为我们挑选的时间当中“不慎”横垮了两个周期(10:05-10:10,10:10-10:15),所以 RRDtool 会把它们全部画出来,而

不是只画其中的5分钟。

[ 本帖最后由 ailms 于 2006-12-4 09:44 编辑 ]


--------------------------------------------------------------------------------
 ailms 回复于:2006-12-04 09:27:24

使用RRDtool 进行绘图_(二)
 [color=blue]
**********************************************************************************************************************
 注 :该教程参考了如下内容 :
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
**********************************************************************************************************************
[/color]

[size=4]五)说明文字(Label)[/size]

 

 [-t|--title string] [-v|--vertical-label string] 


-t 是用于图表上方的标题,-v 是用于 Y 轴的说明文字

实例1 :给图表增加标题

 

 [root@dns1 bob]# rrdtool graph 1.png / > --start now-183600 / # 从当前开始往前51个小时 > -t "51 hours ago" -v "Traffic" / # 标题是 “51 hours ago”,Y 轴的说明文字是 “Traffic” > DEF:value1=eth0.rrd:eth0_in:AVERAGE / > DEF:value2=eth0.rrd:eth0_out:AVERAGE / > LINE1:value1#0000ff:in / # 注释 :以1个像素宽的曲线画出 value1,颜色是蓝色,图例的说明文字是“in” > LINE2:value2#ff0000:out # 注释 :以2个像素宽的曲线画出 value2,颜色是红色,图例的说明文字是 “out” 497x179 [root@dns1 bob]# 

 


现在我们用的是 LINE 的方式来绘图。LINE 可以有3种,分别是 LINE1|2|3,也就是线条的粗细。还有一种是 STACK 方式下面再介绍。

可以看到流入的流量比流出的流量稍大,这样看的话,out 流量比较难看,是否可以有别的方式呢?RRDtool 还提供了

另外一种格式,就是 STACK 。意思就是在前一个对象的基础(把前一个对象的值当成 X 轴)上绘图,而不是从 X 轴开始。

实例2 :使用 STACK 方式绘图

 

 [root@dns1 bob]# rrdtool graph 3.png / > --start now-120000 / > -t "33 hours ago" / > -v "Traffic" / > DEF:value1=eth0.rrd:eth0_in:AVERAGE / > DEF:value2=eth0.rrd:eth0_out:AVERAGE / > AREA:value1#00ff00:in / > LINE:value2#ff0000:out:STACK # 注意最后的 “STACK” ,表示在 value1 的基础上绘图 497x179 [root@dns1 bob]# 

 

 

这是没有采用 STACK 方式绘图的效果 :

 

可以看得出上面采用 STACK 方式的比较清晰,但要注意,采用 STACK 方式后,在读取 out 流量时,Y 轴的刻度不再是 out 的值,

应该用刻度值减去 in 的值,才是 out 真正的值。这点比较麻烦。需要配合 GPRINT 语句才能达到一定的效果。

[size=4]六)图表大小(Size)[/size]

 

 [-w|--width pixels] [-h|--height pixels] 


这里说图表大小而不是图片大小,是因为 –w ,-h 控制的是 X/Y 轴共同围起来的那部分大小,而不是整个图片的大小,这点在前面就可以看出了。

默认的图表大小是 400 (长)x 100 (高),但一般会返回497x179 这样的数字,这个才是图片的大小。

RRDtool 比 MRTG 好的一个地方就是 MRTG 一放大图片,就会变得模糊。RRDtool 则不会。

在官方文档中,-w 似乎是一个比较敏感的参数,我们看下面的描述 :

引用:
First it makes sure that the RRA covers as much of the graphing time frame as possible. Second it looks at the resolution of the

 RRA compared to the resolution of the graph. It tries to find one which has the same or higher better resolution. With the ``-r''
 
 option you can force RRDtool to assume a different resolution than the one calculated from the pixel width of the graph.

 

引用:
By default, rrdtool graph calculates the width of one pixel in the time domain and tries to get data from an RRA with that resolution.

With the step option you can alter this behaviour. If you want rrdtool graph to get data at a one-hour resolution from the RRD, set

step to 3'600. Note: a step smaller than one pixel will silently be ignored

 

这两段话分别是从rrd-beginners  和 rrd_graph 文档中摘出来的。似乎看起来 –w 会影响到图表的 resolution ,进一步影响到 RRDtool 如何选择 RRA ,

但经过实验却发现并非如此。

[color=red]我对这两段话中的图表的 resolution 一词不知如何理解和计算,希望好心的朋友能够指点一下 ^_^ .[/color]


实例1 :使用 –w 设定图表大小为 300 像素

 

 [root@dns1 bob]# rrdtool graph 3.png  > -w 300 / # 设定 size 为 300 pixel > --start now-120000 / > DEF:value1=eth0.rrd:eth0_in:AVERAGE / > AREA:value1#ff0000            381x154 [root@dns1 bob]# 

 


可以看到图表是不是变小了呢?而且整个图片的大小也变小了。

如果用前面的话来推理,由于 120000/300(-w的值)= 400 > 300 (step),由于没有 resolution=400 的 RRA,

所以应该采用 resolution=7200 的第2个 RRA 的数据来绘图,但实际上不是。

 

上面这个才是 300 pixel 宽,resolution=7200 的效果

所以我觉得 –w 和 –h 并不能影响 RRDtool 如何选择 RRA ,只能起到缩小放大的作用。

BTW:当你绘制的时间范围较大时,可以使用 –w 增大图表大小,这样看起来比较“舒服“

 


[size=4]七) Y 轴上下限(Limits)[/size]

 

  [-u|--upper-limit value] [-l|--lower-limit value] [-r|--rigid]  

 
 默认情况下,RRDtool 会和 MRTG 一样自动调整 Y 轴的数字,来配合当前的数值大小。如果想禁止该特性,可以通过 –upper-limit 和
 
-–lower-limit 来做限制,表示Y轴显示的值从多少到多少。如果没有指定 –rigid ,则在图表的上下边界处还是会有一些延伸,但如果指定了
 
-–rigid ,则严格按照 –-upper-limit 和 –-lower-limit 绘制。

在使用 –lower-limit 时要注意,如果数据中有负数,如果 -–lower-limit 为 0,则负数部分是显示不出来的。

实例1 :使用 –-upper-limit 和 –-lower-limit 限制 Y 轴的上下限

 

 [root@dns1 bob]# rrdtool graph 1.png / > --start now-120000 / > -v "Traffic" -t "33 Hours ago" / > --lower-limit -5000 / # 限制Y轴下限为 -5000  > --upper-limit 10000 / # 上限为 10000 > --rigid /   # 严格按照上面的规定来画 > DEF:value1=eth0.rrd:eth0_in:AVERAGE / > DEF:value2=eth0.rrd:eth0_out:AVERAGE / > AREA:value1#00ff00:in / > LINE1:value2#ff0000:out:STACK 497x179 [root@dns1 bob]# 

 

 

[size=4]八) X/Y 轴刻度(Grid)[/size]

 

 [-x|--x-grid GTM:GST:MTM:MST:LTM:LST:LPR:LFM]  [-x|--x-grid none] [-y|--y-grid grid step:label factor]  [-y|--y-grid none] [-Y|--alt-y-grid] [-X|--units-exponent value] 


RRDtool 中设置 X 轴的刻度比较复杂,如果没有必要,可以交给 RRDtool 自动去处理。

例如上面的图,33 小时的情况下,X 轴只有2个值,显得很不足。这时候有两种方法 :

A)一是使用 –w 增大图表的宽度,这样 RRDtool 会自动加多一些刻度上去。

 

不过需要增加多大才会有上面的这种效果不得而知,所以这种方法不是很方便。

B)二是通过上面的选项自己设置 X/Y 轴的刻度如何显示。首先看上图,在垂直的线中,红色的线称为 Major Grid(主要网格线),

    灰色的线称为 Base Grid (次要网格线)(这里是借用 EXCEL 中的概念 ^_^ )。 X 轴下面的时间文字成为 Label 。了解这
   
    三样东西后,就可以动手调整刻度了。
   
C)有两种方法可以快速去掉 X/Y 轴的刻度,就是 –-x-grid none 和 –-y-grid none

D)GTM:GST :控制次要格网线的位置。GTM 是一个时间单位,可以是 SECOND、MINUTE、HOUR、DAY 、WEEK、MONTH、YEAR 。

     GST 则是一个数字,控制每隔多长时间放置一根次要格线。例如我们要画一个1天的图表,决定每15分钟一根次要网格线,则格式为 MINUTE:15
    
E)MTM:MST :控制主要网格线的位置。MTM 同样是时间单位,MST 是一个数字。接上面的例子,决定一个小时1根主要网格线。则格式为 HOUR:1

     LTM:LST :控制每隔多长时间输出一个label 。决定为1小时1个 label 。则格式为 HOUR:1

G)LPR:LFM :LTM:LST 只是决定了 label 的显示位置了,没有指定要显示什么内容。LPR 指的是如何放置 label 。如果LPR 为0,则数字对齐格线

    (适用于显示时间)。如果不为0,则会做一些偏移(适用于显示星期几、月份等)。至于LFM 则需要熟悉一下 date 命令的参数,常用的有 %a(星期几)、
   
    %b(月份)、%d(天)、%H(小时)、%M(分)、%Y(年)。我们决定显示小时和分,所以用 %H%M

H)综合起来,X 轴的刻度定义就是 –-x-grid MINUTE:15:HOUR:1:HOUR:1:0:’%H:%M’。最好把 %H:%M 括起来

     建议 MST是 GST 的2-6倍,MST 和 LST 相同。这样画出来的图比较美观一些


   

这明显就是图片太小了,不够显示。把上面的 :%M 去掉就可以了,只显示小时,不显示分钟

   

如果把图片放大一点就更好了 (-w 800)

   

所以在设置 X 轴的刻度时,要记得不要显示太多东西,否则需要增大图片的大小

   

I)Y 轴刻度的设置又不一样了

   grid step :用于控制Y轴每隔多少显示一根水平线

   label factor :默认为1,也就是在每根水平线的高度那里显示一个值。

   例如下面就是一个例子 (每隔800显示一根水平线)

   

J)Y 轴还有一个很方便的选项就是 –Y ,它可以最大限度的优化 Y 轴的刻度,建议每次绘图都加上去。

K)Y 轴另外一个有用的选项就是 –X (虽然选项名是 -X ,但确实是用来设置 Y 轴刻度值的)。在上面的图我们看到 RRDtool 自动对 Y 轴的值进行调整,

     以 k 为单位显示。但如果你不想以 k 显示,而是想固定以某个单位来显示(M,b)该怎么办呢?这就要用到 –X 选项了。-X 后面跟一个参数,参数值
    
     范围是 -18、-15、-12、-9、-6 、-3、0、3、6、9、12、15、18 。0 表示以原值显示,3 表示数值除以1000,也就是以 k 为单位显示,6 就是以
    
     M 显示,9 就是以 G 显示。如果你给出1或者2,则 RRDtool 也可以接受,但会被“静悄悄”的改为0。下面就是一个以原值(-X 0)显示的例子

 

[ 本帖最后由 ailms 于 2006-12-4 09:44 编辑 ]


--------------------------------------------------------------------------------
 ailms 回复于:2006-12-04 09:28:00

使用RRDtool 进行绘图_(三)
[color=blue]
**********************************************************************************************************************
注 :该教程参考了如下内容 :
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
**********************************************************************************************************************
[/color]


[size=4]九、 其他(Miscellaneous)[/size]

 

 [-n|--font FONTTAG:size:[font]] [-g|--no-legend] [-b|--base value] 


A)-n | --font 是一个有意思的选项。CU 的 abel 兄曾提供了一个中文 patch 可以实现显示中文的效果。但对于我这等对 C 一窍不通的家伙,就不知道怎么用了。

    不过幸好 –n 选项可以实现这个目的,只需要中文字体的文件就可以搞定了。

     [color=blue]首先你要找出一个中文的字体文件[/color]。例如/usr/share/fonts/zh_CN/TrueType/gkai00mp.ttf 。你也可以把 Windows 上的 C:/Windows/Fonts 下面的中
    
     文字体拷贝到 Linux 上,例如home/bob/Fonts/simhei.ttf (黑体)效果不错,其他的则不太行,会出现模糊或者重叠的情况。建议就使用黑体算了。

     [color=blue]其次是确定字体大小。[/color]中文字体不宜小于 7 ,否则看不清楚

     [color=blue]确定你要修改的是图表的那个部分[/color]。有 DEFAULT(全部),TITLE (标题)、AXIS(坐标轴字体)、UNIT(Y轴单位字体)、LEGEND(图例字体)几种。

下面就以实际的例子来说明如何显示中文 :

实例1 :使用 –n 让 RRDtool 显示中文

 

 [root@dns1 bob]# rrdtool graph 4.png / > -n TITLE:10:'/home/bob/Fonts/simhei.ttf' / # 修改标题的字体为黑体 > -n AXIS:10:'/home/bob/Fonts/simhei.ttf' / # 修改 X 轴的字体为黑体 > --start now-240000 / # 大于3天的数据 > DEF:value1=eth0.rrd:eth0_in:AVERAGE / > AREA:value1#00ff00:in -t "33小时前的 eth0 接口流量" -v "traffic" > -Y –w 600 # 图表宽度为 600 pixel 503x190 [root@dns1 bob]# 


这就是最终的效果了,可以看到标题和 X 轴都是中文的,但 Y 轴的字体还是默认的字体。

 

B)-g |--no-legend 用于取消图表下方的图例,不过不建议这么做。

C)-b|--base value 在 MRTG 和 RRDtool 中,默认 1k=1000 ,使用 –b 可以进行调整,例如 –b 1024

[size=4]十)数字报表[/size]

看看上面的图表,是不是觉得还少了些什么呢?对了,就是只有图,没有文字说明。如何象 MRTG 那样能够显示“最大值”、“平均值”、“当前值”呢?

这就需要用到 GRPINT 和 COMMENT 语句了。
GPRINT 就是在图表的下方(仍然属于图片的内部)输出最大值、最小值、平均值这些东东;COMMENT 就是用来输出一些字符串,例如报表的表头。

A)GPRINT的格式是GPRINT:vname:CF:format 。由于 format 部分太多参数了,我这里就用最常用的那个 : %x.ylf 。

B)COMMENT 的格式是COMMENT:text 。要注意 COMMENT 默认是不输出换行的,如果要输出换行,必须用 “/n” 。

下面就以一个实例来说明如何打印报表 : 绘制1小时前的流量图,并打印数字报表(参照 abel 兄给出的例子)

 

 [root@dns1 bob]# rrdtool graph 1.png / > --start now-1h -w 600 -n DEFAULT:8 / > DEF:value1=eth0.rrd:eth0_in:AVERAGE / > DEF:value2=eth0.rrd:eth0_out:AVERAGE / > COMMENT:" /n" / > COMMENT:"         当前值--------------平均值--------------最大值--------------最小值--------------/n"     > COMMENT:" /n"  > AREA:value1#00FF00:"流入" / > GPRINT:value1:LAST:'.2lf'  / > GPRINT:value1:AVERAGE:.2lf  / > GPRINT:value1:MAX:.2lf  / > GPRINT:value1:MIN:.2lf  / > COMMENT:" /n" / > LINE2:value2#ff0000:"流出":STACK / # 注意这里是 STACK 方式 > GPRINT:value2:LAST:.2lf  / > GPRINT:value2:AVERAGE:.2lf  / > GPRINT:value2:MAX:.2lf  / > GPRINT:value2:MIN:.2lf  / > COMMENT:" /n" / > COMMENT:” /n” / > COMMENT:"LAST UPDATED /:$(date '+%Y-%m-%d %H/:%M')/n" -Y 687x270 [root@dns1 bob]# 

 


[color=red]注意比较 Y 轴刻度值和“流出”部分的值的关系, Y 轴刻度值 —“流入” =“流出”[/color]

由于时间精力有限,关于对齐方面的工作就大家自己试验吧.如果绘制的对象数量不是很多,可以用横向报表,不要用这种垂直的格式,

[color=red]这种格式的好处是便于比较各个对象的值。不过我可以肯定,如何让这些数字和上面的表头对齐是一个会令你极度抓狂的工作的!!![/color]

上面的  COMMENT 一是输出表头,二是输出空行。注意,要用 COMMENT 输出空行,必须用 COMMENT:’ /n’ 。

注意到 ‘/’ 前面的空格吗?这个是不可以漏的,否则就不会有空行的效果了。

[size=4]十一)特殊功能[/size]

 

 VRULE:time#color[:legend] HRULE:value#color[:legend] SHIFT:vname:offset 


A)VRULE/HRULE 可以用于在图表上面绘制垂直线/水平线。例如我们想要在图表上面标出最大值,可以用 HRULE 在 Y 轴的指定刻度值

    那里绘制一根水平线,例如 HRUE:100000#ff0000:”最大值” 在 100k 处画一根水平线,并指出这是最大值。

 

SHIFT 可以用来移动数据,例如 abel 兄曾经在 “[教學]中的教學(二) RRDTOOL 1.2 更新項目”中提到过一个问题,

就是“xx同期相比”如何画?下面就以如何比较3天的数据。

实例1 :绘制连续3天的数据

 

 [root@dns1 bob]# rrdtool graph 1.png / > DEF:value1=eth0.rrd:eth0_in:AVERAGE:end=now:start=now-1d / # 1天前 > DEF:value2=eth0.rrd:eth0_in:AVERAGE:end=now-1d:start=now-2d / # 2天前 > DEF:value3=eth0.rrd:eth0_in:AVERAGE:end=now-2d:start=now-3d / # 3天前 > LINE1:value1#00ff00:"1 day ago" / > LINE1:value2#ff0000:"2 days ago" / > LINE1:value3#000000:"3 days aog" / > -Y 475x168 You have new mail in /var/spool/mail/root [root@dns1 bob]# 

 

 

为什么只有1天前的数据呢?因为我们没有指定 –-start ,RRDtool 默认只绘制1天前的数据。由于这里覆盖了3天,

所以我们可以把 –-start 定义为 –-start now-3d 就可以了。

 

现在是不是3天的数据都画出来了呢?不过由于它们是横向排列的,所以要比较同个时间段的并不容易,能否把它们

按“垂直”的方式排列呢?这就要用到 SHIFT 了!

 

 [root@dns1 bob]# rrdtool graph 3.png / > DEF:value1=eth0.rrd:eth0_in:AVERAGE:end=now:start=now-1d / # 1天前 > DEF:value2=eth0.rrd:eth0_in:AVERAGE:end=now-1d:start=now-2d / # 2天前 > DEF:value3=eth0.rrd:eth0_in:AVERAGE:end=now-2d:start=now-3d / # 3天前 > LINE1:value1#00ff00:"1 day ago"  / > SHIFT:value2:86400 LINE1:value2#ff0000:"2 days ago" / # 把曲线向右移动1天 > SHIFT:value3:172800 LINE1:value3#000000:"3 days ago" / # 把曲线向右移动2天 > -Y –w 600 475x168 

 


[root@dns1 bob]#

 


和上面的图表比较,是否可以发现 X 轴不同了,不再是3天,而是1天多1点了。而且3根曲线重叠在一起了,可以看出在这三天中,

只有1天前的23点左右有一点流量之外,其余绝大部分都没有流量。

这就是 SHIFT 的功能了,可以把曲线/方块沿着 X 轴移动(左右都可以),我们达到比较同期数据的目的。是不是很好用呢?

[size=4]十二)总结[/size]

这次的内容可真够多的,足足写了19页。不过工具性的东西就是这样 :别看内容 N多,你只要动手画出1个图之后,就会觉得一

切都很简单了。以后只要套用就可以了。关键是如何更好的把你想要的数据以合适的发给你是呈现出来。

上面这些内容都是我通过实验得出的,由于具体的环境不同,可能会跟大家的不同,或者出现错误。我希望大家不要客气,有错误

的地方就指正,有什么好的发现也提出来,一起完善 RRDtool 的文档。这样就可以让越来越多的人了解、掌握 RRDtool 了 。  

 (^_^)!

[ 本帖最后由 ailms 于 2006-12-4 09:45 编辑 ]


--------------------------------------------------------------------------------
 ailms 回复于:2006-12-04 09:45:55

RRDtool简体中文教程_9:如何使用RPN
如何使用RPN
 [color=blue]
**********************************************************************************************************************
注 :该教程参考了如下内容 :
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
**********************************************************************************************************************
[/color]

[size=4]一)前言[/size]

RPN 代表逆波兰式(Reverse Polish Notation)。逆波兰式最早于1920年由Jan Lukasiewicz 发明,最神奇的地方是用它来表示数学表达式,

完全不需要括号。而且 RPN 不像普通的数学表达式那样,操作符在操作数的中间,而是在操作数的右边。例如 3+2 用 RPN 表示就是 3,2,+ ;

3+(2X5) 用 RPN 表示就是 3,2,5,x,+ 最后运算的部分(加法部分)的操作符放在最后,乘号放在前面,表示先执行 2 x 5 ,在把结果和3相加。

在 RRDtool 中,RPN 还可以用来表示 if-then-else 关系。这点在绘图中很有用。例如你要看 eth0 接口在一天当中流量 ≥ 10Mb/s 的部分,“隐藏”

其他低于 10Mb/s 的部分,则可以用到这个功能。

[size=4]二)操作符[/size]

什么是 RPN

A)RPN 是 Reverse Polish Notation 的缩写,是用于表示算术运算和逻辑运算的一种语法格式。

B)RRDtool 的 CDEF 语句中就经常使用 RPN 来对 DEF 取出来的数据进行运算。

C)RPN 的特点是操作数和操作符出现的顺序和运算的顺序一致,这样就不需要使用括号了

D)RPN 的格式是 <value1>,<value2>,<operator> ,[<value1>,<value2>,<operator>]… 可以看出是操作数在前,操作符在后的格式

E)RPN 需要提到堆栈的概念(stack)。堆栈是用来存储操作数和操作符的。

F)当堆栈中压入(push)一个操作符时,就从堆栈中取出(pop)所需要的操作数进行计算(根据操作的不同pop出不同数量的操作数)。
 
     结果再返回(push)堆栈,最终整个 RPN 应该只返回一个值,或者说堆栈中只有一个元素

G)在 CDEF 中书写 RPN 操作符,要一律以大写的格式出现

H) RPN 中,如果某个部分的运算结果非 0,则被认为是 true ,只有 0 才被认为是 false

[size=4]三)RPN 操作符的分类[/size]

A)布尔操作符 :GT、GE、LT、LE、EQ、NE、

B)特殊值比较符 :UN、ISINF、

C)条件操作符 :IF

D)比较操作符 :MIN、MAX、LIMIT

E)算术操作符 :+ 、-、*、/、%、SIN, COS, LOG, EXP, SQRT、FLOOR, CEIL、ATAN、ATAN2、DEG2RAD, RAD2DEG

F)数据集操作符 :所谓数据集(sets),就是指多个数据。SORT、REV、AVG、TREND

G)特殊值 :UNKN、INF、NEINF、PREV、COUNT

H)时间操作符 :NOW、TIME、LTIME

I)堆栈操作符 :POP、DUP、EXC

四)RPN 操作的结果

A)布尔操作符 :从堆栈中 pop 出两个元素,并根据比较结果返回 0 (false) 或者 1 。任何同 UNKNOWN 或者 INF 、NEINF 比较的都为 0

B)特殊值比较符 :从堆栈中 pop 出1个元素,并同 UNKNOWN 或者 INF、NEINF 比较。结果为 0 或者 1

C)条件操作符 :从堆栈中pop出3个元素,如果最后pop出的那个元素不为0(条件部分为 true),则第2次 pop 出的那个元素被重新入栈(then部分);

     否则第一次pop出的元素重新入栈(else部分)。结果为 then 部分或者 else 部分返回的值,不一定为0或者1

D)比较操作符 :

     对于 MIN/MAX 操作符来说,从堆栈中 pop 出两个操作符,并把较大/小的那个重新入栈。如果其中有一个 unknown ,则结果为 unknonw

     对于 LIMIT 操作符来说,先从堆栈中 pop 出2个操作数,作为边界的定义;再 pop 出1个操作数,比较该操作数是否落在前面定义的范围内。
    
     如果是则把最后 pop 出的那个元素重新入栈;否则把 UNKN 值入栈;注意,是 UNKN ,不是 0

E)算术操作符 :根据操作符 pop 出所需数量的操作数,并把算术运算的结果重新入栈

F)数据集操作符 :

    对于 SORT、REV 来说,先从堆栈中 POP 出一个元素,该元素的值就是下面要 pop 出的元素的数量。然后对堆栈从上到下的若干个元素
   
   由第一次 pop 的出的那个元素的值决定)进行排序/反向排序。结果再重新入栈。

   注意 :由于堆栈的特点是后进先出,所以要操作的元素是从SORT操作符往左方向计数。例如v1,v2,v3,v4,3,SORT是对 v2~v4 排序,
  
            不是对 v1~v3 排序。  这点在书写 RPN 时要特别注意。

   注意 :SORT 操作是最小值在堆栈的最顶部;REV 则相反,最小值是在堆栈的最顶部。

   对于 AVG 操作来说,同样是先 pop 出1个元素,并按照指定的数量对后续的若干个操作数进行操作,但结果只有一个数值,并入栈。


G)特殊值 :

    UNKN 表示压入一个 UNKN 值;INF、NEINF 分别表示把 INF、NEINF 值压入堆栈

H)时间操作符 :

   TIME 返回当前所提取的记录的 timestamp ,注意 TIME 直接返回当前记录的 timestamp ,不用任何参数

   NOW 返回当前时间,同样 NOW 不用任何参数

I)堆栈操作符 :

   POP :弹出堆栈的最顶部的那个元素

  EXC :交换堆栈顶部的第一个和第二个元素的值

[size=4]五)如何阅读 RPN[/size]

A)首先按照从左到右的顺序,找出第一个 RPN 操作符,并根据上一节的内容,对相应的操作数进行操作

B)操作结果分成两种 :

如果是一个值,直接替换掉该部分 RPN

如果是多个值(数据集操作,但 AVG 操作只返回一个值),则结果可能为多个数值。则把这若干个数值用 ‘,’ 隔开,替换原来那部分 RPN

C)如此循环,一直到整个 RPN 只返回一个值为止

[size=4]六、RPN 实例[/size]

A)布尔型操作符 :2,1,GE 表示 2>=1 ;

B)特殊值比较符 :mydata,UN 表示 mydata == UNKNOWN

C)条件操作符 :mydata,UN,0,mydata,IF 表示如果 mydata 等于 UNKNOWN ,则返回 0;否则还是返回 mydata 本身

D)比较操作符 :mydata,20,MAX 表示返回 mydata,20 这两个数值中较大的一个;alpha,0,100,LIMIT 表示测试 alpha 的值是否小于等于0,大于等于100;

E)算术操作符 :1,2,- 表示 1-2=-1

F)数据集操作符 :

    v1,v2,v3,v4,v5,4,SORT 表示对 v1~v4 进行正向排序,结果堆栈中还是有5个元素;

    v1,v2,v3,v4,3,AVG,+,2,/ 表示对 v4,v3,v2 进行求平均值,并把结果入栈。假设v2~v4的结果为 k ,则为 v1,k,+,2,/ 也就是返回 (v1+k)/2

G)特殊值 :mydata,0,GT,UNKN,mydata,IF 表示如果 mydata 大于 0则返回 UNKNOWN ,否则还是 mydata

H)时间操作符 : TIME,`date –d “2006-10-01 10:00” +%s`,GT,0,1,IF 表示如果当前记录的采集时间是在 2006-10-01 10:00 之后就返回1,否则返回 0

I)堆栈操作符 :POP 就立即弹出第一个元素
 

[size=4]七)如何表示 AND、OR 关系[/size]

A)我们知道 RPN 表达式的值除非0,否则都认为是 true

B)我们可以利用 加法操作和乘法操作来实现 OR 和 AND 的逻辑关系;如果两个 RPN 表达式的值相加不等于0,就一定为 true ;

     如果两个 RPN 表达式的值相乘不等于0,就一定为 true

C)AND 关系的例子 :例如要比较某个值(15,9)是否在特定范围内可以用 :

    15,10,GT,15,20,LT,* ,结果就是(15>10)*(15 < 20)= 1 * 1 =1 ,所以为 true

     9,10,GT,9,20,LT,* ,结果就是 (9 >10)* ( 9 < 20)= 0 * 1 =0 ,所以为 false

D)OR 关系的例子:同上例如要比较某个值(7,15)小于10,或者大于20:

     7,10,LT,7,20,GT,+ ,结果为 (7 < 10)+ (7 > 20) = 1+0 = 1,所以为 true

     15,10,LT,15,20,GT,+ ,结果为 ( 15 < 10) + ( 15 > 20) = 0 + 0 =0 ,所以为 false

E)不过使用 + 需要注意一个地方 :相加的双方都必须是正数,否则可能出现问题,例如一个正数(-5,true)和另外一个正数(5,true)相加为 0(false)

如果是按照 OR 的关系,应该是 true 的,但结果变成0(false),所以在使用 + 来表示 OR 的关系时,要注意该问题

F)使用 * 则没有该问题了,正数 * 负数 = 负数 (true)。所以如果遇到 OR 关系的时候,可以转换为 AND 关系来计算。

     例如要表达 (x < a) OR ( x > b) 的关系,可以改为 (x >a) AND ( x < b ) ,诀窍就是把比较操作符调反方向,把 + 改为 *

[size=4]八)实例[/size]

实例1:例如要看 eth0的总流量,可以用如下的定义

 

 DEF:value1=eth0.rrd:eth0_in:AVERAGE / DEF:value2=eth0.rrd:eth0_out:AVERAGE / CDEF:value3=value1,value2,+ / AREA:value3#ff0000:”total” 


实例2 :假设我们要把 eth0 和 lo 的流入流量相加,得出总的流入流量

 

 DEF:value1=eth0.rrd:eth0_in:AVERAGE / DEF:value2=lo.rrd:lo_out:AVERAGE / CDEF:value3=value2,UN,0,value2,IF / CDEF:value4=value1,value3,+ / AREA:value4#00ff00:”total in” 

由于 lo.rrd 一直没有数据插入,所以一直都是 NaN ,如果直接把 value1 和 value2 相加,由于 value2 是 UNKNOWN,

所以相加的结果也是 UNKNOWN 。图表上将什么都不显示,所以需要对 value2 进行判断,如果 value2 的值 UNKNOWN (value2,UN),

则返回0,否则返回 value2 本身。然后把这个值赋予变量 value3 ,最后把 value1 和 value3 相加,才得出真正入流量
 
实例3 :只看 eth0 中流量大于 10Mb/s 的部分,其余不看

 

 DEF:value1=eth0.rrd:eth0_in:AVERAGE / DEF:value2=eth0.rrd:eth0-_out:AVERAGE / CDEF:value3=value1,1000000,GT,value1,UNKN,IF / CDEF:value4=value2,1000000,GT,value2,UNKN,IF / AREA:value3#00ff00:”traffic_in /> 10M//s” / AREA:value4#ff0000:”traffic_out /> 10Mb//s”:STACK 

 

实例4 :只绘制特定时间段(在 2006/11/29 10:30 ~ 2006/11/29 12:30)的数据

 

 DEF:value1=eth0.rrd:eth0_in:AVERAGE / DEF:value2=eth0.rrd:eth0_out:AVERAGE / CDEF:value3=TIME,$(date –d ‘2006-11-29 10:30’ +%s),GT,TIME,$(date –d '2006-11-29 12:30' +%s),LT,*,value1,UNKN,IF / CDEF:value4=TIME,$(date –d ‘2006-11-29 12:30’ +%s),GT,TIME,$(date –d '2006-11-29 13:30' +%s),LT,*,value2,UNKN,IF / AREA:value3#00ff00:”traffic_in” / AREA:value4#ff0000:”traffic_out”:STACK 

 

[size=4]九、完结[/size]

 相信到目前为止,大家对 RRDtool 的认识应该更深了吧。一定要多做实验,这样才能做到熟能生巧,灵活应用。
 
 其实剩下的还有 xport、dump、restore、resize、tune、rrdcgi 几个操作没讲,而且有一些应用经验方面的东西也没有提到,
 
 不过想要全部写出来,可能太耗时间和精力了,这些东西足足写了我2个星期才写完。中间还要不断的做实验以验证正确性,怕误导了大家。
 
 如果需要的话,可以自己下载官方文档学习,或者能有热心的朋友补充就更好了,^_^ 。
 
[size=4]十、 本人的一点学习体会[/size]

  本人从开始看 RRDtool 官方文档到开始写这篇教程,差不多用了2个月。 RRDtool 比学习 MRTG 难多了,资料少,RRDtool 的中文资料目前就只有 abel

兄写的那一篇教程,如果没有实际的上机操作,是不可能看懂的,所以 abel 兄也特别交代这点。如果只一心想速成,到头来反而吃亏的是自己。

   象sendmail、bind 这些服务器的配置,随便在 google 上都可以搜到一大把所谓的“快速入门”,很多人也都照着做了。但明明别人可以的,为什么轮到自己
  
却失败呢?相信这是很多人心中曾有的郁闷经历。其实归根到底就是基础的问题,再深入一些就是学习心态的问题。“不积跬步,无以至千里;不积小流,无以成江海”。

配置一个服务器并不是照抄配置就可以的。环境的不同,需求的不同这些因素都要考虑在内。怎么可能做到完全一样呢?同一个语句换个环境可能就不行了。所以我很

少看那些所谓的快速入门,要么看 manual ,要么看书(说到这里,感觉 O’Reilly 的书真是不错!^_^),如果是象 RRDtool这种的,就只好看官方文档了。
  
  学习的同时也要注意选择好的教材。有时候一本好书能带给无穷的好处。这点在我第一次看 O’Reilly 的 《dns & bind 4th》就有感觉,老外的书很注重循序渐进,
 
通常他们都是从某个实际工作环境的一个小例子说起,逐步引入各个命令、配置语句。然后随着需求的壮大,不断引入新的内容,最后形成一个总体。这样看完后会心中会

有一个整体的框架和概念。不象国内一些书,毫不顾及条理,一上来就讲语法、命令,搞得读者很快都没有兴趣。这样的书可谓害人不浅。

   同时也建议大家读英文原版的书。为什么呢?虽然中文的看起来快一些,但学习不是竞走比赛。不是比谁看的快,而是比谁学的牢。英文书的词汇其实都是专业词汇,

只要看多了,自然记住了。实在记不住,可以用金山词霸等工具辅助。俺的英文水平只有二级,但并不妨碍我看书。况且看英文书,有一个“英文→中文”的转换的过程。就

是揣摩作者这句话的含义,或者说这句话应该如何翻译好。有些人觉得这个没有什么,但我觉得这个过程是你弄清作者思想的重要步骤。在你不断的揣摩中,可能会有不同

的理解,直到你认为这是最正确的那一种解释为止。如果是看中文书,可能会由于惰性,比较容易就接受作者的想法,而失去这个主动我思考的过程。

  一时有感而发,胡乱写了一通,请各位朋友见谅了。

  书山有路勤为径,学海无涯苦做舟!

   愿以该座右铭和各位有志于Linux的朋友一起共勉!