RRDs::graph中关于TICK框与标签重叠的不兼容性
很多年前我写了一个监控工具,用RRD来收集数据(其实使用的是perl模块 RRDs)。当时的操作系统是SLES 10(rrdtool 1.2012和 rrdtool 1.3007)。
自从升级到SLES 15 SP6(perl-rrdtool-1.8.0-150600.1.4.x86_64)后,我发现我的TICK区块会与标签重叠。
图表底部看起来是这样的:

TICK的作用只是对柱状图的一种“颜色图例”,用来对未显示的状态进行分类(绿色/黄色/橙色/红色)。
绘制底部那部分的相关代码看起来是这样的(来自 RRDs::graph($fname, @settings, @graph_args); 的 @graph_args 数组):
...
51 'COMMENT: Last\\t Minimum\\t Average\\t Maximum\\t Sample\\n'
52 'GPRINT:S_A:LAST: %6.2lf\\t\\g'
53 'GPRINT:V_S_I: %6.2lf\\t\\g'
54 'GPRINT:V_S_A: %6.2lf\\t\\g'
55 'GPRINT:V_S_X: %6.2lf\\t\\g'
56 'LINE:S_I'
57 'AREA:S_R#F061::STACK'
58 'LINE1:S_I#F066'
59 'LINE1:S_X#F066'
60 'LINE1:S_A#F06:System \\n'
61 'GPRINT:P_A:LAST: %6.2lf\\t\\g'
62 'GPRINT:V_P_I: %6.2lf\\t\\g'
63 'GPRINT:V_P_A: %6.2lf\\t\\g'
64 'GPRINT:V_P_X: %6.2lf\\t\\g'
65 'LINE:P_I'
66 'AREA:P_R#C601::STACK'
67 'LINE1:P_I#C606'
68 'LINE1:P_X#C606'
69 'LINE1:P_A#C60:Peer \\n'
70 'GPRINT:C_A:LAST: %6.2lf\\t\\g'
71 'GPRINT:V_C_I: %6.2lf\\t\\g'
72 'GPRINT:V_C_A: %6.2lf\\t\\g'
73 'GPRINT:V_C_X: %6.2lf\\t\\g'
74 'LINE:C_I'
75 'AREA:C_R#3F31::STACK'
76 'LINE1:C_I#3F36'
77 'LINE1:C_X#3F36'
78 'LINE1:C_A#3F3:Clock \\n'
79 'GPRINT:A_A:LAST: %6.2lf\\t\\g'
80 'GPRINT:V_A_I: %6.2lf\\t\\g'
81 'GPRINT:V_A_A: %6.2lf\\t\\g'
82 'GPRINT:V_A_X: %6.2lf\\t\\g'
83 'LINE:A_I'
84 'AREA:A_R#06F1::STACK'
85 'LINE1:A_I#06F6'
86 'LINE1:A_X#06F6'
87 'LINE1:A_A#06F:Total \\n'
88 'TICK:S0X#F00C:0.06'
89 'TICK:S1X#F90C:0.06'
90 'TICK:S2X#FF0C:0.06'
91 'TICK:S3X#0C09:0.06'
92 'TICK:S0A#F00C:0.04:Failed'
93 'TICK:S1A#F90C:0.04:Bad'
94 'TICK:S2A#FF0C:0.04:Marginal'
95 'TICK:S3A#0C09:0.04:Good'
96 'TICK:S0I#F00C:0.02'
97 'TICK:S1I#F90C:0.02'
98 'TICK:S2I#FF0C:0.02'
99 'TICK:S3I#0C09:0.02'
(该命令是以某种复杂的方式组装的,因此展示那段代码只会分散注意力。因此我使用Perl调试器来提取关键设置)
下面给出一个例子,展示旧版rrdtool的图形底部是怎样的(调用它的代码并未改变):

