12 ALERT_INTERVAL = 86400
14 def handleInterrupt(sig, frame):
16 if os.getpid() == mainPid:
17 logging.info( "Got stop signal." )
21 signal.signal(signal.SIGINT, handleInterrupt)
25 parser = argparse.ArgumentParser(description='Alert on excessive number of error log lines.')
26 parser.add_argument('logfile', type=str, help='logfile to be watched')
27 parser.add_argument('handler', type=str,
28 help='alert will be delivered to standard input of handler')
29 parser.add_argument('-s', '--interval-size', type=int, default=600, dest='interval_size',
30 help='sample interval size in seconds (default: 600)')
31 parser.add_argument('-n', '--num-intervals', type=int, default=6, dest='num_intervals',
32 help='number of intervals to keep in history (default: 6)')
33 parser.add_argument('-l', '--log-level', type=str, default='INFO', dest='log_lvl',
34 choices=['DEBUG', 'INFO', 'WARNING'], help='select log level')
36 args = parser.parse_args()
38 logging.basicConfig(format='[%(asctime)s] %(levelname)s: %(message)s',
39 level=logging.getLevelName(args.log_lvl),
40 datefmt='%m/%d/%Y %H:%M:%S')
42 num_intervals = (args.num_intervals + 1)
43 intervals = [False] * num_intervals
50 for line in misc.follow_file(args.logfile):
51 time_now = time.time()
52 time_slot = int(time_now) // args.interval_size
53 time_slot_diff = time_slot - last_time_slot
54 last_time_slot = time_slot
56 interval_ptr = (interval_ptr + time_slot_diff) % num_intervals
57 for i in range(0, min(num_intervals, time_slot_diff)):
58 intervals[(interval_ptr + i ) % num_intervals] = False
61 intervals[interval_ptr] = True
63 if len(lines) > LINES_TO_KEEP:
66 logging.debug( misc.print_list(intervals, interval_ptr) )
68 intervals_error_state = True
69 for i in range(1, num_intervals):
70 if not intervals[(interval_ptr + i) % num_intervals]:
71 intervals_error_state = False
74 if intervals_error_state:
75 if not error_state or time_now - last_alert_time > ALERT_INTERVAL:
76 last_alert_time = time_now
77 misc.feed_handler( args.handler,
78 misc.create_msg("Log Alert",
81 "Number of errors exceeded!",
84 logging.warning("Entering error state!")
89 logging.info("Leaving error state.")