From 6ab1d132344f333dc12623b521fb101e9430c8fa Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Thu, 21 Sep 2006 20:55:45 +0000 Subject: [PATCH] - Fixed log rotation bug - Refactoring git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/trunk@376 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- server/filter.py | 108 ++++++++++++++++++++++++------------------ server/filtergamin.py | 29 ++++-------- server/filterpoll.py | 41 +++++++--------- 3 files changed, 90 insertions(+), 88 deletions(-) diff --git a/server/filter.py b/server/filter.py index 79b40eaf..62825212 100644 --- a/server/filter.py +++ b/server/filter.py @@ -56,25 +56,23 @@ class Filter(JailThread): self.jail = jail ## The failures manager. self.failManager = FailManager() - ## The log file handler. - self.crtHandler = None - self.crtFilename = None - ## The log file path. - self.logPath = [] - ## The regular expression matching the failure. - self.failRegex = '' - self.failRegexObj = None - ## The amount of time to look back. - self.findTime = 6000 - ## The ignore IP list. - self.ignoreIpList = [] self.modified = False - ## The time of the last modification of the file. - self.lastModTime = dict() + ## The log file handler. + self.__crtHandler = None + self.__crtFilename = None + ## The log file path. + self.__logPath = [] + ## The regular expression matching the failure. + self.__failRegex = '' + self.__failRegexObj = None + ## The amount of time to look back. + self.__findTime = 6000 + ## The ignore IP list. + self.__ignoreIpList = [] ## The last position of the file. - self.lastPos = dict() + self.__lastPos = dict() ## The last date in tht log file. - self.lastDate = dict() + self.__lastDate = dict() self.dateDetector = DateDetector() self.dateDetector.addDefaultTemplate() @@ -87,7 +85,10 @@ class Filter(JailThread): # @param path log file path def addLogPath(self, path): - raise Exception("addLogPath() is abstract") + self.getLogPath().append(path) + # Initialize default values + self.__lastDate[path] = 0 + self.__lastPos[path] = 0 ## # Delete a log path @@ -95,7 +96,9 @@ class Filter(JailThread): # @param path the log file to delete def delLogPath(self, path): - raise Exception("delLogPath() is abstract") + self.getLogPath().remove(path) + del self.__lastDate[path] + del self.__lastPos[path] ## # Get the log file path @@ -103,7 +106,20 @@ class Filter(JailThread): # @return log file path def getLogPath(self): - return self.logPath + return self.__logPath + + ## + # Check whether path is already monitored. + # + # @param path The path + # @return True if the path is already monitored else False + + def containsLogPath(self, path): + try: + self.getLogPath().index(path) + return True + except ValueError: + return False ## # Set the regular expression which matches the time. @@ -147,8 +163,8 @@ class Filter(JailThread): # @param value the regular expression def setFailRegex(self, value): - self.failRegex = value - self.failRegexObj = re.compile(value) + self.__failRegex = value + self.__failRegexObj = re.compile(value) logSys.info("Set failregex = %s" % value) ## @@ -157,7 +173,7 @@ class Filter(JailThread): # @return the regular expression def getFailRegex(self): - return self.failRegex + return self.__failRegex ## # Set the time needed to find a failure. @@ -167,7 +183,7 @@ class Filter(JailThread): # @param value the time def setFindTime(self, value): - self.findTime = value + self.__findTime = value logSys.info("Set findtime = %s" % value) ## @@ -176,7 +192,7 @@ class Filter(JailThread): # @return the time def getFindTime(self): - return self.findTime + return self.__findTime ## # Set the maximum retry value. @@ -232,16 +248,16 @@ class Filter(JailThread): def addIgnoreIP(self, ip): if DNSUtils.isValidIP(ip): logSys.debug("Add " + ip + " to ignore list") - self.ignoreIpList.append(ip) + self.__ignoreIpList.append(ip) else: logSys.warn(ip + " is not a valid address") def delIgnoreIP(self, ip): logSys.debug("Remove " + ip + " from ignore list") - self.ignoreIpList.remove(ip) + self.__ignoreIpList.remove(ip) def getIgnoreIP(self): - return self.ignoreIpList + return self.__ignoreIpList ## # Check if IP address is in the ignore list. @@ -252,7 +268,7 @@ class Filter(JailThread): # @return True if IP address is in ignore list def inIgnoreIPList(self, ip): - for i in self.ignoreIpList: + for i in self.__ignoreIpList: s = i.split('/', 1) # IP address without CIDR mask if len(s) == 1: @@ -274,8 +290,8 @@ class Filter(JailThread): """ Opens the log file specified on init. """ try: - self.crtFilename = filename - self.crtHandler = open(filename) + self.__crtFilename = filename + self.__crtHandler = open(filename) logSys.debug("Opened " + filename) return True except OSError: @@ -289,8 +305,8 @@ class Filter(JailThread): # Close the log file. def __closeLogFile(self): - self.crtFilename = None - self.crtHandler.close() + self.__crtFilename = None + self.__crtHandler.close() ## # Set the file position. @@ -300,23 +316,25 @@ class Filter(JailThread): # timestamp in order to detect this. def __setFilePos(self): - line = self.crtHandler.readline() - lastDate = self.lastDate[self.crtFilename] + line = self.__crtHandler.readline() + lastDate = self.__lastDate[self.__crtFilename] lineDate = self.dateDetector.getUnixTime(line) + print lastDate + print lineDate if lastDate < lineDate: logSys.debug("Date " + `lastDate` + " is smaller than " + `lineDate`) - logSys.debug("Log rotation detected for " + self.crtFilename) - self.lastPos[self.crtFilename] = 0 - lastPos = self.lastPos[self.crtFilename] + logSys.debug("Log rotation detected for " + self.__crtFilename) + self.__lastPos[self.__crtFilename] = 0 + lastPos = self.__lastPos[self.__crtFilename] logSys.debug("Setting file position to " + `lastPos` + " for " + - self.crtFilename) - self.crtHandler.seek(lastPos) + self.__crtFilename) + self.__crtHandler.seek(lastPos) ## # Get the file position. def __getFilePos(self): - return self.crtHandler.tell() + return self.__crtHandler.tell() ## # Gets all the failure in the log file. @@ -333,7 +351,7 @@ class Filter(JailThread): return False self.__setFilePos() lastLine = None - for line in self.crtHandler: + for line in self.__crtHandler: try: # Try to convert UTF-8 string to Latin-1 #line = line.decode('utf-8').encode('latin-1') @@ -349,16 +367,16 @@ class Filter(JailThread): for element in self.findFailure(line): ip = element[0] unixTime = element[1] - if unixTime < time.time()-self.findTime: + if unixTime < time.time()-self.__findTime: break if self.inIgnoreIPList(ip): logSys.debug("Ignore "+ip) continue logSys.debug("Found "+ip) self.failManager.addFailure(FailTicket(ip, unixTime)) - self.lastPos[filename] = self.__getFilePos() + self.__lastPos[filename] = self.__getFilePos() if lastLine: - self.lastDate[filename] = self.dateDetector.getTime(lastLine) + self.__lastDate[filename] = self.dateDetector.getUnixTime(lastLine) self.__closeLogFile() return True @@ -371,7 +389,7 @@ class Filter(JailThread): def findFailure(self, line): failList = list() - match = self.failRegexObj.search(line) + match = self.__failRegexObj.search(line) if match: date = self.dateDetector.getUnixTime(match.string) if date <> None: diff --git a/server/filtergamin.py b/server/filtergamin.py index 66f7d30c..670518ee 100644 --- a/server/filtergamin.py +++ b/server/filtergamin.py @@ -71,17 +71,12 @@ class FilterGamin(Filter): # @param path log file path def addLogPath(self, path): - try: - self.getLogPath().index(path) + if self.containsLogPath(path): logSys.error(path + " already exists") - except ValueError: + else: self.monitor.watch_file(path, self.callback) - self.getLogPath().append(path) - # Initialize default values - self.lastDate[path] = 0 - self.lastModTime[path] = 0 - self.lastPos[path] = 0 - logSys.info("Added logfile = %s" % path) + Filter.addLogPath(self, path) + logSys.info("Added logfile = %s" % path) ## # Delete a log path @@ -89,17 +84,13 @@ class FilterGamin(Filter): # @param path the log file to delete def delLogPath(self, path): - try: - self.monitor.stop_watch(path) - self.getLogPath().remove(path) - del self.lastDate[path] - del self.lastModTime[path] - del self.lastPos[path] - logSys.info("Removed logfile = %s" % path) - except ValueError: + if not self.containsLogPath(path): logSys.error(path + " is not monitored") - - + else: + self.monitor.stop_watch(path) + Filter.delLogPath(self, path) + logSys.info("Removed logfile = %s" % path) + ## # Main loop. # diff --git a/server/filterpoll.py b/server/filterpoll.py index 3b5ad8c7..0950046d 100644 --- a/server/filterpoll.py +++ b/server/filterpoll.py @@ -52,9 +52,9 @@ class FilterPoll(Filter): def __init__(self, jail): Filter.__init__(self, jail) - + ## The time of the last modification of the file. + self.__lastModTime = dict() self.__file404Cnt = dict() - logSys.info("Created FilterPoll") ## @@ -63,17 +63,13 @@ class FilterPoll(Filter): # @param path log file path def addLogPath(self, path): - try: - self.getLogPath().index(path) + if self.containsLogPath(path): logSys.error(path + " already exists") - except ValueError: - self.getLogPath().append(path) - # Initialize default values - self.lastDate[path] = 0 - self.lastModTime[path] = 0 - self.lastPos[path] = 0 + else: + self.__lastModTime[path] = 0 self.__file404Cnt[path] = 0 - logSys.info("Added logfile = %s" % path) + Filter.addLogPath(self, path) + logSys.info("Added logfile = %s" % path) ## # Delete a log path @@ -81,16 +77,13 @@ class FilterPoll(Filter): # @param path the log file to delete def delLogPath(self, path): - try: - self.getLogPath().remove(path) - del self.lastDate[path] - del self.lastModTime[path] - del self.lastPos[path] - del self.__file404Cnt[path] - logSys.info("Removed logfile = %s" % path) - except ValueError: + if not self.containsLogPath(path): logSys.error(path + " is not monitored") - + else: + del self.__lastModTime[path] + del self.__file404Cnt[path] + Filter.delLogPath(self, path) + logSys.info("Removed logfile = %s" % path) ## # Main loop. @@ -107,7 +100,7 @@ class FilterPoll(Filter): for file in self.getLogPath(): if self.isModified(file): self.getFailures(file) - prevModified = True + self.modified = True if self.modified: try: @@ -116,7 +109,7 @@ class FilterPoll(Filter): except FailManagerEmpty: self.failManager.cleanup(time.time()) self.dateDetector.sortTemplate() - prevModified = False + self.modified = False time.sleep(self.getSleepTime()) else: time.sleep(self.getSleepTime()) @@ -133,11 +126,11 @@ class FilterPoll(Filter): try: logStats = os.stat(filename) self.__file404Cnt[filename] = 0 - if self.lastModTime[filename] == logStats.st_mtime: + if self.__lastModTime[filename] == logStats.st_mtime: return False else: logSys.debug(filename + " has been modified") - self.lastModTime[filename] = logStats.st_mtime + self.__lastModTime[filename] = logStats.st_mtime return True except OSError: logSys.error("Unable to get stat on " + filename)