1 | 1 | simandl | #!/usr/bin/env perl |
2 | | | |
3 | | | my $NAME="warnings.pl"; |
4 | | | |
5 | | | # check commandline arguments |
6 | | | # |
7 | | | my $cmd=shift; |
8 | | | if ($cmd eq "-p") { print_rows(@ARGV); } |
9 | | | elsif ($cmd eq "-c") { check_thresholds(@ARGV); } |
10 | | | else { helptext(); exit; } |
11 | | | |
12 | | | sub check_thresholds { |
13 | | | if ( ($#ARGV != 6) && ($#ARGV != 11) ) { |
14 | | | print "\nUSAGE: $NAME -c <module> <database> <row> <consolidation> <timespan> <lt|eq|gt> <threshold> [-m <> <> <> <>]\n\n"; |
15 | | | exit; |
16 | | | } |
17 | | | $module=shift; |
18 | | | $db=shift; |
19 | | | $row=shift; |
20 | | | $consolidation=shift; |
21 | | | $time=shift; |
22 | | | $func=shift; |
23 | | | $threshold=shift; |
24 | | | |
25 | | | |
26 | | | open LINES,"rrdtool fetch ./modules/$module/rrd/$db.rrd -s -$time $consolidation|"; |
27 | | | @lines=<LINES>; |
28 | | | close LINES; |
29 | | | |
30 | | | print @lines; |
31 | | | |
32 | | | $caught=0; |
33 | | | $num=-1; |
34 | | | $vmin=999999999999999999; |
35 | | | $vmax=0; |
36 | | | |
37 | | | if ($func eq "gt") { $function="higher than"; } |
38 | | | elsif ($func eq "eq") { $function="equal"; } |
39 | | | elsif ($func eq "lt") { $function="lower than"; } |
40 | | | |
41 | | | foreach (@lines) { |
42 | | | # first line contains data-row names |
43 | | | if ($num == -1) { |
44 | | | chomp; |
45 | | | @names=split; |
46 | | | $num++; |
47 | | | next; |
48 | | | } |
49 | | | if ((! /nan/) && ( /:/)) { |
50 | | | # process lines containing valid values |
51 | | | chomp; |
52 | | | $num++; |
53 | | | @items=split; |
54 | | | $val=@items[$row]; |
55 | | | $vsum+=$val; |
56 | | | $vmin=$val if $vmin>$val; |
57 | | | $vmax=$val if $vmax<$val; |
58 | | | if (($func eq "gt") && ($val>$threshold)) { $caught++; } |
59 | | | elsif (($func eq "eq") && ($val==$threshold)) { $caught++; } |
60 | | | elsif (($func eq "lt") && ($val<$threshold)) { $caught++; } |
61 | | | } |
62 | | | } |
63 | | | |
64 | | | # check if there was at least one valid line |
65 | | | if ($num > 0) { $vavg=$vsum/$num; } else { $vavg=-1; $num=-1; } |
66 | | | |
67 | | | if ($num == $caught) { |
68 | | | my @message; |
69 | | | ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); |
70 | | | $year+=1900; |
71 | | | $mon++; |
72 | | | $dow=("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday")[$wday]; |
73 | | | if ($isdst) { $dst="(DST)"; } else { $dst=""; } |
74 | | | $mday="0".$mday if $mday<10; |
75 | | | $mon="0".$mon if $mon<10; |
76 | | | $sec="0".$sec if $sec<10; |
77 | | | $min="0".$min if $min<10; |
78 | | | $hour="0".$hour if $hour<10; |
79 | | | |
80 | | | my @message=("HotSaNIC THRESHOLD WARNING!","","Date : $dow, $year-$mon-$mday","Time : $hour:$min:$sec $dst","Module : $module","database: $db","data-row: ".@names[$row-1],"","","$consolidation value constantly $function $threshold over the last $time seconds.",(sprintf "minimum: %12.2f",$vmin),(sprintf "average: %12.2f",$vavg),(sprintf "maximum: %12.2f",$vmax),""); |
81 | | | |
82 | | | $cmd=shift; |
83 | | | if ($cmd eq "-m") { |
84 | | | print "sending...\n"; |
85 | | | sendmail(@_,@message); |
86 | | | } |
87 | | | else { print join("\n",@message),"\n"; } |
88 | | | } |
89 | | | } |
90 | | | |
91 | | | sub print_rows { |
92 | | | if ($#ARGV != 1) { |
93 | | | print "\nUSAGE: $NAME -p <module> <database>\n\n"; |
94 | | | exit; |
95 | | | } |
96 | | | $module=shift; |
97 | | | $db=shift; |
98 | | | open LINES,"rrdtool fetch ./modules/$module/rrd/$db.rrd -s -1 MAX|"; |
99 | | | ( $line=<LINES> ) =~ s/^\s*//g; |
100 | | | close LINES; |
101 | | | $n=1; |
102 | | | print "Row numbers for $module - $db.rrd\n"; |
103 | | | foreach (split /\s+/,$line) { print $n++." -> $_\n"; } |
104 | | | exit; |
105 | | | } |
106 | | | |
107 | | | |
108 | | | sub sendmail { |
109 | | | use Net::SMTP; |
110 | | | |
111 | | | my $SMTP_Host = shift || ""; |
112 | | | my $account = shift || "dummy"; |
113 | | | my $sender = shift || "hotsanic-system"; |
114 | | | my $recipient = shift || "admin"; |
115 | | | my @message = (@_); |
116 | | | unshift @message,"From: HotSaNIC <$sender>",""; |
117 | | | unshift @message,"Subject: HotSaNIC threshold warning"; |
118 | | | |
119 | | | # add line-breaks (\r\n) to text |
120 | | | @message = map { $_."\r\n" } @message; |
121 | | | |
122 | | | my $smtp = Net::SMTP->new( $SMTP_Host, Helo => $account, Debug => 0 ); |
123 | | | my $OK; |
124 | | | |
125 | | | $OK = $smtp->mail($sender); |
126 | | | if (! $OK) { return "ERROR: sender unknown: \"$sender\""; } |
127 | | | |
128 | | | $OK = $smtp->recipient( $recipient ); |
129 | | | if (! $OK) { return "ERROR: recipient invalid: \"$recipient\""; } |
130 | | | |
131 | | | # Nachricht senden |
132 | | | $OK = $smtp->data(\@message); |
133 | | | if (! $OK) { return "ERROR: message could not be delivered: \"$!\""; } |
134 | | | |
135 | | | # Ordungsgemäss beim Server abmelden |
136 | | | $OK = $smtp->quit(); |
137 | | | if (! $OK) { return "ERROR: could not close connection.\"$!\""; } |
138 | | | } |
139 | | | |
140 | | | |
141 | | | sub helptext { |
142 | | | print " |
143 | | | USAGE: |
144 | | | |
145 | | | $NAME -c <module> <database> <row> <consolidation> <timespan> <lt|eq|gt> <threshold> |
146 | | | check the given database for given events and print results to running shell. |
147 | | | |
148 | | | $NAME -p <module> <database> |
149 | | | print DB-internal names. |
150 | | | |
151 | | | $NAME -c ... -m <SMTPhost> <SMTPaccount> <sender> <recipient> |
152 | | | mails the results in the given way |
153 | | | |
154 | | | $NAME -f config_file |
155 | | | check all targets configured in config_file. (not implemented yet!) |
156 | | | |
157 | | | |
158 | | | <module> name of the module to query (you have to be in the HotSaNIC main directory) |
159 | | | |
160 | | | <database> name of the database to query |
161 | | | |
162 | | | <data-row-number> number of the database-row |
163 | | | \"?\" to show row names |
164 | | | |
165 | | | [MAX|MIN|AVERAGE] consolidation function of the data-row you like to query |
166 | | | |
167 | | | <timespan> timespan backwards from now in seconds |
168 | | | |
169 | | | [lt|eq|gt] threshold functions |
170 | | | lt -> test if values are less than <threshold> |
171 | | | eq -> test if values are equal <threshold> |
172 | | | gt -> test if values are greater than <threshold> |
173 | | | |
174 | | | <threshold> threshold value |
175 | | | |
176 | | | example: |
177 | | | |
178 | | | $NAME -c traffic eth0 1 MAX 120 gt 100000 |
179 | | | generates a warning message if the incoming traffic (row 1) of the traffic on eth0 exceeded 100000 bytes/s over the last 2 minutes |
180 | | | |
181 | | | $NAME -c system cpu 4 MAX 120 lt 0.3 |
182 | | | generates a warning message if the idle-time (row 4) of your CPU was constantly lower than 30% over the last 2 minutes |
183 | | | \n"; |
184 | | | } |
185 | | | |