可轻松解析 rrdtool 的输出

问题描述 投票:0回答:3

我正在处理大量 RRD 文件,我必须在其中查询大量数据 - 并且主要是通过读取所有数据并将其传递。

目前,我使用

rrdtool fetch <filename> CF --start XXX --end YYY
,但由于它一次只返回一个 CF 的数据,所以我首先必须执行单独的查询来查找 CF(= 运行并解析
rrdtool info <filename>
),然后运行
rrdtool fetch
每个都找到CF。不过,输出解析起来很简单。

或者,还有

rrdtool xport DEF:XX=<filename>:RRA:CF ... XPORT:XX:XX ...
,其中有多个“集”的后一个命令,用于我想要的每件事。从好的方面来说,这可以一次性为我提供所有数据,但我仍然需要事先对我想要的“什么”数据有一个相当好的了解。而且,它只输出 XML(解析起来总是很麻烦)。 我有一种感觉,我错过了一些非常明显的东西,因为从文件中获取时间戳→数字列表根本不可能有这么大的麻烦......有任何线索吗?

rrdtool rrd
3个回答
2
投票
有补丁

用于添加 JSON 支持,但目前没有办法解决:

解析至少两种不同的输出格式(
    rrdtool info
  • 的 ASCII,然后来自
    rrdtool xport
    的 XML 或来自
    rrdtool fetch
    的表格数据)。
    通过 
  • rrdtool dump
  • 将文件的全部内容转储为 XML,然后重新实现
    librrd
    的相当一部分内部结构。
    
        

1
投票
rrdtool info /tmp/pb_1_amp.rrd

的输出转换为嵌套数组。所以来自:


filename = "/tmp/pb_1_amp.rrd" rrd_version = "0003" step = 1800 last_update = 1372685403 header_size = 1208 ds[amp].index = 0 ds[amp].type = "GAUGE" ds[amp].minimal_heartbeat = 3200 ds[amp].min = 0.0000000000e+00 ds[amp].max = 1.0000000000e+02 ds[amp].last_ds = "5.6" ds[amp].value = 1.6800000000e+01 ds[amp].unknown_sec = 0 rra[0].cf = "AVERAGE" rra[0].rows = 576 rra[0].cur_row = 385 rra[0].pdp_per_row = 1 rra[0].xff = 5.0000000000e-01 rra[0].cdp_prep[0].value = NaN rra[0].cdp_prep[0].unknown_datapoints = 0 rra[1].cf = "AVERAGE" rra[1].rows = 672 rra[1].cur_row = 159 rra[1].pdp_per_row = 6 rra[1].xff = 5.0000000000e-01 rra[1].cdp_prep[0].value = 1.6999833333e+01 rra[1].cdp_prep[0].unknown_datapoints = 0 rra[2].cf = "AVERAGE" rra[2].rows = 732 rra[2].cur_row = 639 rra[2].pdp_per_row = 24 rra[2].xff = 5.0000000000e-01 rra[2].cdp_prep[0].value = 1.6999833333e+01 rra[2].cdp_prep[0].unknown_datapoints = 0 rra[3].cf = "AVERAGE" rra[3].rows = 1460 rra[3].cur_row = 593 rra[3].pdp_per_row = 144 rra[3].xff = 5.0000000000e-01 rra[3].cdp_prep[0].value = 6.6083527778e+02 rra[3].cdp_prep[0].unknown_datapoints = 0

至:

Array ( [filename] => /tmp/pb_1_amp.rrd [rrd_version] => 0003 [step] => 1800 [last_update] => 1372685403 [header_size] => 1208 [ds] => Array ( [amp] => Array ( [index] => 0 [type] => GAUGE [minimal_heartbeat] => 3200 [min] => 0.0000000000e+00 [max] => 1.0000000000e+02 [last_ds] => 5.6 [value] => 1.6800000000e+01 [unknown_sec] => 0 ) ) [rra] => Array ( [0] => Array ( [cf] => AVERAGE [rows] => 576 [cur_row] => 385 [pdp_per_row] => 1 [xff] => 5.0000000000e-01 [cdp_prep] => Array ( [0] => Array ( [value] => NaN [unknown_datapoints] => 0 ) ) ) [1] => Array ( [cf] => AVERAGE [rows] => 672 [cur_row] => 159 [pdp_per_row] => 6 [xff] => 5.0000000000e-01 [cdp_prep] => Array ( [0] => Array ( [value] => 1.6999833333e+01 [unknown_datapoints] => 0 ) ) ) [2] => Array ( [cf] => AVERAGE [rows] => 732 [cur_row] => 639 [pdp_per_row] => 24 [xff] => 5.0000000000e-01 [cdp_prep] => Array ( [0] => Array ( [value] => 1.6999833333e+01 [unknown_datapoints] => 0 ) ) ) [3] => Array ( [cf] => AVERAGE [rows] => 1460 [cur_row] => 593 [pdp_per_row] => 144 [xff] => 5.0000000000e-01 [cdp_prep] => Array ( [0] => Array ( [value] => 6.6083527778e+02 [unknown_datapoints] => 0 ) ) ) ) )

它是用 PHP 编写的,但应该很容易移植到任何其他语言。这是代码:

$store = array(); foreach ($lines as $line) { list($raw_key, $raw_val) = explode(' = ', $line); $keys = preg_split('/[\.\[\]]/', $raw_key, -1, PREG_SPLIT_NO_EMPTY); $key_count = count($keys); $pointer = &$store; foreach ($keys as $key_num => $key) { if (!array_key_exists($key, $pointer)) { $pointer[$key] = array(); } $pointer = &$pointer[$key]; if ($key_num+1 === $key_count) { $pointer = trim($raw_val, '"'); } } }

它假设 
rrdtool info

输出被换行符 (

\n
) 分割并在
$lines
中找到。希望这有帮助。
    


0
投票
rrdtool info

,如果您想要全部内容,请使用

rrdtool dump
    

© www.soinside.com 2019 - 2024. All rights reserved.