Ticket #1195 (closed defect: fixed)

Opened 4 months ago

Last modified 4 months ago

[PATCH] Fix apache_volume plugin for high-traffic sites

Reported by: cbiedl Assigned to: kenyon
Priority: normal Milestone: Munin 2.0
Component: plugins Version: 1.4.6
Severity: normal Keywords:
Cc:

Description

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.

Change History

02/01/12 08:00:20 changed by kenyon

  • owner changed from nobody to kenyon.
  • status changed from new to assigned.

02/01/12 08:02:06 changed by kenyon

  • status changed from assigned to closed.
  • resolution set to fixed.

Applied the change in r4636, thanks!