- Fixed log rotation bug

- Refactoring

git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/trunk@376 a942ae1a-1317-0410-a47c-b1dcaea8d605
0.x
Cyril Jaquier 2006-09-21 20:55:45 +00:00
parent d61690fd9e
commit 6ab1d13234
3 changed files with 90 additions and 88 deletions

View File

@ -56,25 +56,23 @@ class Filter(JailThread):
self.jail = jail self.jail = jail
## The failures manager. ## The failures manager.
self.failManager = FailManager() 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 self.modified = False
## The time of the last modification of the file. ## The log file handler.
self.lastModTime = dict() 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. ## The last position of the file.
self.lastPos = dict() self.__lastPos = dict()
## The last date in tht log file. ## The last date in tht log file.
self.lastDate = dict() self.__lastDate = dict()
self.dateDetector = DateDetector() self.dateDetector = DateDetector()
self.dateDetector.addDefaultTemplate() self.dateDetector.addDefaultTemplate()
@ -87,7 +85,10 @@ class Filter(JailThread):
# @param path log file path # @param path log file path
def addLogPath(self, 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 # Delete a log path
@ -95,7 +96,9 @@ class Filter(JailThread):
# @param path the log file to delete # @param path the log file to delete
def delLogPath(self, path): 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 # Get the log file path
@ -103,7 +106,20 @@ class Filter(JailThread):
# @return log file path # @return log file path
def getLogPath(self): 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. # Set the regular expression which matches the time.
@ -147,8 +163,8 @@ class Filter(JailThread):
# @param value the regular expression # @param value the regular expression
def setFailRegex(self, value): def setFailRegex(self, value):
self.failRegex = value self.__failRegex = value
self.failRegexObj = re.compile(value) self.__failRegexObj = re.compile(value)
logSys.info("Set failregex = %s" % value) logSys.info("Set failregex = %s" % value)
## ##
@ -157,7 +173,7 @@ class Filter(JailThread):
# @return the regular expression # @return the regular expression
def getFailRegex(self): def getFailRegex(self):
return self.failRegex return self.__failRegex
## ##
# Set the time needed to find a failure. # Set the time needed to find a failure.
@ -167,7 +183,7 @@ class Filter(JailThread):
# @param value the time # @param value the time
def setFindTime(self, value): def setFindTime(self, value):
self.findTime = value self.__findTime = value
logSys.info("Set findtime = %s" % value) logSys.info("Set findtime = %s" % value)
## ##
@ -176,7 +192,7 @@ class Filter(JailThread):
# @return the time # @return the time
def getFindTime(self): def getFindTime(self):
return self.findTime return self.__findTime
## ##
# Set the maximum retry value. # Set the maximum retry value.
@ -232,16 +248,16 @@ class Filter(JailThread):
def addIgnoreIP(self, ip): def addIgnoreIP(self, ip):
if DNSUtils.isValidIP(ip): if DNSUtils.isValidIP(ip):
logSys.debug("Add " + ip + " to ignore list") logSys.debug("Add " + ip + " to ignore list")
self.ignoreIpList.append(ip) self.__ignoreIpList.append(ip)
else: else:
logSys.warn(ip + " is not a valid address") logSys.warn(ip + " is not a valid address")
def delIgnoreIP(self, ip): def delIgnoreIP(self, ip):
logSys.debug("Remove " + ip + " from ignore list") logSys.debug("Remove " + ip + " from ignore list")
self.ignoreIpList.remove(ip) self.__ignoreIpList.remove(ip)
def getIgnoreIP(self): def getIgnoreIP(self):
return self.ignoreIpList return self.__ignoreIpList
## ##
# Check if IP address is in the ignore list. # 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 # @return True if IP address is in ignore list
def inIgnoreIPList(self, ip): def inIgnoreIPList(self, ip):
for i in self.ignoreIpList: for i in self.__ignoreIpList:
s = i.split('/', 1) s = i.split('/', 1)
# IP address without CIDR mask # IP address without CIDR mask
if len(s) == 1: if len(s) == 1:
@ -274,8 +290,8 @@ class Filter(JailThread):
""" Opens the log file specified on init. """ Opens the log file specified on init.
""" """
try: try:
self.crtFilename = filename self.__crtFilename = filename
self.crtHandler = open(filename) self.__crtHandler = open(filename)
logSys.debug("Opened " + filename) logSys.debug("Opened " + filename)
return True return True
except OSError: except OSError:
@ -289,8 +305,8 @@ class Filter(JailThread):
# Close the log file. # Close the log file.
def __closeLogFile(self): def __closeLogFile(self):
self.crtFilename = None self.__crtFilename = None
self.crtHandler.close() self.__crtHandler.close()
## ##
# Set the file position. # Set the file position.
@ -300,23 +316,25 @@ class Filter(JailThread):
# timestamp in order to detect this. # timestamp in order to detect this.
def __setFilePos(self): def __setFilePos(self):
line = self.crtHandler.readline() line = self.__crtHandler.readline()
lastDate = self.lastDate[self.crtFilename] lastDate = self.__lastDate[self.__crtFilename]
lineDate = self.dateDetector.getUnixTime(line) lineDate = self.dateDetector.getUnixTime(line)
print lastDate
print lineDate
if lastDate < lineDate: if lastDate < lineDate:
logSys.debug("Date " + `lastDate` + " is smaller than " + `lineDate`) logSys.debug("Date " + `lastDate` + " is smaller than " + `lineDate`)
logSys.debug("Log rotation detected for " + self.crtFilename) logSys.debug("Log rotation detected for " + self.__crtFilename)
self.lastPos[self.crtFilename] = 0 self.__lastPos[self.__crtFilename] = 0
lastPos = self.lastPos[self.crtFilename] lastPos = self.__lastPos[self.__crtFilename]
logSys.debug("Setting file position to " + `lastPos` + " for " + logSys.debug("Setting file position to " + `lastPos` + " for " +
self.crtFilename) self.__crtFilename)
self.crtHandler.seek(lastPos) self.__crtHandler.seek(lastPos)
## ##
# Get the file position. # Get the file position.
def __getFilePos(self): def __getFilePos(self):
return self.crtHandler.tell() return self.__crtHandler.tell()
## ##
# Gets all the failure in the log file. # Gets all the failure in the log file.
@ -333,7 +351,7 @@ class Filter(JailThread):
return False return False
self.__setFilePos() self.__setFilePos()
lastLine = None lastLine = None
for line in self.crtHandler: for line in self.__crtHandler:
try: try:
# Try to convert UTF-8 string to Latin-1 # Try to convert UTF-8 string to Latin-1
#line = line.decode('utf-8').encode('latin-1') #line = line.decode('utf-8').encode('latin-1')
@ -349,16 +367,16 @@ class Filter(JailThread):
for element in self.findFailure(line): for element in self.findFailure(line):
ip = element[0] ip = element[0]
unixTime = element[1] unixTime = element[1]
if unixTime < time.time()-self.findTime: if unixTime < time.time()-self.__findTime:
break break
if self.inIgnoreIPList(ip): if self.inIgnoreIPList(ip):
logSys.debug("Ignore "+ip) logSys.debug("Ignore "+ip)
continue continue
logSys.debug("Found "+ip) logSys.debug("Found "+ip)
self.failManager.addFailure(FailTicket(ip, unixTime)) self.failManager.addFailure(FailTicket(ip, unixTime))
self.lastPos[filename] = self.__getFilePos() self.__lastPos[filename] = self.__getFilePos()
if lastLine: if lastLine:
self.lastDate[filename] = self.dateDetector.getTime(lastLine) self.__lastDate[filename] = self.dateDetector.getUnixTime(lastLine)
self.__closeLogFile() self.__closeLogFile()
return True return True
@ -371,7 +389,7 @@ class Filter(JailThread):
def findFailure(self, line): def findFailure(self, line):
failList = list() failList = list()
match = self.failRegexObj.search(line) match = self.__failRegexObj.search(line)
if match: if match:
date = self.dateDetector.getUnixTime(match.string) date = self.dateDetector.getUnixTime(match.string)
if date <> None: if date <> None:

View File

@ -71,16 +71,11 @@ class FilterGamin(Filter):
# @param path log file path # @param path log file path
def addLogPath(self, path): def addLogPath(self, path):
try: if self.containsLogPath(path):
self.getLogPath().index(path)
logSys.error(path + " already exists") logSys.error(path + " already exists")
except ValueError: else:
self.monitor.watch_file(path, self.callback) self.monitor.watch_file(path, self.callback)
self.getLogPath().append(path) Filter.addLogPath(self, path)
# Initialize default values
self.lastDate[path] = 0
self.lastModTime[path] = 0
self.lastPos[path] = 0
logSys.info("Added logfile = %s" % path) logSys.info("Added logfile = %s" % path)
## ##
@ -89,16 +84,12 @@ class FilterGamin(Filter):
# @param path the log file to delete # @param path the log file to delete
def delLogPath(self, path): def delLogPath(self, path):
try: if not self.containsLogPath(path):
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:
logSys.error(path + " is not monitored") logSys.error(path + " is not monitored")
else:
self.monitor.stop_watch(path)
Filter.delLogPath(self, path)
logSys.info("Removed logfile = %s" % path)
## ##
# Main loop. # Main loop.

View File

@ -52,9 +52,9 @@ class FilterPoll(Filter):
def __init__(self, jail): def __init__(self, jail):
Filter.__init__(self, jail) Filter.__init__(self, jail)
## The time of the last modification of the file.
self.__lastModTime = dict()
self.__file404Cnt = dict() self.__file404Cnt = dict()
logSys.info("Created FilterPoll") logSys.info("Created FilterPoll")
## ##
@ -63,16 +63,12 @@ class FilterPoll(Filter):
# @param path log file path # @param path log file path
def addLogPath(self, path): def addLogPath(self, path):
try: if self.containsLogPath(path):
self.getLogPath().index(path)
logSys.error(path + " already exists") logSys.error(path + " already exists")
except ValueError: else:
self.getLogPath().append(path) self.__lastModTime[path] = 0
# Initialize default values
self.lastDate[path] = 0
self.lastModTime[path] = 0
self.lastPos[path] = 0
self.__file404Cnt[path] = 0 self.__file404Cnt[path] = 0
Filter.addLogPath(self, path)
logSys.info("Added logfile = %s" % path) logSys.info("Added logfile = %s" % path)
## ##
@ -81,16 +77,13 @@ class FilterPoll(Filter):
# @param path the log file to delete # @param path the log file to delete
def delLogPath(self, path): def delLogPath(self, path):
try: if not self.containsLogPath(path):
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:
logSys.error(path + " is not monitored") 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. # Main loop.
@ -107,7 +100,7 @@ class FilterPoll(Filter):
for file in self.getLogPath(): for file in self.getLogPath():
if self.isModified(file): if self.isModified(file):
self.getFailures(file) self.getFailures(file)
prevModified = True self.modified = True
if self.modified: if self.modified:
try: try:
@ -116,7 +109,7 @@ class FilterPoll(Filter):
except FailManagerEmpty: except FailManagerEmpty:
self.failManager.cleanup(time.time()) self.failManager.cleanup(time.time())
self.dateDetector.sortTemplate() self.dateDetector.sortTemplate()
prevModified = False self.modified = False
time.sleep(self.getSleepTime()) time.sleep(self.getSleepTime())
else: else:
time.sleep(self.getSleepTime()) time.sleep(self.getSleepTime())
@ -133,11 +126,11 @@ class FilterPoll(Filter):
try: try:
logStats = os.stat(filename) logStats = os.stat(filename)
self.__file404Cnt[filename] = 0 self.__file404Cnt[filename] = 0
if self.lastModTime[filename] == logStats.st_mtime: if self.__lastModTime[filename] == logStats.st_mtime:
return False return False
else: else:
logSys.debug(filename + " has been modified") logSys.debug(filename + " has been modified")
self.lastModTime[filename] = logStats.st_mtime self.__lastModTime[filename] = logStats.st_mtime
return True return True
except OSError: except OSError:
logSys.error("Unable to get stat on " + filename) logSys.error("Unable to get stat on " + filename)