手册仍然声称 TICK 的语法是:
TICK:vname
#rrggbb[aa][:fraction[:legend]]
软件包版本
由于问题可能出在 rrdtool 之外,我将补充更多软件包版本信息:
> rpm -qa rrdtool librrd libpango\*
libpango-1_0-0-32bit-1.51.1-150600.1.3.x86_64
libpangomm-1_4-1-2.46.3-150600.1.2.x86_64
libpango-1_0-0-1.51.1-150600.1.3.x86_64
rrdtool-1.8.0-150600.1.4.x86_64
我发现Fedora 42中的 rrdtool-1.9.0-3.fc42.x86_64 也有同样的问题:
$ rpm -qa rrdtool rrd\* pango\* cairo\*
cairo-1.18.2-3.fc42.x86_64
cairo-gobject-1.18.2-3.fc42.x86_64
cairomm-1.14.5-8.fc42.x86_64
cairomm1.16-1.18.0-8.fc42.x86_64
pangomm-2.46.4-3.fc42.x86_64
pangomm2.48-2.56.1-1.fc42.x86_64
pango-1.56.4-2.fc42.x86_64
rrdtool-1.9.0-3.fc42.x86_64
简化测试用例
我设法创建了一个简化的测试用例:
首先是示例RRD数据库的转储:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE rrd SYSTEM "https://oss.oetiker.ch/rrdtool/rrdtool.dtd">
<!-- Round Robin Database Dump -->
<rrd>
<version>0003</version>
<step>60</step> <!-- Seconds -->
<lastupdate>1751958726</lastupdate> <!-- 2025-07-08 09:12:06 CEST -->
<ds>
<name> N_SYS </name>
<type> GAUGE </type>
<minimal_heartbeat>105</minimal_heartbeat>
<min>0.0000000000e+00</min>
<max>NaN</max>
<!-- PDP Status -->
<last_ds>1</last_ds>
<value>6.0000000000e+00</value>
<unknown_sec> 0 </unknown_sec>
</ds>
<ds>
<name> N_PEER </name>
<type> GAUGE </type>
<minimal_heartbeat>105</minimal_heartbeat>
<min>0.0000000000e+00</min>
<max>NaN</max>
<!-- PDP Status -->
<last_ds>0.7</last_ds>
<value>4.2000000000e+00</value>
<unknown_sec> 0 </unknown_sec>
</ds>
<ds>
<name> N_ALL </name>
<type> GAUGE </type>
<minimal_heartbeat>105</minimal_heartbeat>
<min>0.0000000000e+00</min>
<max>NaN</max>
<!-- PDP Status -->
<last_ds>0.769230769230769</last_ds>
<value>4.6153846154e+00</value>
<unknown_sec> 0 </unknown_sec>
</ds>
<!-- Round Robin Archives -->
<rra>
<cf>AVERAGE</cf>
<pdp_per_row>1</pdp_per_row> <!-- 60 seconds -->
<params>
<xff>9.0000000000e-01</xff>
</params>
<cdp_prep>
<ds>
<primary_value>1.0000000000e+00</primary_value>
<secondary_value>1.0000000000e+00</secondary_value>
<value>NaN</value>
<unknown_datapoints>0</unknown_datapoints>
</ds>
<ds>
<primary_value>7.0000000000e-01</primary_value>
<secondary_value>6.0000000000e-01</secondary_value>
<value>NaN</value>
<unknown_datapoints>0</unknown_datapoints>
</ds>
<ds>
<primary_value>7.6923076923e-01</primary_value>
<secondary_value>6.9230769231e-01</secondary_value>
<value>NaN</value>
<unknown_datapoints>0</unknown_datapoints>
</ds>
</cdp_prep>
<database>
<!-- 2025-07-08 09:12:00 CEST / 1751958720 --> <row><v>1.0000000000e+00</v><v>8.0000000000e-01</v><v>8.4615384615e-01</v></row>
</database>
</rra>
</rrd>
用来创建 demo.png 的命令:
$ rrdtool restore /tmp/demo.dump /tmp/demo.rrd
$ rrdtool graph /tmp/demo.png 'DEF:S_A=/tmp/demo.rrd:N_SYS:AVERAGE' 'CDEF:S1A=S_A,0.30,GT,S_A,UNKN,IF' 'TICK:S1A#F90C:0.04:Bad'
这会得到下图:

解决方案
SUSE的一个支持案例也不能真正解释发生了什么,但升级到SP7(rrdtool-1.8.0-150600.1.4.x86_64)后,TICK标记又看起来正常了。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。