From 1eda41862b7279427ab2da51b8dd12767118bfa4 Mon Sep 17 00:00:00 2001 From: Niko Tyni Date: Wed, 9 Mar 2005 17:17:06 +0000 Subject: * change all ISG::ParseConfig references to its new name, Config::Grammar --- lib/Smokeping.pm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index 8cd5897..6718f36 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -9,7 +9,7 @@ use Digest::MD5 qw(md5_base64); use SNMP_util; use SNMP_Session; use POSIX; -use ISG::ParseConfig; +use Config::Grammar; use RRDs; use Sys::Syslog qw(:DEFAULT setlogsock); setlogsock('unix') @@ -1383,7 +1383,7 @@ DOC # if there is a subprobe, the top-level section # of this probe turns into a template, and we # need to delete its _mandatory list. - # Note that ISG::ParseConfig does mandatory checking + # Note that Config::Grammar does mandatory checking # after the whole config tree is read, so we can fiddle # here with "_mandatory" all we want. # see 1.3 above @@ -1446,7 +1446,7 @@ DOC }, }; # $PROBES - my $parser = ISG::ParseConfig->new + my $parser = Config::Grammar->new ( { _sections => [ qw(General Database Presentation Probes Alerts Targets) ], @@ -2374,7 +2374,7 @@ The contents of this manual is generated directly from the configuration file parser. The Parser for the Configuration file is written using David Schweikers -ParseConfig module. Read all about it in L. +Config::Grammar module. Read all about it in L. The Configuration file has a tree-like structure with section headings at various levels. It also contains variable assignments and tables. -- cgit v1.2.3-24-g4f1b From d9b0e622f870cc151ffe814abde6f62a47cdba58 Mon Sep 17 00:00:00 2001 From: Tobi Oetiker Date: Wed, 13 Apr 2005 11:35:52 +0000 Subject: * updated version numbers in branche * propperly deal with branches in the target tree that have no probe propperty set. --- lib/Smokeping.pm | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index 6718f36..048f795 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -20,7 +20,7 @@ use Smokeping::RRDtools; # globale persistent variables for speedy use vars qw($cfg $probes $VERSION $havegetaddrinfo $cgimode); -$VERSION="1.99001"; +$VERSION="1.99004"; # we want opts everywhere my %opt; @@ -918,13 +918,15 @@ sub update_rrds($$$$$) { my $justthisprobe = shift; # if defined, update only the targets probed by this probe my $probe = $tree->{probe}; - my $probeobj = $probes->{$probe}; foreach my $prop (keys %{$tree}) { if (ref $tree->{$prop} eq 'HASH'){ update_rrds $cfg, $probes, $tree->{$prop}, $name."/$prop", $justthisprobe; } - next if defined $justthisprobe and $probe ne $justthisprobe; + # if we are looking down a branche where no probe propperty is set there is not sense + # in further exploring it + next unless defined $probe and defined $justthisprobe and $probe ne $justthisprobe; + my $probeobj = $probes->{$probe}; if ($prop eq 'host' and check_filter($cfg,$name)) { #print "update $name\n"; my $updatestring = $probeobj->rrdupdate_string($tree); -- cgit v1.2.3-24-g4f1b From 21df925982b162f18479c9ab8312e3573dcd7f24 Mon Sep 17 00:00:00 2001 From: Tobi Oetiker Date: Wed, 13 Apr 2005 19:31:27 +0000 Subject: * added labeling fixes for rrdtool 1.2 compatibility * added navigator mode where it is possible to alter the timerange shown in a graph. This feature is sponsored by BeverlyCorp. * fix fix for matcher cache skipping --- lib/Smokeping.pm | 347 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 218 insertions(+), 129 deletions(-) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index 048f795..963299d 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -542,6 +542,9 @@ sub get_overview ($$$$){ my $date = $cfg->{Presentation}{overview}{strftime} ? POSIX::strftime($cfg->{Presentation}{overview}{strftime}, localtime(time)) : scalar localtime(time); + if ( $RRDs::VERSION >= 1.199908 ){ + $date =~ s|:|\\:|g; + } foreach my $prop (sort {$tree->{$a}{_order} <=> $tree->{$b}{_order}} grep { ref $tree->{$_} eq 'HASH' and defined $tree->{$_}{host}} keys %$tree) { @@ -566,11 +569,10 @@ sub get_overview ($$$$){ "CDEF:dm=median,0,$max,LIMIT", "CDEF:dm2=median,1.5,*,0,$max,LIMIT", "LINE1:dm2", # this is for kicking things down a bit - "LINE1:dm#$medc:median RTT avg\\: ", - "GPRINT:median:AVERAGE: %0.2lf %ss ", - "GPRINT:median:LAST: latest RTT\\: %0.2lf %ss ", - "GPRINT:ploss:AVERAGE: avg pkg loss\\: %.2lf %% ", - "COMMENT: $date\\j"); + "LINE1:dm#$medc:median RTT", + "GPRINT:median:AVERAGE:avg RTT\\: %.2lf %ss", + "GPRINT:ploss:AVERAGE:avg pkt loss\\: %.2lf %%", + "COMMENT:$date\\j"); my $ERROR = RRDs::error(); $page .= "
"; if (defined $ERROR) { @@ -645,26 +647,46 @@ sub smokecol ($) { return \@items; } +sub parse_datetime($){ + my $in = shift; + for ($in){ + /^\s*(\d{4})-(\d{1,2})-(\d{1,2})(?:\s+(\d{1,2}):(\d{2})(?::(\d{2}))?)?\s*$/ && + return POSIX::mktime($6||0,$5||0,$4||0,$3,$2-1,$1-1900,0,0,-1); + /([ -:a-z0-9]+)/ && return $1; + }; +} + sub get_detail ($$$$){ + # when drawing the detail page there are two modes for doing it + # a) classic with several static graphs on the page + # b) with one graph and below the graph one can specify the end time + # and the length of the graph. my $cfg = shift; my $q = shift; my $tree = shift; my $open = shift; + return "" unless $tree->{host}; + my @dirs = @{$open}; my $file = pop @dirs; my $dir = ""; - die "ERROR: ".(join ".", @dirs)." has no probe defined\n" + + return "
ERROR: ".(join ".", @dirs)." has no probe defined
" unless $tree->{probe}; - die "ERROR: ".(join ".", @dirs)." $tree->{probe} is not known\n" + + return "
ERROR: ".(join ".", @dirs)." $tree->{probe} is not known
" unless $cfg->{__probes}{$tree->{probe}}; + my $probe = $cfg->{__probes}{$tree->{probe}}; my $ProbeDesc = $probe->ProbeDesc(); my $step = $probe->step(); my $pings = $probe->_pings($tree); - my $page; + my $mode = $q->param('displaymode') || 's'; + return "
ERROR: unknown displaymode $mode
" + unless $mode =~ /^[sn]$/; for (@dirs) { $dir .= "/$_"; @@ -674,142 +696,190 @@ sub get_detail ($$$$){ unless -d $cfg->{General}{imgcache}.$dir; } - my $rrd = $cfg->{General}{datadir}."/".(join "/", @dirs)."/${file}.rrd"; - my $img = $cfg->{General}{imgcache}."/".(join "/", @dirs)."/${file}.rrd"; - - my %lasthight; - if (open (HG,"<${img}.maxhight")){ - while (){ - chomp; - my @l = split / /; - $lasthight{$l[0]} = $l[1]; - } - close HG; - } - my $max = findmax $cfg, $rrd; - if (open (HG,">${img}.maxhight")){ - foreach my $s (keys %{$max}){ - print HG "$s $max->{$s}\n"; - } - close HG; - } + my $rrd = $cfg->{General}{datadir}."/".$dir."/${file}.rrd"; + + my $imgbase; + my $imghref; + my $max; + my @tasks; + my %lasthight; + + if ($mode eq 's'){ + # in nave mode there is only one graph, so the height calculation + # is not necessary. + $imgbase = $cfg->{General}{imgcache}."/".(join "/", @dirs)."/${file}"; + $imghref = $cfg->{General}{imgurl}."/".(join "/", @dirs)."/${file}"; + @tasks = @{$cfg->{Presentation}{detail}{_table}}; + if (open (HG,"<${imgbase}.maxhight")){ + while (){ + chomp; + my @l = split / /; + $lasthight{$l[0]} = $l[1]; + } + close HG; + } + $max = findmax $cfg, $rrd; + if (open (HG,">${imgbase}.maxhight")){ + foreach my $s (keys %{$max}){ + print HG "$s $max->{$s}\n"; + } + close HG; + } + } else { + my $basedir = + mkdir $cfg->{General}{imgcache}."/__navcache",0755 unless -d $imgbase; + # remove old images after one hour + my $pattern = "$cfg->{General}{imgcache}/__navcache/*.png"; + for (<$pattern>){ + unlink $_ if -A $_ > 1/24; + } + $imgbase =$cfg->{General}{imgcache}."/__navcache/".time()."$$"; + $imghref =$cfg->{General}{imgurl}."/__navcache/".time()."$$"; + @tasks = (["Navigator Mode", parse_datetime($q->param('start')),parse_datetime($q->param('end'))]); + my ($graphret,$xs,$ys) = RRDs::graph + ("dummy", + '--start', $tasks[0][1], + '--end',$tasks[0][2], + "DEF:maxping=${rrd}:median:AVERAGE", + 'PRINT:maxping:MAX:%le' ); + my $ERROR = RRDs::error(); + do_log $ERROR if $ERROR; + my $val = $graphret->[0]; + $val = 1 if $val =~ /nan/i; + $max = { $tasks[0][1] => $val }; + } + my $smoke = $pings >= 3 - ? smokecol $pings : - [ 'COMMENT:(Not enough pings to draw any smoke.)\s', 'COMMENT:\s' ]; - # one \s doesn't seem to be enough + ? smokecol $pings : + [ 'COMMENT:(Not enough pings to draw any smoke.)\s', 'COMMENT:\s' ]; + # one \s doesn't seem to be enough my @upargs; my @upsmoke; - my @median; - my $date = $cfg->{Presentation}{detail}{strftime} ? - POSIX::strftime($cfg->{Presentation}{detail}{strftime}, - localtime(time)) : scalar localtime(time); - - for (@{$cfg->{Presentation}{detail}{_table}}) { - my ($desc,$start) = @{$_}; - $start = exp2seconds($start); - do { - @median = ("DEF:median=${rrd}:median:AVERAGE", - "DEF:loss=${rrd}:loss:AVERAGE", - "CDEF:ploss=loss,$pings,/,100,*", - "GPRINT:median:AVERAGE:Median Ping RTT (avg %.1lf %ss) ", - "LINE1:median#202020" - ); + my %lc; + if ( defined $cfg->{Presentation}{detail}{loss_colors}{_table} ) { + for (@{$cfg->{Presentation}{detail}{loss_colors}{_table}}) { + my ($num,$col,$txt) = @{$_}; + $lc{$num} = [ $txt, "#".$col ]; + } + } else { my $p = $pings; + %lc = (0 => ['0', '#26ff00'], + 1 => ["1/$p", '#00b8ff'], + 2 => ["2/$p", '#0059ff'], + 3 => ["3/$p", '#5e00ff'], + 4 => ["4/$p", '#7e00ff'], + int($p/2) => [int($p/2)."/$p", '#dd00ff'], + $p-1 => [($p-1)."/$p", '#ff0000'], + ); + }; + + my %upt; + if ( defined $cfg->{Presentation}{detail}{uptime_colors}{_table} ) { + for (@{$cfg->{Presentation}{detail}{uptime_colors}{_table}}) { + my ($num,$col,$txt) = @{$_}; + $upt{$num} = [ $txt, "#".$col]; + } + } else { + %upt = ( 3600 => ['<1h', '#FFD3D3'], + 2*3600 => ['<2h', '#FFE4C7'], + 6*3600 => ['<6h', '#FFF9BA'], + 12*3600 => ['<12h','#F3FFC0'], + 24*3600 => ['<1d', '#E1FFCC'], + 7*24*3600 => ['<1w', '#BBFFCB'], + 30*24*3600 => ['<1m', '#BAFFF5'], + '1e100' => ['>1m', '#DAECFF'] + ); + } + + my $date = $cfg->{Presentation}{detail}{strftime} ? + POSIX::strftime($cfg->{Presentation}{detail}{strftime}, + localtime(time)) : scalar localtime(time); + my $BS = ''; + if ( $RRDs::VERSION >= 1.199908 ){ + $date =~ s|:|\\:|g; + $ProbeDesc =~ s|:|\\:|g; + $BS = '\\'; + } - my %lc; - my $lastup = 0; - if ( defined $cfg->{Presentation}{detail}{loss_colors}{_table} ) { - for (@{$cfg->{Presentation}{detail}{loss_colors}{_table}}) { - my ($num,$col,$txt) = @{$_}; - $lc{$num} = [ $txt, "#".$col ]; - } - } else { - %lc = (0 => ['0', '#26ff00'], - 1 => ["1/$p", '#00b8ff'], - 2 => ["2/$p", '#0059ff'], - 3 => ["3/$p", '#5e00ff'], - 4 => ["4/$p", '#7e00ff'], - int($p/2) => [int($p/2)."/$p", '#dd00ff'], - $p-1 => [($p-1)."/$p", '#ff0000'], + for (@tasks) { + my ($desc,$start,$end) = @{$_}; + $end ||= 'last'; + $start = exp2seconds($start) if $mode eq 's'; + + my $startstr = POSIX::strftime("%Y-%m-%d %H:%M",localtime($mode eq 'n' ? $start : time-$start)); + my $endstr = POSIX::strftime("%Y-%m-%d %H:%M",localtime($mode eq 'n' ? $end : time)); + + my $last = -1; + my $swidth = $max->{$start} / $cfg->{Presentation}{detail}{height}; + my @median = ("DEF:median=${rrd}:median:AVERAGE", + "DEF:loss=${rrd}:loss:AVERAGE", + "CDEF:ploss=loss,$pings,/,100,*", + "GPRINT:median:AVERAGE:Median Ping RTT (%.1lf %ss avg) ", + "LINE1:median#202020" ); - }; - my $last = -1; - my $swidth = $max->{$start} / $cfg->{Presentation}{detail}{height}; foreach my $loss (sort {$a <=> $b} keys %lc){ next if $loss >= $pings; - my $lvar = $loss; $lvar =~ s/\./d/g ; + my $lvar = $loss; $lvar =~ s/\./d/g ; push @median, - ( - "CDEF:me$lvar=loss,$last,GT,loss,$loss,LE,*,1,UNKN,IF,median,*", - "CDEF:meL$lvar=me$lvar,$swidth,-", - "CDEF:meH$lvar=me$lvar,0,*,$swidth,2,*,+", - "AREA:meL$lvar", - "STACK:meH$lvar$lc{$loss}[1]:$lc{$loss}[0]" - ); - $last = $loss; + ( + "CDEF:me$lvar=loss,$last,GT,loss,$loss,LE,*,1,UNKN,IF,median,*", + "CDEF:meL$lvar=me$lvar,$swidth,-", + "CDEF:meH$lvar=me$lvar,0,*,$swidth,2,*,+", + "AREA:meL$lvar", + "STACK:meH$lvar$lc{$loss}[1]:$lc{$loss}[0]" + # "LINE2:me$lvar$lc{$loss}[1]:$lc{$loss}[0]" + ); + $last = $loss; } - push @median, ( "GPRINT:ploss:AVERAGE: avg pkg loss\\: %.2lf %%\\l" ); -# map {print "$_
"} @median; - }; + push @median, ( "COMMENT:\\l", + "GPRINT:ploss:AVERAGE:Packet Loss\\: %.2lf %% average", + "GPRINT:ploss:MAX:%.2lf %% maximum", + "GPRINT:ploss:LAST:%.2lf %% current\\l" + ); + # if we have uptime draw a colorful background or the graph showing the uptime my $cdir=$cfg->{General}{datadir}."/".(join "/", @dirs)."/"; if (-f "$cdir/${file}.adr") { - @upsmoke = (); - @upargs = ('COMMENT:Link Up: ', - "DEF:uptime=${rrd}:uptime:AVERAGE", - "CDEF:duptime=uptime,86400,/", - 'GPRINT:duptime:LAST: %0.1lf days ('); - my %upt; - if ( defined $cfg->{Presentation}{detail}{uptime_colors}{_table} ) { - for (@{$cfg->{Presentation}{detail}{uptime_colors}{_table}}) { - my ($num,$col,$txt) = @{$_}; - $upt{$num} = [ $txt, "#".$col]; - } - } else { - %upt = ( 3600 => ['<1h', '#FFD3D3'], - 2*3600 => ['<2h', '#FFE4C7'], - 6*3600 => ['<6h', '#FFF9BA'], - 12*3600 => ['<12h','#F3FFC0'], - 24*3600 => ['<1d', '#E1FFCC'], - 7*24*3600 => ['<1w', '#BBFFCB'], - 30*24*3600 => ['<1m', '#BAFFF5'], - '1e100' => ['>1m', '#DAECFF'] - ); - } - my $lastup = 0; - foreach my $uptime (sort {$a <=> $b} keys %upt){ - push @upargs, - ( - "CDEF:up$uptime=uptime,$lastup,GE,uptime,$uptime,LE,*,INF,UNKN,IF", - "AREA:up$uptime$upt{$uptime}[1]:$upt{$uptime}[0]" - ); - push @upsmoke, - ( - "CDEF:ups$uptime=uptime,$lastup,GE,uptime,$uptime,LE,*,cp2,UNKN,IF", - "AREA:ups$uptime$upt{$uptime}[1]" + @upsmoke = (); + @upargs = ('COMMENT:Link Up${BS}: ', + "DEF:uptime=${rrd}:uptime:AVERAGE", + "CDEF:duptime=uptime,86400,/", + 'GPRINT:duptime:LAST: %0.1lf days ('); + my $lastup = 0; + foreach my $uptime (sort {$a <=> $b} keys %upt){ + push @upargs, + ( + "CDEF:up$uptime=uptime,$lastup,GE,uptime,$uptime,LE,*,INF,UNKN,IF", + "AREA:up$uptime$upt{$uptime}[1]:$upt{$uptime}[0]" + ); + push @upsmoke, + ( + "CDEF:ups$uptime=uptime,$lastup,GE,uptime,$uptime,LE,*,cp2,UNKN,IF", + "AREA:ups$uptime$upt{$uptime}[1]" ); - $lastup=$uptime; - } - - push @upargs, 'COMMENT:)\l'; -# map {print "$_
"} @upargs; - }; + $lastup=$uptime; + } + + push @upargs, 'COMMENT:)\l'; + # map {print "$_
"} @upargs; + }; my @log = (); push @log, "--logarithmic" if $cfg->{Presentation}{detail}{logarithmic} and - $cfg->{Presentation}{detail}{logarithmic} eq 'yes'; - + $cfg->{Presentation}{detail}{logarithmic} eq 'yes'; + my @lazy =(); - @lazy = ('--lazy') if $lasthight{$start} and $lasthight{$start} == $max->{$start}; + @lazy = ('--lazy') if $mode eq 's' and $lasthight{$start} and $lasthight{$start} == $max->{$start}; + $desc = "Navigator Graph" if $mode eq 'n'; my ($graphret,$xs,$ys) = RRDs::graph - ($cfg->{General}{imgcache}.$dir."/${file}_last_${start}.png", + ("${imgbase}_${end}_${start}.png", @lazy, - '--start','-'.$start, + '--start',( $mode eq 's' ? '-'.$start : $start), + ($end ne 'last' ? ('--end',$end) : ()), '--height',$cfg->{Presentation}{detail}{height}, '--width',,$cfg->{Presentation}{detail}{width}, '--title',$desc, - '--rigid', - '--upper-limit', $max->{$start}, + '--rigid','--upper-limit', $max->{$start}, @log, '--lower-limit',(@log ? ($max->{$start} > 0.01) ? '0.001' : '0.0001' : '0'), '--vertical-label',"Seconds", @@ -824,8 +894,6 @@ sub get_detail ($$$$){ @$smoke, @upsmoke, # draw the rest of the uptime bg color @median, -# 'LINE3:median#ff0000:Median RTT in grey '.$cfg->{Database}{pings}.' pings sorted by RTT', -# 'LINE1:median#ff8080', # Gray background for times when no data was collected, so they can # be distinguished from network being down. ( $cfg->{Presentation}{detail}{nodata_color} ? ( @@ -834,14 +902,34 @@ sub get_detail ($$$$){ ()), 'HRULE:0#000000', 'COMMENT:\s', - "COMMENT:Probe: $pings $ProbeDesc every $step seconds", + "COMMENT:Probe${BS}: $pings $ProbeDesc every $step seconds", 'COMMENT:created on '.$date.'\j' ); my $ERROR = RRDs::error(); - $page .= "
". - ( $ERROR || - "{General}{imgurl}.$dir."/${file}_last_${start}.png\">" )."
"; + if ($mode eq 'n'){ + $page .= "
"; + $page .= ( $ERROR || qq{} ); + $page .= "
"; + $page .= $q->start_form(-method=>'GET') + . "

Time range: " + . $q->textfield(-name=>'start',-default=>$startstr) + . "  to  ".$q->textfield(-name=>'end',-default=>$endstr) + . $q->hidden(-name=>'target' ) + . $q->hidden(-name=>'displaymode',-default=>$mode ) + . " " + . $q->submit(-name=>'Generate!') + . "

" + . $q->end_form(); + } else { + $startstr =~ s/\s/%20/g; + $endstr =~ s/\s/%20/g; + $page .= "
"; + $page .= ( $ERROR || + qq{' + . qq{}."" ); + $page .= "
"; + + } } return $page; @@ -925,7 +1013,8 @@ sub update_rrds($$$$$) { } # if we are looking down a branche where no probe propperty is set there is not sense # in further exploring it - next unless defined $probe and defined $justthisprobe and $probe ne $justthisprobe; + next unless defined $probe; + next if defined $justthisprobe and $probe ne $justthisprobe; my $probeobj = $probes->{$probe}; if ($prop eq 'host' and check_filter($cfg,$name)) { #print "update $name\n"; -- cgit v1.2.3-24-g4f1b From 1f333688daf8f6dcf6f5a9c0be857dbcf0675dc3 Mon Sep 17 00:00:00 2001 From: Tobi Oetiker Date: Fri, 15 Apr 2005 15:03:01 +0000 Subject: make unlink in navcache work --- lib/Smokeping.pm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index 963299d..518f5a1 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -559,9 +559,11 @@ sub get_overview ($$$$){ '--start','-'.exp2seconds($cfg->{Presentation}{overview}{range}), '--title',$tree->{$prop}{title}, '--height',$cfg->{Presentation}{overview}{height}, - '--width',,$cfg->{Presentation}{overview}{width}, + '--width',$cfg->{Presentation}{overview}{width}, '--vertical-label',"Seconds", '--imgformat','PNG', + '--alt-autoscale-max', + '--alt-y-grid', '--lower-limit','0', "DEF:median=${rrd}:median:AVERAGE", "DEF:loss=${rrd}:loss:AVERAGE", @@ -726,11 +728,10 @@ sub get_detail ($$$$){ close HG; } } else { - my $basedir = - mkdir $cfg->{General}{imgcache}."/__navcache",0755 unless -d $imgbase; + mkdir $cfg->{General}{imgcache}."/__navcache",0755 unless -d $cfg->{General}{imgcache}."/__navcache"; # remove old images after one hour my $pattern = "$cfg->{General}{imgcache}/__navcache/*.png"; - for (<$pattern>){ + for (<"$pattern">){ unlink $_ if -A $_ > 1/24; } $imgbase =$cfg->{General}{imgcache}."/__navcache/".time()."$$"; -- cgit v1.2.3-24-g4f1b From e5123e033bdae8ceaf9ba847b929ec56d9dfa1e8 Mon Sep 17 00:00:00 2001 From: Tobi Oetiker Date: Fri, 15 Apr 2005 15:25:38 +0000 Subject: make navigator feature more robust for situations where invalid timeranges are provided. --- lib/Smokeping.pm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index 518f5a1..16df63f 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -745,10 +745,10 @@ sub get_detail ($$$$){ "DEF:maxping=${rrd}:median:AVERAGE", 'PRINT:maxping:MAX:%le' ); my $ERROR = RRDs::error(); - do_log $ERROR if $ERROR; + return "
RRDtool did not understand your input: $ERROR.
" if $ERROR; my $val = $graphret->[0]; $val = 1 if $val =~ /nan/i; - $max = { $tasks[0][1] => $val }; + $max = { $tasks[0][1] => $val * 1.5 }; } my $smoke = $pings >= 3 @@ -808,8 +808,8 @@ sub get_detail ($$$$){ $end ||= 'last'; $start = exp2seconds($start) if $mode eq 's'; - my $startstr = POSIX::strftime("%Y-%m-%d %H:%M",localtime($mode eq 'n' ? $start : time-$start)); - my $endstr = POSIX::strftime("%Y-%m-%d %H:%M",localtime($mode eq 'n' ? $end : time)); + my $startstr = $start =~ /^\d+$/ ? POSIX::strftime("%Y-%m-%d %H:%M",localtime($mode eq 'n' ? $start : time-$start)) : $start; + my $endstr = $end =~ /^\d+$/ ? POSIX::strftime("%Y-%m-%d %H:%M",localtime($mode eq 'n' ? $end : time)) : $end; my $last = -1; my $swidth = $max->{$start} / $cfg->{Presentation}{detail}{height}; -- cgit v1.2.3-24-g4f1b From cc63560d93815cac731fefe82f24aee01aba7676 Mon Sep 17 00:00:00 2001 From: Niko Tyni Date: Tue, 10 May 2005 11:45:52 +0000 Subject: * 2.0/lib/Smokeping.pm: + make 'smokeping -static' work again + document '@include' and its friends in smokeping_config in addition to Config::Grammar --- lib/Smokeping.pm | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index 16df63f..8015d25 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -50,6 +50,10 @@ sub find_libdir { sub do_log(@); sub load_probe($$$$); +sub dummyCGI::param { + return wantarray ? () : ""; +} + sub load_probes ($){ my $cfg = shift; my %prbs; @@ -2451,6 +2455,7 @@ sub load_cfg ($) { sub makepod ($){ my $parser = shift; my $e='='; + my $a='@'; my $retval = < or C<">. +Whitespace can also be escaped with C<\\>. Quotes inside quotes are allowed but must +be escaped with a backslash as well. + +${e}head2 SPECIFIC SYNTAX + +The text below describes the specific syntax of the SmokePing configuration file. POD -- cgit v1.2.3-24-g4f1b From ef0a8b6b72eff929a9f6a414e16db33ec3fac07d Mon Sep 17 00:00:00 2001 From: Tobi Oetiker Date: Wed, 11 May 2005 19:48:55 +0000 Subject: fix zooming --- lib/Smokeping.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index 8015d25..caaeab0 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -930,7 +930,7 @@ sub get_detail ($$$$){ $endstr =~ s/\s/%20/g; $page .= "
"; $page .= ( $ERROR || - qq{' + qq{' . qq{}."" ); $page .= "
"; @@ -2132,7 +2132,7 @@ let the pattern match: >10%,*10*,>10% -will fire if more than 10% of the packets have been losst twice over the +will fire if more than 10% of the packets have been lost at least twice over the last 10 samples. A complete example -- cgit v1.2.3-24-g4f1b From 83ab1432a8f085b2139cab8a61227b80e5b319b4 Mon Sep 17 00:00:00 2001 From: Tobi Oetiker Date: Wed, 11 May 2005 19:58:21 +0000 Subject: prepare for the release of smokeping-2.0rc4 --- lib/Smokeping.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index caaeab0..7be666d 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -20,7 +20,7 @@ use Smokeping::RRDtools; # globale persistent variables for speedy use vars qw($cfg $probes $VERSION $havegetaddrinfo $cgimode); -$VERSION="1.99004"; +$VERSION="1.99005"; # we want opts everywhere my %opt; -- cgit v1.2.3-24-g4f1b From 02b65c3987f68a239c92376cbf24bc066a04d38d Mon Sep 17 00:00:00 2001 From: Niko Tyni Date: Thu, 26 May 2005 19:24:08 +0000 Subject: * tSmoke stuff; no testing done yet + 2.0/lib/Smokeping.pm: include config file support + 2.0/tSmoke.v4.README: integrate into tSmoke script + 2.0/bin/tSmoke.dist: * renamed from tSmoke.pl to tSmoke * installation instructions updated + 2.0/etc/tmail.dist: * renamed from 2.0/etc/tmail + 2.0/Makefile: * doc file generation --- lib/Smokeping.pm | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index 7be666d..46545a0 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -1555,7 +1555,7 @@ DOC _vars => [ qw(owner imgcache imgurl datadir pagedir piddir sendmail offset smokemail cgiurl mailhost contact netsnpp - syslogfacility syslogpriority concurrentprobes changeprocessnames) ], + syslogfacility syslogpriority concurrentprobes changeprocessnames tmail) ], _mandatory => [ qw(owner imgcache imgurl datadir piddir smokemail cgiurl contact) ], @@ -1714,6 +1714,13 @@ be appended to the process name as '[probe]', eg. '/usr/bin/smokeping If 'concurrentprobes' is not set to 'yes', this variable has no effect. DOC }, + tmail => + { + %$FILECHECK_SUB, + _doc => < { -- cgit v1.2.3-24-g4f1b From 9791370bdbea2be98b9f715a4cea7bbfc5ec9880 Mon Sep 17 00:00:00 2001 From: Tobi Oetiker Date: Tue, 31 May 2005 20:14:23 +0000 Subject: prepare for the release of smokeping-2.0rc5 --- lib/Smokeping.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index 46545a0..a7f00a9 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -20,7 +20,7 @@ use Smokeping::RRDtools; # globale persistent variables for speedy use vars qw($cfg $probes $VERSION $havegetaddrinfo $cgimode); -$VERSION="1.99005"; +$VERSION="1.99006"; # we want opts everywhere my %opt; -- cgit v1.2.3-24-g4f1b From 66c8d49cbe278316114a6eef8ccb509c9e67d0ba Mon Sep 17 00:00:00 2001 From: Tobi Oetiker Date: Sun, 3 Jul 2005 22:15:20 +0000 Subject: tune the rrd files for min/max/heartbeat --- lib/Smokeping.pm | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index a7f00a9..15eb126 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -385,6 +385,7 @@ sub init_target_tree ($$$$) { my $comparison = Smokeping::RRDtools::compare($name.".rrd", \@create); die("Error: RRD parameter mismatch ('$comparison'). You must delete $name.rrd or fix the configuration parameters.\n") if $comparison; + Smokeping::RRDtools::tuneds($name.".rrd", \@create); } } } -- cgit v1.2.3-24-g4f1b From 6c3d9be08286f6bf6b21bfb7e4f8ee77900025df Mon Sep 17 00:00:00 2001 From: Tobi Oetiker Date: Sun, 3 Jul 2005 22:22:05 +0000 Subject: backslash after LinuUp --- lib/Smokeping.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index 15eb126..6df240b 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -848,7 +848,7 @@ sub get_detail ($$$$){ my $cdir=$cfg->{General}{datadir}."/".(join "/", @dirs)."/"; if (-f "$cdir/${file}.adr") { @upsmoke = (); - @upargs = ('COMMENT:Link Up${BS}: ', + @upargs = ("COMMENT:Link Up${BS}: ", "DEF:uptime=${rrd}:uptime:AVERAGE", "CDEF:duptime=uptime,86400,/", 'GPRINT:duptime:LAST: %0.1lf days ('); -- cgit v1.2.3-24-g4f1b From 3ca78feffa42b2863dcc23c2143d96bead1e107f Mon Sep 17 00:00:00 2001 From: Tobi Oetiker Date: Mon, 4 Jul 2005 05:58:11 +0000 Subject: the old pngs in __navcache did not get removed properly ... --- lib/Smokeping.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index 6df240b..641c651 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -735,9 +735,9 @@ sub get_detail ($$$$){ } else { mkdir $cfg->{General}{imgcache}."/__navcache",0755 unless -d $cfg->{General}{imgcache}."/__navcache"; # remove old images after one hour - my $pattern = "$cfg->{General}{imgcache}/__navcache/*.png"; - for (<"$pattern">){ - unlink $_ if -A $_ > 1/24; + my $pattern = $cfg->{General}{imgcache}."/__navcache/*.png"; + for (glob $pattern){ + unlink $_ if time - (stat $_)[9] > 3600; } $imgbase =$cfg->{General}{imgcache}."/__navcache/".time()."$$"; $imghref =$cfg->{General}{imgurl}."/__navcache/".time()."$$"; -- cgit v1.2.3-24-g4f1b From caea6ae36aaacadab7029f172821899d237108f4 Mon Sep 17 00:00:00 2001 From: Tobi Oetiker Date: Fri, 29 Jul 2005 08:14:17 +0000 Subject: set LC_NUMERIC to C to help people that would otherwhise get , as decimal separator --- lib/Smokeping.pm | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index 641c651..5d28b78 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -12,8 +12,15 @@ use POSIX; use Config::Grammar; use RRDs; use Sys::Syslog qw(:DEFAULT setlogsock); + setlogsock('unix') if grep /^ $^O $/xo, ("linux", "openbsd", "freebsd", "netbsd"); + +# 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'; +POSIX::setlocale(&POSIX::LC_NUMERIC,""); + use File::Basename; use Smokeping::Examples; use Smokeping::RRDtools; @@ -877,7 +884,8 @@ sub get_detail ($$$$){ my @lazy =(); @lazy = ('--lazy') if $mode eq 's' and $lasthight{$start} and $lasthight{$start} == $max->{$start}; $desc = "Navigator Graph" if $mode eq 'n'; - my ($graphret,$xs,$ys) = RRDs::graph + my $timer_start = time(); + my @task = ("${imgbase}_${end}_${start}.png", @lazy, '--start',( $mode eq 's' ? '-'.$start : $start), @@ -910,11 +918,13 @@ sub get_detail ($$$$){ 'COMMENT:\s', "COMMENT:Probe${BS}: $pings $ProbeDesc every $step seconds", 'COMMENT:created on '.$date.'\j' ); + + my ($graphret,$xs,$ys) = RRDs::graph @task; my $ERROR = RRDs::error(); if ($mode eq 'n'){ $page .= "
"; - $page .= ( $ERROR || qq{} ); + $page .= ( $ERROR || qq|| ); $page .= "
"; $page .= $q->start_form(-method=>'GET') . "

Time range: " @@ -930,6 +940,9 @@ sub get_detail ($$$$){ $startstr =~ s/\s/%20/g; $endstr =~ s/\s/%20/g; $page .= "

"; +# $page .= (time-$timer_start)."
"; +# $page .= join " ",map {"'$_'"} @task; + $page .= "
"; $page .= ( $ERROR || qq{' . qq{}."" ); -- cgit v1.2.3-24-g4f1b From 69064fb816bd54a08ffd92760f125a5d83793250 Mon Sep 17 00:00:00 2001 From: Niko Tyni Date: Tue, 23 Aug 2005 12:43:37 +0000 Subject: * 2.0/lib/Smokeping.pm, 2.0/CHANGES: + make errors in DYNAMIC updates appear in the web server error log * 2.0/TODO: + replace the __WARN__ and __DIE__ handlers with CGI::Carp? --- lib/Smokeping.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index 5d28b78..8f98341 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -2572,7 +2572,8 @@ sub cgi ($) { -charset=> ( $cfg->{Presentation}{charset} || 'iso-8859-15') ); if ($q->param(-name=>'secret') && $q->param(-name=>'target') ) { - update_dynaddr $cfg,$q; + my $ret = update_dynaddr $cfg,$q; + do_cgilog($ret) if defined $ret and $ret ne ""; } else { display_webpage $cfg,$q; } -- cgit v1.2.3-24-g4f1b From fcaa98c7edf28d8d16ff3f970460d2a0bcbd409d Mon Sep 17 00:00:00 2001 From: Niko Tyni Date: Mon, 29 Aug 2005 12:04:26 +0000 Subject: * 2.0/lib/Smokeping.pm: + use CGI::Carp and warn() for do_cgilog() to get timestamps there as well --- lib/Smokeping.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index 8f98341..9134612 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -2422,7 +2422,7 @@ sub daemonize_me ($) { sub do_cgilog ($){ my $str = shift; print "

" , $str, "

\n"; - print STDERR $str,"\n"; # for the webserver log + warn $str, "\n"; # for the webserver log } sub do_debuglog ($){ -- cgit v1.2.3-24-g4f1b From 04e1ef4cd80ad08455452d56aa4b953ed3a53057 Mon Sep 17 00:00:00 2001 From: Niko Tyni Date: Tue, 30 Aug 2005 12:38:35 +0000 Subject: * 2.0/lib/Smokeping.pm: + make the address of the remote client appear in the web server's error log --- lib/Smokeping.pm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index 9134612..050cb34 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -2395,6 +2395,7 @@ sub daemonize_me ($) { sub initialize_cgilog (){ $use_cgilog = 1; + CGI::Carp::set_progname($0 . " [client " . ($ENV{REMOTE_ADDR}||"(unknown)") . "]"); $logging=1; } @@ -2571,11 +2572,12 @@ sub cgi ($) { -expires=>'+'.($cfg->{Database}{step}).'s', -charset=> ( $cfg->{Presentation}{charset} || 'iso-8859-15') ); + initialize_cgilog(); if ($q->param(-name=>'secret') && $q->param(-name=>'target') ) { - my $ret = update_dynaddr $cfg,$q; + my $ret = update_dynaddr $cfg,$q; do_cgilog($ret) if defined $ret and $ret ne ""; } else { - display_webpage $cfg,$q; + display_webpage $cfg,$q; } } -- cgit v1.2.3-24-g4f1b From 733f5ee3d4aad0c1a21d796d5a36baa82389e199 Mon Sep 17 00:00:00 2001 From: Niko Tyni Date: Sun, 4 Sep 2005 09:20:48 +0000 Subject: * 2.0/lib/Smokeping.pm, 2.0/TODO, 2.0/CHANGES: + return '404 not found' when DYNAMIC updates fail --- lib/Smokeping.pm | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index 050cb34..18415f4 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -118,11 +118,11 @@ sub update_dynaddr ($$){ my $address = $ENV{REMOTE_ADDR}; my $targetptr = $cfg->{Targets}; foreach my $step (@target){ - return "Error: Unknown Target $step" + return "Error: Unknown target $step" unless defined $targetptr->{$step}; $targetptr = $targetptr->{$step}; }; - return "Error: Invalid Target" + return "Error: Invalid target or secret" unless defined $targetptr->{host} and $targetptr->{host} eq "DYNAMIC/${secret}"; my $file = $cfg->{General}{datadir}."/".(join "/", @target); @@ -2568,15 +2568,20 @@ sub cgi ($) { umask 022; load_cfg shift; my $q=new CGI; - print $q->header(-type=>'text/html', - -expires=>'+'.($cfg->{Database}{step}).'s', - -charset=> ( $cfg->{Presentation}{charset} || 'iso-8859-15') - ); initialize_cgilog(); if ($q->param(-name=>'secret') && $q->param(-name=>'target') ) { my $ret = update_dynaddr $cfg,$q; - do_cgilog($ret) if defined $ret and $ret ne ""; + if (defined $ret and $ret ne "") { + print $q->header(-status => "404 Not Found"); + do_cgilog("Updating DYNAMIC address failed: $ret"); + } else { + print $q->header; # no HTML output on success + } } else { + print $q->header(-type=>'text/html', + -expires=>'+'.($cfg->{Database}{step}).'s', + -charset=> ( $cfg->{Presentation}{charset} || 'iso-8859-15') + ); display_webpage $cfg,$q; } } -- cgit v1.2.3-24-g4f1b From 3946df708ae20686c8453eb55be934103daf2f7e Mon Sep 17 00:00:00 2001 From: Niko Tyni Date: Sun, 4 Sep 2005 11:34:08 +0000 Subject: * lib/Smokeping.pm, lib/Smokeping/probes/base.pm, doc/smokeping_upgrade.pod, TODO, CHANGES: + the DYNAMIC-related files (.adr and .snmp) can now be located outside "datadir" by specifying the new configuration variable "dyndir" --- lib/Smokeping.pm | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index 18415f4..a14699f 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -110,6 +110,11 @@ sub lnk ($$) { } } +sub dyndir ($) { + my $cfg = shift; + return $cfg->{General}{dyndir} || $cfg->{General}{datadir}; +} + sub update_dynaddr ($$){ my $cfg = shift; my $q = shift; @@ -125,7 +130,12 @@ sub update_dynaddr ($$){ return "Error: Invalid target or secret" unless defined $targetptr->{host} and $targetptr->{host} eq "DYNAMIC/${secret}"; - my $file = $cfg->{General}{datadir}."/".(join "/", @target); + my $file = dyndir($cfg); + for (0..$#target-1) { + $file .= "/" . $target[$_]; + ( -d $file ) || mkdir $file, 0755; + } + $file.= "/" . $target[-1]; my $prevaddress = "?"; my $snmp = snmpget_ident $address; if (-r "$file.adr" and not -z "$file.adr"){ @@ -852,7 +862,7 @@ sub get_detail ($$$$){ ); # if we have uptime draw a colorful background or the graph showing the uptime - my $cdir=$cfg->{General}{datadir}."/".(join "/", @dirs)."/"; + my $cdir=dyndir($cfg)."/".(join "/", @dirs)."/"; if (-f "$cdir/${file}.adr") { @upsmoke = (); @upargs = ("COMMENT:Link Up${BS}: ", @@ -1567,7 +1577,7 @@ DOC General configuration values valid for the whole SmokePing setup. DOC _vars => - [ qw(owner imgcache imgurl datadir pagedir piddir sendmail offset + [ qw(owner imgcache imgurl datadir dyndir pagedir piddir sendmail offset smokemail cgiurl mailhost contact netsnpp syslogfacility syslogpriority concurrentprobes changeprocessnames tmail) ], _mandatory => @@ -1637,7 +1647,16 @@ DOC The directory where SmokePing can keep its rrd files. DOC }, + dyndir => + { + %$DIRCHECK_SUB, + _doc => < will be used instead. +DOC + }, piddir => { %$DIRCHECK_SUB, -- cgit v1.2.3-24-g4f1b From 0fb4bc74b24ea96e80d4e27428b8c2451fbf0eb5 Mon Sep 17 00:00:00 2001 From: Niko Tyni Date: Sun, 4 Sep 2005 11:40:42 +0000 Subject: * lib/Smokeping.pm, CHANGES: + don't create directories in "datadir" when running as a CGI --- lib/Smokeping.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Smokeping.pm') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index a14699f..28923e7 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -363,7 +363,7 @@ sub init_target_tree ($$$$) { foreach my $prop (keys %{$tree}) { if (ref $tree->{$prop} eq 'HASH'){ - if (not -d $name) { + if (not -d $name and not $cgimode) { mkdir $name, 0755 or die "ERROR: mkdir $name: $!\n"; }; init_target_tree $cfg, $probes, $tree->{$prop}, "$name/$prop"; -- cgit v1.2.3-24-g4f1b