import argparse
import logging
+import os
+import signal
import time
import misc
-MAX_LINES = 10
+LINES_TO_KEEP = 10
ALERT_INTERVAL = 86400
-logging.basicConfig(format='[%(asctime)s] %(levelname)s: %(message)s',
- level=logging.INFO,
- datefmt='%m/%d/%Y %H:%M:%S')
+def handleInterrupt(sig, frame):
+ global stop
+ if os.getpid() == mainPid:
+ logging.info( "Got stop signal." )
+ stop = True
+
+mainPid = os.getpid()
+signal.signal(signal.SIGINT, handleInterrupt)
+
+stop = False
parser = argparse.ArgumentParser(description='Alert on excessive number of error log lines.')
parser.add_argument('logfile', type=str, help='logfile to be watched')
help='sample interval size in seconds (default: 600)')
parser.add_argument('-n', '--num-intervals', type=int, default=6, dest='num_intervals',
help='number of intervals to keep in history (default: 6)')
+parser.add_argument('-l', '--log-level', type=str, default='INFO', dest='log_lvl',
+ choices=['DEBUG', 'INFO', 'WARNING'], help='select log level')
args = parser.parse_args()
-kept_times = []
+logging.basicConfig(format='[%(asctime)s] %(levelname)s: %(message)s',
+ level=logging.getLevelName(args.log_lvl),
+ datefmt='%m/%d/%Y %H:%M:%S')
+
+num_intervals = (args.num_intervals + 1)
+intervals = [False] * num_intervals
lines = []
-last_slot_time = None
+last_time_slot = 0
+interval_ptr = 0
error_state = False
last_alert_time = 0
for line in misc.follow_file(args.logfile):
time_now = time.time()
- slot_now = int(time_now) // args.interval_size
+ time_slot = int(time_now) // args.interval_size
+ time_slot_diff = time_slot - last_time_slot
+ last_time_slot = time_slot
+
+ interval_ptr = (interval_ptr + time_slot_diff) % num_intervals
+ for i in range(0, min(num_intervals, time_slot_diff)):
+ intervals[(interval_ptr + i ) % num_intervals] = False
- if line != None:
- if not last_slot_time or slot_now > last_slot_time:
- kept_times.append(slot_now)
- last_slot_time = slot_now
+ if line:
+ intervals[interval_ptr] = True
lines.append(line)
- if len(lines) > MAX_LINES:
+ if len(lines) > LINES_TO_KEEP:
lines.pop(0)
- while len(kept_times) > 0 and \
- kept_times[0] <= slot_now - (args.num_intervals + 1):
- kept_times.pop(0)
+ logging.debug( misc.print_list(intervals, interval_ptr) )
- intervals = [False] * (args.num_intervals + 1)
- for kept_time in kept_times:
- intervals[slot_now - kept_time] = True
+ intervals_error_state = True
+ for i in range(1, num_intervals):
+ if not intervals[(interval_ptr + i) % num_intervals]:
+ intervals_error_state = False
+ break
- logging.debug(intervals)
-
- if not False in intervals[1:]:
+ if intervals_error_state:
if not error_state or time_now - last_alert_time > ALERT_INTERVAL:
last_alert_time = time_now
misc.feed_handler( args.handler,
misc.create_msg("Log Alert",
"☠",
args.logfile,
- "Number of errors exceeded!",
lines) )
if not error_state:
logging.warning("Entering error state!")
if error_state:
logging.info("Leaving error state.")
error_state = False
+
+ if stop:
+ break