3
# monitor host reboots via SNMP
9
# reboot.monitor --statefile=filename --dir=dir host1 host2...
11
# Since this is scheduled from mon, it must maintain state between
12
# runs. It uses the "statefile" for this, in which it stores a
13
# sysUpTime sample for each host specified on the command line.
15
# THIS STATE FILE MUST NOT BE SHARED BETWEEN MULTIPLE INSTANCES OF THIS
16
# MONITOR, SINCE IT DOES NOT HANDLE LOCKING OF THE FILE DURING UPDATES!!
20
# $Id: reboot.monitor 1.3 Mon, 25 Jun 2001 12:05:08 -0400 trockij $
22
# Copyright (C) 1998, Jim Trocki
24
# This program is free software; you can redistribute it and/or modify
25
# it under the terms of the GNU General Public License as published by
26
# the Free Software Foundation; either version 2 of the License, or
27
# (at your option) any later version.
29
# This program is distributed in the hope that it will be useful,
30
# but WITHOUT ANY WARRANTY; without even the implied warranty of
31
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32
# GNU General Public License for more details.
34
# You should have received a copy of the GNU General Public License
35
# along with this program; if not, write to the Free Software
36
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
39
# modified June 2000 by Ed Ravin <eravin@panix.com>
40
# changed output to conform with other monitors (just hostname on summary)
41
# minor cosmetic changes (usage, use default Mon state dir)
42
# the old behavior still available with the "--verbose" option
47
($ME = $0) =~ s-.*/--;
49
GetOptions (\%opt, "statefile=s", "dir=s", "verbose");
51
$STATEDIR = $opt{"dir"} ? $opt{"dir"}
52
: $ENV{"MON_STATEDIR"} ? $ENV{"MON_STATEDIR"}
53
: die "$ME: --dir not specified and \$MON_STATEDIR not set\n";
55
$STATEFILE = $opt{"statefile"} || $ME;
57
$STATE = "$STATEDIR/$STATEFILE";
59
die "$ME: reboot state dir $STATEDIR does not exist\n"
62
$VERBOSE= $opt{"verbose"} || 0;
64
die "$ME: no host arguments\n" if (@ARGV == 0);
74
if (!open (IN, "$STATE")) {
75
die "$ME: could not open state file $STATE\n";
78
while (defined ($host = <IN>)) {
79
if ($host =~ /^(\S+) (\d+) (\d+)/) {
80
$last_sample{$1}{"uptime"} = $2;
81
$last_sample{$1}{"lastcheck"} = $3;
87
# get uptime for each host via SNMP
91
foreach $host (@ARGV) {
92
if (!defined($s = new SNMP::Session (DestHost => $host))) {
93
print "reboot.monitor: cannot create SNMP session to $host\n";
97
if (!defined($u = $s->get("sysUpTime.0"))) {
102
# If the uptime is lower than the last sample,
103
# assume this is a reboot. Note that this cannot
104
# account for counter rollover!
108
# no history for this
110
if (!defined $last_sample{$host}{"uptime"}) {
112
} elsif ($u < $last_sample{$host}{"uptime"}) {
113
push (@failures, $host);
114
$last_sample{$host}{"olduptime"} = $last_sample{$host}{"uptime"};
115
$last_sample{$host}{"oldcheck"} = $last_sample{$host}{"lastcheck"};
118
$last_sample{$host}{"uptime"} = $u;
119
$last_sample{$host}{"lastcheck"} = time;
125
if (!open (OUT, ">$STATE")) {
126
die "$ME: could not open $STATEFILE for writing: $!\n";
129
foreach $k (sort keys %last_sample) {
130
print OUT "$k $last_sample{$k}{uptime} $last_sample{$k}{lastcheck}\n";
136
# all is OK, nobody has rebooted
138
if (@failures == 0) {
143
# we have reboots, so calculate uptime, downtime,
147
foreach $host (@failures) {
148
$downtime = &secs_to_hms (
149
$t - $last_sample{$host}{"oldcheck"} -
150
int ($last_sample{$host}{"uptime"} / 100));
151
$uptime = &secs_to_hms (
152
int ($last_sample{$host}{"olduptime"} / 100));
155
push (@f, "$host / down $downtime / up $uptime");
166
printf ("%-20s %-25s %-25s\n", "host", "rebooted on", "last seen up on");
167
printf ("%-20s %-25s %-25s\n", "-" x 20, "-" x 25, "-" x 25);
171
foreach $host (@failures) {
172
$secs = int($last_sample{$host}{"uptime"} / 100);
173
$t = localtime ($timen - $secs);
174
$downtime= localtime($last_sample{$host}{"oldcheck"} - ($last_sample{$host}{"uptime"} / 100) );
175
printf ("%-20s %-25s %-25s\n", $host, $t, $downtime);
183
my ($dd, $hh, $mm, $ss);
185
$dd = int ($s / 86400);
188
$hh = int ($s / 3600);
197
sprintf("%02d:%02d", $hh, $mm);
199
sprintf("%d days, %02d:%02d", $dd, $hh, $mm);