mirror of https://github.com/fail2ban/fail2ban
allow to parse milliseconds as float + more test cases;
normalize capturing with epoch-pattern match - similar to `{DATE}` should capture and cut out the whole pattern match from the log-line;pull/2038/head
parent
3e8098d427
commit
dcbf904876
|
@ -199,12 +199,15 @@ class DateEpoch(DateTemplate):
|
||||||
DateTemplate.__init__(self)
|
DateTemplate.__init__(self)
|
||||||
self.name = "Epoch"
|
self.name = "Epoch"
|
||||||
self._longFrm = longFrm;
|
self._longFrm = longFrm;
|
||||||
|
self._grpIdx = 1
|
||||||
epochRE = r"\d{10,11}\b(?:\.\d{3,6})?"
|
epochRE = r"\d{10,11}\b(?:\.\d{3,6})?"
|
||||||
if longFrm:
|
if longFrm:
|
||||||
self.name = "LongEpoch";
|
self.name = "LongEpoch";
|
||||||
epochRE = r"\d{10,11}(?:\d{3}(?:\d{3})?)?"
|
epochRE = r"\d{10,11}(?:\d{3}(?:\.\d{1,6}|\d{3})?)?"
|
||||||
if pattern:
|
if pattern:
|
||||||
regex = RE_EPOCH_PATTERN.sub(lambda v: "(%s)" % epochRE, pattern)
|
# pattern should capture/cut out the whole match:
|
||||||
|
regex = "(" + RE_EPOCH_PATTERN.sub(lambda v: "(%s)" % epochRE, pattern) + ")"
|
||||||
|
self._grpIdx = 2
|
||||||
self.setRegex(regex)
|
self.setRegex(regex)
|
||||||
elif not lineBeginOnly:
|
elif not lineBeginOnly:
|
||||||
regex = r"((?:^|(?P<square>(?<=^\[))|(?P<selinux>(?<=\baudit\()))%s)(?:(?(selinux)(?=:\d+\)))|(?(square)(?=\])))" % epochRE
|
regex = r"((?:^|(?P<square>(?<=^\[))|(?P<selinux>(?<=\baudit\()))%s)(?:(?(selinux)(?=:\d+\)))|(?(square)(?=\])))" % epochRE
|
||||||
|
@ -231,10 +234,10 @@ class DateEpoch(DateTemplate):
|
||||||
if not dateMatch:
|
if not dateMatch:
|
||||||
dateMatch = self.matchDate(line)
|
dateMatch = self.matchDate(line)
|
||||||
if dateMatch:
|
if dateMatch:
|
||||||
v = dateMatch.group(1)
|
v = dateMatch.group(self._grpIdx)
|
||||||
# extract part of format which represents seconds since epoch
|
# extract part of format which represents seconds since epoch
|
||||||
if self._longFrm and len(v) >= 13:
|
if self._longFrm and len(v) >= 13:
|
||||||
if len(v) >= 16:
|
if len(v) >= 16 and '.' not in v:
|
||||||
v = float(v) / 1000000
|
v = float(v) / 1000000
|
||||||
else:
|
else:
|
||||||
v = float(v) / 1000
|
v = float(v) / 1000
|
||||||
|
|
|
@ -103,7 +103,7 @@ class DateDetectorTest(LogCaptureTestCase):
|
||||||
|
|
||||||
def testGetEpochPattern(self):
|
def testGetEpochPattern(self):
|
||||||
self.__datedetector = DateDetector()
|
self.__datedetector = DateDetector()
|
||||||
self.__datedetector.appendTemplate('\|\s{LEPOCH}(?=\s\|)')
|
self.__datedetector.appendTemplate('(?<=\|\s){LEPOCH}(?=\s\|)')
|
||||||
# correct short/long epoch time, using all variants:
|
# correct short/long epoch time, using all variants:
|
||||||
for fact in (1, 1000, 1000000):
|
for fact in (1, 1000, 1000000):
|
||||||
for dateUnix in (1138049999, 32535244799):
|
for dateUnix in (1138049999, 32535244799):
|
||||||
|
|
|
@ -290,6 +290,17 @@ class Fail2banRegexTest(LogCaptureTestCase):
|
||||||
self.assertTrue(fail2banRegex.start(args))
|
self.assertTrue(fail2banRegex.start(args))
|
||||||
self.assertLogged('Lines: 1 lines, 0 ignored, 1 matched, 0 missed')
|
self.assertLogged('Lines: 1 lines, 0 ignored, 1 matched, 0 missed')
|
||||||
|
|
||||||
|
def testRegexEpochPatterns(self):
|
||||||
|
(opts, args, fail2banRegex) = _Fail2banRegex(
|
||||||
|
"-r", "-d", "^\[{LEPOCH}\]\s+", "--maxlines", "5",
|
||||||
|
"[1516469849] 192.0.2.1 FAIL: failure\n"
|
||||||
|
"[1516469849551] 192.0.2.2 FAIL: failure\n"
|
||||||
|
"[1516469849551000] 192.0.2.3 FAIL: failure\n"
|
||||||
|
"[1516469849551.000] 192.0.2.4 FAIL: failure",
|
||||||
|
r"^<HOST> FAIL\b"
|
||||||
|
)
|
||||||
|
self.assertTrue(fail2banRegex.start(args))
|
||||||
|
self.assertLogged('Lines: 4 lines, 0 ignored, 4 matched, 0 missed')
|
||||||
|
|
||||||
def testWrongFilterFile(self):
|
def testWrongFilterFile(self):
|
||||||
# use test log as filter file to cover eror cases...
|
# use test log as filter file to cover eror cases...
|
||||||
|
|
Loading…
Reference in New Issue