我正在使用rrdtool
来收集和处理一些系统指标。
我一直在试验相当奇妙的HWPREDICT
功能,让您可以对Holt-Winters进行像差检测的季节性预测。
但是我现在遇到了一个问题,因为当我开始时,我将HWPREDICT
参数设置为每天都有一个“季节”:
rrdtool create <filename> -s 300 DS:curr_sessions:GAUGE:600:0:U RRA:AVERAGE:0.5:1:2880 RRA:AVERAGE:0.5:12:2016 RRA:AVERAGE:0.5:60:2400 RRA:HWPREDICT:1440:0.1:0.0001:288
间隔5分钟的288个样本意味着一天的“季节”。
我想做的是扩展它,这样我的'季节'是2016年的样本 - 一周。
E.g。
RRA:HWPREDICT:4032:0.1:0.0001:2016
但是我很难搞清楚是否有办法在不重置源数据的情况下做到这一点。我查看了rrddump
,它允许您转储/恢复。这会导出XML但保留RRA结构。
rrdtune
可让您调整alpha / beta / gamma的某些参数,但不会调整季节长度。
rrdresize允许你修改RRA的长度,但不能修改季节的长度。
有没有人有一个很好的解决方案,让我重新创建我的rrd
但保留其中的数据? (我不介意'丢失'我的HWPREDICT RRA数据,因为无论如何改变季节周期几乎使它无效,但是我希望将现有数据保存在其他RRA中。
对于奖励积分 - 我最熟悉perl,所以如果有人能够给我一个指向正确方向的点,请不要介意使用perl / XML。 (我可以用某种方式“捏造”导出的XML,只是“用一堆未初始化的值来”提供一个新的RRA吗?)
答案 0 :(得分:0)
到目前为止的部分答案:
使用新参数创建新的rrd
文件。包含--start
以允许您回溯日期足够远。 (在转储的XML中查找最低'时间戳')。
处理转储的XML并提取数据。这里有一个问题 - 如果你有重叠的RRA,rrdtool将不接受'冲突'时间戳。例如,如果您有MAX
和AVERAGE
。
我选择挑选MAX
,因为这对我来说可能最有用。
我也按顺序完成了它,因为我已按照适当的顺序指定了我的初始RRA(例如,首先是最小分辨率)。这可能会起作用,但请记住,你可能会得到一些不同的值,看看更粗糙的分辨率'MAX'。
#!/usr/local/bin/perl
use strict;
use warnings;
use XML::Twig;
my %update_vals;
sub parse_rra {
my ( $twig, $rra ) = @_;
return unless $rra->first_child_text('cf') eq 'MAX';
my $step = $twig->root->first_child_text('step');
my $lastupd = $twig->root->first_child_text('lastupdate');
my $base_time = $lastupd - $lastupd % $step;
my $pdp_step = $rra->first_child_text('pdp_per_row');
my @row_vals;
foreach my $row ( $rra->first_child('database')->children('row') ) {
my $val = $row->first_child_text('v');
push( @row_vals, $val );
}
my $start_rra = $base_time - $#row_vals * $step * $pdp_step;
foreach my $value (@row_vals) {
if ( not $value eq "NaN"
or not defined $update_vals{$start_rra} )
{
$update_vals{$start_rra} = $value;
$start_rra += $step * $pdp_step;
}
}
}
my $target_file = "your_rrd_dump.xml";
my $destination_file = "new.rrd";
my $twig = XML::Twig->new( 'twig_handlers' => { 'rra' => \&parse_rra } )
->parsefile($target_file);
foreach my $timestamp ( sort keys %update_vals ) {
print
`rrdtool update $destination_file $timestamp:$update_vals{$timestamp}`;
}
现在,到目前为止 - 所有这一切都是'重播'您可用的所有时间戳。不幸的是 - 对于任何合并的数据点,它根本不起作用(基于RRA配置),因为您没有足够的样本(例如每天1个)。
作为第二种方法(已编辑):
使用XML::Twig
处理 - 首先保存'非HWPREDICT'数据并删除HWPREDICT
内容。第二个是你处理并将HWPREDICT
RRA拼接到前一个,以创建一个新的XML转储...你可以恢复它。
注意 - 如果您的数据差异很大,这可能就行不通了。 (注意 - 重新初始化的HWPREDICT
内容可能需要一段时间才能再次“安定下来”。
#!/usr/local/bin/perl
use strict;
use warnings;
use XML::Twig;
my @cf_to_replace =
qw ( HWPREDICT MHWPREDICT SEASONAL DEVSEASONAL DEVPREDICT FAILURES );
my %hwp_cf = map { $_ => 1 } @cf_to_replace;
my $xml_doc;
sub discard_hwp {
my ( $twig, $rra ) = @_;
my $CF = $rra->first_child_text('cf');
if ( $hwp_cf{$CF} ) { $rra->delete }
}
sub splice_hwp {
my ( $twig, $rra ) = @_;
my $CF = $rra->first_child_text('cf');
if ( $hwp_cf{$CF} ) {
$rra->cut;
$rra->paste( 'last_child', $xml_doc->root );
}
}
my $orig_file = 'your_xml_dump.xml';
my $newly_created_rrddump = 'new_params.xml';
$xml_doc = XML::Twig->new(
'pretty_print' => 'indented',
'twig_handlers' => { 'rra' => \&discard_hwp }
)->parsefile($orig_file);
my $new = XML::Twig->new( 'twig_handlers' => { 'rra' => \&splice_hwp } )
->parsefile($newly_created_rrddump);
open( my $output, ">", "new.xml" ) or die $!;
print {$output} $xml_doc->sprint;
close($output);
这样做基本上是通过两个单独的'rrdtool转储'并将RRA
拼接在一起。我会试一试,看看它是否确实能满足我的需要 - 直到Holt-Winters功能稳定下来我才会知道。