rrdtool - 修改HWPREDICT rra

时间:2015-06-10 12:00:27

标签: xml perl rrdtool

我正在使用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吗?)

1 个答案:

答案 0 :(得分:0)

到目前为止的部分答案:

使用新参数创建新的rrd文件。包含--start以允许您回溯日期足够远。 (在转储的XML中查找最低'时间戳')。

处理转储的XML并提取数据。这里有一个问题 - 如果你有重叠的RRA,rrdtool将不接受'冲突'时间戳。例如,如果您有MAXAVERAGE

我选择挑选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个)。

作为第二种方法(已编辑):

  • 创建'源'RRD。
  • 使用所需参数创建“新”RRD。

使用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功能稳定下来我才会知道。