17 with open(filename, "r") as f:
18 logging.info("Re-attached to log file.")
23 if not os.path.exists(filename):
29 yield line.rstrip("\n")
30 except FileNotFoundError:
34 def feed_handler(data):
36 handler = subprocess.Popen(shlex.split(args.handler),
37 stdin=subprocess.PIPE,
38 stdout=subprocess.PIPE,
39 stderr=subprocess.PIPE,
41 out_data, err_data = handler.communicate("%s\n" % data)
42 if handler.returncode != 0:
43 logging.warning("Handler exited with non-zero return code %d! (%s)" %
44 (handler.returncode, err_data))
45 except Exception as e:
46 logging.error("Error feeding handler: %s" % str(e))
48 def create_msg(title, icon, logfile, text, lines):
49 msg = "<b>%s</b> <i>%s</i> %s" % (title, logfile, icon)
50 msg += "<br>%s" % text
52 for line in lines: msg += line + "\n"
56 logging.basicConfig(format='[%(asctime)s] %(levelname)s: %(message)s',
58 datefmt='%m/%d/%Y %H:%M:%S')
60 parser = argparse.ArgumentParser(description='Alert on excessive number of error log lines.')
61 parser.add_argument('logfile', type=str, help='logfile to be watched')
62 parser.add_argument('handler', type=str,
63 help='alert will be delivered to standard input of handler')
64 parser.add_argument('-s', '--interval-size', type=int, default=600, dest='interval_size',
65 help='sample interval size in seconds (default: 600)')
66 parser.add_argument('-n', '--num-intervals', type=int, default=6, dest='num_intervals',
67 help='number of intervals to keep in history (default: 6)')
69 args = parser.parse_args()
76 for line in follow(args.logfile):
77 now = int(time.time()) // args.interval_size
80 if not last_time or now > last_time:
81 kept_times.append(now)
84 if len(lines) > MAX_LINES:
87 while len(kept_times) > 0 and \
88 kept_times[0] <= now - args.num_intervals:
91 intervals = [False] * args.num_intervals
92 for kept_time in kept_times:
93 intervals[now - kept_time] = True
95 logging.debug(intervals)
97 if not False in intervals:
99 logging.warning("Entering error state!")
101 feed_handler( create_msg("Log Alert",
104 "Number of errors exceeded!",
108 logging.info("Leaving error state.")
110 feed_handler( create_msg("Log Un-Alert",
113 "Log is back to normal.",