summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorTobi Oetiker <tobi@oetiker.ch>2010-08-28 09:59:55 +0200
committerTobi Oetiker <tobi@oetiker.ch>2010-08-28 09:59:55 +0200
commit1aa624d182cdec1d1f5caa69f814df29947a76f0 (patch)
treed9ebb27a4aa0c56c2c0f4dff32b22011c86d2246 /lib
parent3f7adcc5b693de323fd921cf34678e41bbf6d154 (diff)
downloadsmokeping-1aa624d182cdec1d1f5caa69f814df29947a76f0.tar.gz
smokeping-1aa624d182cdec1d1f5caa69f814df29947a76f0.tar.xz
I run smokeping on many boxes and and my Gentoo/Funtoo boxes frequently run
into localization setup issues which will bomb out Smokeping's web interface. It works fine invoked from the shell. I use the attached patch to help me diagnose the server setup problem. The behavior is identical to current Smokeping in that it logs a message and throws a HTTP 500 error. The basic Smokeping localization sanity check has uncovered "insane" setups where the PERL %ENV environment variables are being ignored by "setlocale" on several of my boxes for unknown reasons. Obviously, smokeping should quit, which it does... -- Lee Thompson stagr.lee gmail.com
Diffstat (limited to 'lib')
-rw-r--r--lib/Smokeping.pm82
1 files changed, 65 insertions, 17 deletions
diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm
index 136b56b..6828430 100644
--- a/lib/Smokeping.pm
+++ b/lib/Smokeping.pm
@@ -8,7 +8,9 @@ use Pod::Usage;
use Digest::MD5 qw(md5_base64);
use SNMP_util;
use SNMP_Session;
-use POSIX;
+# enable locale??
+#use locale;
+use POSIX qw(locale_h signal_h sys_wait_h);
use Smokeping::Config;
use RRDs;
use Sys::Syslog qw(:DEFAULT setlogsock);
@@ -26,9 +28,36 @@ setlogsock('unix')
# make sure we do not end up with , in odd places where one would expect a '.'
# we set the environment variable so that our 'kids' get the benefit too
-$ENV{LC_NUMERIC}='C';
-if (POSIX::setlocale(&POSIX::LC_NUMERIC,"") ne "C") {
- die("Resetting LC_NUMERIC failed - try removing LC_ALL from the environment");
+$ENV{'LC_NUMERIC'}='C';
+if (setlocale(LC_NUMERIC,"") ne "C") {
+ if ($ENV{'LC_ALL'} eq 'C') {
+ # This has got to be a bug in perl/mod_perl, apache or libc
+ die("Your internalization implementation on your operating system is "
+ . "not responding to your setup of LC_ALL to \"C\" as LC_NUMERIC is "
+ . "coming up as \"" . setlocale(LC_NUMERIC, "") . "\" leaving "
+ . "smokeping unable to compare numbers...");
+ }
+ elsif ($ENV{'LC_ALL'} ne "") {
+ # This error is most likely setup related and easy to fix with proper
+ # setup of the operating system or multilanguage locale setup. Hint,
+ # setting LANG is better than setting LC_ALL...
+ die("Resetting LC_NUMERIC failed probably because your international "
+ . "setup of the LC_ALL to \"". $ENV{'LC_ALL'} . "\" is overridding "
+ . "LC_NUMERIC. Setting LC_ALL is not compatible with smokeping...");
+ }
+ else {
+ # This is pretty nasty to figure out. Seems there are still lots
+ # of bugs in LOCALE behavior and if you get this error, you are
+ # affected by it. The worst is when "setlocale" is reading the
+ # environment variables of your webserver and not reading the PERL
+ # %ENV array like it should.
+ die("Something is wrong with the internalization setup of your "
+ . "operating system, webserver, or the perl plugin to your webserver "
+ . "(like mod_perl) and smokeping can not compare numbers correctly. "
+ . "On unix, check your /etc/locale.gen and run sudo locale-gen, set "
+ . "LC_NUMERIC in your perl plugin config or even your webserver "
+ . "startup script to potentially fix or work around the problem...");
+ }
}
@@ -311,11 +340,14 @@ FOR
for(1..$multis){
$extra .= "-\$i$_";
};
- /^(==|!=|<|>|<=|>=|\*)(\d+(?:\.\d*)?|U|S|\d*\*)(%?)$/
+ /^(==|!=|<|>|<=|>=|\*)(\d+(?:\.\d*)?|U|S|\d*\*)(%?)(?:(<|>|<=|>=)(\d+(?:\.\d*)?)(%?))$/
or die "ERROR: Alert $al pattern entry '$_' is invalid\n";
my $op = $1;
my $value = $2;
my $perc = $3;
+ my $op2 = $4;
+ my $value2 = $5;
+ my $perc2 = $6;
if ($op eq '*') {
if ($value =~ /^([1-9]\d*)\*$/) {
$value = $1;
@@ -336,17 +368,17 @@ FOR
} elsif ($value eq 'U') {
if ($op eq '==') {
$sub .= "$it next if defined \$y->[$i$extra];\n";
- } elsif ($op eq '!=') {
- $sub .= "$it next unless defined \$y->[$i$extra];\n";
- } else {
- die "ERROR: invalid operator $op in connection U in Alert $al definition\n";
- }
+ } elsif ($op eq '!=') {
+ $sub .= "$it next unless defined \$y->[$i$extra];\n";
+ } else {
+ die "ERROR: invalid operator $op in connection U in Alert $al definition\n";
+ }
} elsif ($value eq 'S') {
if ($op eq '==') {
$sub .= "$it next unless defined \$y->[$i$extra] and \$y->[$i$extra] eq 'S';\n";
} else {
die "ERROR: S is only valid with == operator in Alert $al definition\n";
- }
+ }
} elsif ($value eq '*') {
if ($op ne '==') {
die "ERROR: operator $op makes no sense with * in Alert $al definition\n";
@@ -354,16 +386,27 @@ FOR
} else {
if ( $x->{type} eq 'loss') {
die "ERROR: loss should be specified in % (alert $al pattern)\n" unless $perc eq "%";
- } elsif ( $x->{type} eq 'rtt' ) {
- $value /= 1000;
- } else {
- die "ERROR: unknown alert type $x->{type}\n";
- }
+ } elsif ( $x->{type} eq 'rtt' ) {
+ $value /= 1000;
+ } else {
+ die "ERROR: unknown alert type $x->{type}\n";
+ }
$sub .= <<IF;
$it next unless defined \$y->[$i$extra]
$it and \$y->[$i$extra] =~ /^\\d/
-$it and \$y->[$i$extra] $op $value;
+$it and \$y->[$i$extra] $op $value
IF
+ if ($op2){
+ if ( $x->{type} eq 'loss') {
+ die "ERROR: loss should be specified in % (alert $al pattern)\n" unless $perc2 eq "%";
+ } elsif ( $x->{type} eq 'rtt' ) {
+ $value2 /= 1000;
+ }
+ $sub .= <<IF;
+$it and \$y->[$i$extra] $op2 $value2
+IF
+ }
+ $sub .= "$it ;";
}
$i++;
}
@@ -3205,6 +3248,11 @@ You can write
to detect lines that have been losing more than 20% of the packets for two
periods after startup.
+If you want to make sure a value within a certain range you can use two conditions
+in one element
+
+ >45%<=55%
+
Sometimes it may be that conditions occur at irregular intervals. But still
you only want to throw an alert if they occur several times within a certain
amount of times. The operator B<*X*> will ignore up to I<X> values and still