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 ぐらい出てる