From a0807122264b80546cae7069b1e643de265ceb0b Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 21 Sep 2012 00:55:59 +0200 Subject: Added support for time-frame variable in [Rule:* sections] This optional variable extends the threshold trigger to require the matching rule to have a hit within the given time-frame. If threshold is set to 3 and time-frame to 10, it must be 3 events within 10 seconds for this rule to cause an action. Signed-off-by: David Sommerseth --- LogActio/__init__.py | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/LogActio/__init__.py b/LogActio/__init__.py index 3a501ab..4a2b523 100644 --- a/LogActio/__init__.py +++ b/LogActio/__init__.py @@ -43,11 +43,13 @@ class WatcherThread(threading.Thread): return self.__logfile - def AddRule(self, prefix, regex, threshold, reporters): + def AddRule(self, prefix, regex, threshold, timeframe, reporters): # Adds a rule specific for this log file rule = {"prefix": prefix, "regex": re.compile(regex), "threshold": int(threshold), + "timeframe": timeframe and int(timeframe) or None, + "lastseen": 0, "current_count": 0, "alerts_sent": 0, "reporters": reporters} @@ -86,14 +88,19 @@ class WatcherThread(threading.Thread): fp.seek(where) continue + now = int(time.time()) for alert in self.__rules: m = alert["regex"].match(line.splitlines()[0]) # If the received log line matches the regex if not self.__shutdown and m: alert["current_count"] += 1 - # If the threshold has been reached, report the incident - if alert["threshold"] == 0 or (alert["current_count"] % alert["threshold"] == 0): + # If the threshold has been reached and within the given time frame, + # report the incident + if (alert["threshold"] == 0 + or ((alert["current_count"] % alert["threshold"] == 0) + and (alert["timeframe"] is None + or now <= (alert["lastseen"] + alert["timeframe"])))): alert["alerts_sent"] += 1 info = "|".join(m.groups()) # Gather regex exctracted info if len(info) == 0: @@ -105,6 +112,16 @@ class WatcherThread(threading.Thread): for r in rep: r.ProcessEvent(self.__logfile, alert["prefix"], info, alert["current_count"], alert["threshold"]) + alert["lastseen"] = 0 + continue + + if (alert["timeframe"] and (alert["lastseen"] > 0) + and (now >= (alert["lastseen"] + alert["timeframe"]))): + # If the time-frame have timed out, reset it + alert["lastseen"] = 0 + else: + alert["lastseen"] = now + fp.close() return 0 @@ -296,6 +313,8 @@ class LogActio(object): self.__watchthreads[idx].AddRule(rulename, self.__cfg.get(entry, "regex"), self.__cfg.get(entry, "threshold"), + (self.__cfg.has_option(entry, "time-frame") + and self.__cfg.get(entry, "time-frame") or None), rulereps) if rulereps is not None and len(rulereps) > 0: self.__log(3, "Rule reporters prepared: [%s] => %s" % -- cgit