contrib/rrdcopy はあるんだけど MIN/MAX は使われない。 munin 標準のこのような rrd を "RRA:AVERAGE:0.5:1:576", # resolution 5 minutes "RRA:MIN:0.5:1:576", "RRA:MAX:0.5:1:576", "RRA:AVERAGE:0.5:6:432", # 9 days, resolution 30 minutes "RRA:MIN:0.5:6:432", "RRA:MAX:0.5:6:432", "RRA:AVERAGE:0.5:24:540", # 45 days, resolution 2 hours "RRA:MIN:0.5:24:540", "RRA:MAX:0.5:24:540", "RRA:AVERAGE:0.5:288:450", # 450 days, resolution 1 day "RRA:MIN:0.5:288:450", "RRA:MAX:0.5:288:450"); 次のような rrd に MIN MAX を意識しながら dump | convert | restore しても MIN MAX の描画は行われない。 "RRA:AVERAGE:0.5:1:1051200", # resolution 5 minutes "RRA:MIN:0.5:1:1051200", "RRA:MAX:0.5:1:1051200", # convert では荒い rra pdp_per_row > 1 を細かい rra pdp_per_row == 1 にコピーする munin の標準では LINE1 は AVERAGE の g で、フッタに MIN MAX が数字で表示される。 - DEF:adownload=/usr/local/var/munin/group1/host1-plugin1-field1-g.rrd:42:MAX - DEF:idownload=/usr/local/var/munin/group1/host1-plugin1-field1-g.rrd:42:MIN - DEF:gdownload=/usr/local/var/munin/group1/host1-plugin1-field1-g.rrd:42:AVERAGE rrdtool graph を使って直接 i や a の LINE1 を描いても おそらく pdp_per_row == 1 のものは AVERAGE から MIN MAX が計算できるからとして MIN MAX のレコードが使われないものと思われる。 rrdtool resize して pdp_per_row == 1 の RRA を長くすると 長くなった区間の範囲で収まる描画に pdp_per_row > 1 の RRA は使われない。 長くした pdp_per_row == 1 で NaN な箇所は集約した pdp_per_row > 1 を用いて欲しいのだが、そうもいかない。 あれこれ考えみたのだけれど、現状の munin の挙動を極力保ちつつ pdp_per_row == 1 の RRA を長くするのは 徐々に長くしていくことが1つの方法ではないかと思った。 あまり見掛けない方法なので勘違いしているかもしれないが cron で毎日深夜に rrdcached SUSPEND RESUME で配慮しながら rrdtool resize $rrdfile 0 GRAW 288 などとして 1日分づつ延ばしていけばよいのではないか。 munin では、プラグインあたり4枚の画像 2日分 resolution 5min 1週間 resolution 30min 1ヶ月 resolution 2hour 1年 resolution 1day となっているので、例えば延ばしはじめて5日目に1週間の画像が resolution 5min に切り替わり 画像左端の1日分がNaNになる画像ができるはず。 実害としてはこのくらいで、あとはzoomの範囲が丁度 pdp_per_row == 1 で収まる場合に先頭の1日分が欠落する。 # 更新: 2020-05-07T00:47:46+09 # リサイズは問題なく動いてる。 # 上の解像度については munin の画像の横幅 400px だと、1週間については 30min で変わらなかった。 # 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. # クリックした 800px の画面だと 15min になる。さらにズームすると 5min になる。 # 1ヶ月と1年はまた今度。おそらく下で変わらなそう。 # 2日分 resolution 5min ( 2*24*60/400 = 7.2 ) # 1週間 resolution 30min ( 7*24*60/400 = 25.2 ) # 1ヶ月 resolution 2hour ( 30*24*60/400 = 108 ) # 1年 resolution 1day ( 365*24*60/400 = 1314 ) 1day = 1440min # (つまり 400px を前提に解像度を計算して、デフォルトの RRA とそのロールアップが決められてる?) # 更新おわり ぐちゃっとしてますが、1日分ずつ延ばしてみます。
#!/usr/bin/env perl

use Modern::Perl;
use IO::Socket::UNIX;
use POSIX qw(ceil);
use Text::Trim;
use Time::Moment;

my $switching_date = Time::Moment->from_string('2020-04-26T04:00:00+09')->minus_days(3)->epoch; # cron はAM3時。1時間分は余裕をもって。

my $base_dir = "/usr/local/var/munin";
my $client = IO::Socket::UNIX->new(
    Type => SOCK_STREAM,
    Peer => "/var/run/rrdcached.sock",
);

sub req {
    my ($cmd) = @_;
    $client->print("$cmd\n");
    my @lines = ($client->getline);
    die unless $lines[0] =~ /^(\d+)/;
    push @lines, $client->getline for 1..$1;
    wantarray ? @lines : join "", @lines;
}

sub parse {
    my ($res) = @_;
    # 97 Info for xx.rrd follows
    # filename 2 xx.rrd
    # rrd_version 2 0003
    # step 1 300
    # last_update 1 1587744618
    # header_size 1 2872
    # ds[42].index 1 0
    # ds[42].type 2 GAUGE
    # ds[42].minimal_heartbeat 1 600
    # ds[42].min 0 0.0000000000e+00
    # ds[42].max 0 NaN
    # ds[42].last_ds 2 51820000
    # ds[42].value 0 9.3276000000e+08
    # ds[42].unknown_sec 1 0
    # rra[0].cf 2 AVERAGE
    # rra[0].rows 1 578
    # rra[0].cur_row 1 381
    # rra[0].pdp_per_row 1 1
    # rra[0].xff 0 5.0000000000e-01
    # rra[0].cdp_prep[0].value 0 NaN
    # rra[0].cdp_prep[0].unknown_datapoints 1 0
    # ...
    my $step = $res =~ /^step 1 (\d+)/m ? $1 : die;
    my $last_update = $res =~ /^last_update 1 (\d+)/m ? $1 : die;
    my $rra0_rows   = $res =~ /^rra\[0\]\.rows 1 (\d+)/m ? $1 : die;
    ($step, $last_update, $rra0_rows);
}

sub grow {
    my ($file, $rows) = @_;

    req("SUSPEND $file") =~ /suspended/ or die;

    system(qw(rrdtool resize), $file, qw(0 GROW), $rows) == 0 or die;
    system(qw(mv resize.rrd), $file) == 0 or die;

    req("RESUME $file") =~ /resumed/ or die;
}

my @files = map trim, `find -s $base_dir -regex '.*\\.rrd' -and -mtime -30m`;
for my $file (@files) {
    my $res = req("INFO $file");
    my ($step, $last_update, $rra0_rows) = parse $res;
    my $last = int($last_update/$step)*$step;
    my $lack = $last-$step*$rra0_rows - $switching_date;
    my $lack_rows = ceil $lack/$step;
    if ($lack_rows > 0) {
        say "$file\tlack $lack_rows grow";
        grow($file, $lack_rows);
    }
    else {
    }
}

__END__

# crontab -e
0 3 * * *      time -h /usr/local/etc/munin/script/resize_rrd_little_grow.pl 2>&1

93rrd/sec ぐらい出てる

コメントする

perl adv
perl adv