Hi,
I'd like to suggest a small change in the apache_volume plugin:
- print "volume$port.value ", ($1*1024), "\n";
+ print "volume$port.value ", int ($1*1024), "\n";
Since otherwise really-high-traffic sites encounter something that is, er, at least a very interesting feature of Perl: Computations using $1 do switch to exponential notation much earlier than using regular scalar variables.
How to repeat:
perl -e '$s = "976562500000"; $s =~ /(\d+)/; printf "%s\n%s\n\%s\n", ($1 * 1024), int ($1 * 1024), ($1 << 10)'
Using Debian wheezy (Perl 5.14) on amd64, i386 or armel; or Debian squeeze (Perl 5.10) on amd64 only:
1e+15
1000000000000000
1000000000000000
Compare this to
perl -e '$s = "976562500000"; $s =~ /(\d+)/; $t = $1; printf "%s\n%s\n\%s\n", ($t * 1024), int ($t * 1024), ($t << 10)'
or just
perl -e '$s = "976562500000"; printf "%s\n%s\n\%s\n", ($s * 1024), int ($s * 1024), ($s << 10)'
or even (nifty Perl 5.10 feature)
perl -E '$s = "976562500000"; $s =~ /(?<match>\d+)/; printf "%s\n%s\n\%s\n", ($+{match} * 1024), int ($+{match} * 1024), ($+{match} << 10)'
They all yield
1000000000000000
1000000000000000
1000000000000000
This wasn't so bad if rrdupdate wasn't so picky about floating point numbers in DERIVE and COUNTER data sources (see also ticket:1193). Now, if the number of kibibytes an Apache server reports to have served is 976562500000 or above (yes, that's one petabyte, and yes, this happened in the wild), the apache_volume plugin returns a float, and rrdupdate create a message in the log file like
[ERROR] In RRD: Error updating /var/lib/munin/(...)/(...)-apache_volume80-d.rrd: /var/lib/munin/(...)/(...)-apache_volume80-d.rrd: not a simple signed integer: (...)
and the rrd is not updated.
The suggested solution fixes the problem as you can see in the reproducer. Using left-shift instead of multiplication is not an alternative, since at least in Debian squeeze on i386 and armel this results in 4294966272 which is plain wrong. To be honest, int doesn't help either but no value is still better than an invalid one.
As far as I can see, the apache_volume plugin is the only plugin affected by that problem.
And perhaps somebody could ask a Perl monk what is actually happening here.