mirror of https://github.com/fail2ban/fail2ban
switch down log level for some annoying messages to tracedebug or heavydebug (to 7 or even 5);
added verification of specified log-level before transmitting to the server; numeric log-level allowed now in server (resp. fail2ban.conf);pull/1557/head
parent
48ebe3e735
commit
ab0c28260b
|
@ -26,8 +26,11 @@ __license__ = "GPL"
|
||||||
|
|
||||||
import logging.handlers
|
import logging.handlers
|
||||||
|
|
||||||
# Custom debug level
|
# Custom debug levels
|
||||||
|
logging.TRACEDEBUG = 7
|
||||||
logging.HEAVYDEBUG = 5
|
logging.HEAVYDEBUG = 5
|
||||||
|
logging.addLevelName(logging.TRACEDEBUG, 'TRACE')
|
||||||
|
logging.addLevelName(logging.HEAVYDEBUG, 'HEAVY')
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Below derived from:
|
Below derived from:
|
||||||
|
|
|
@ -25,7 +25,7 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
from .configreader import ConfigReader
|
from .configreader import ConfigReader
|
||||||
from ..helpers import getLogger
|
from ..helpers import getLogger, str2LogLevel
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
@ -58,6 +58,8 @@ class Fail2banReader(ConfigReader):
|
||||||
self.__opts = ConfigReader.getOptions(self, "Definition", opts)
|
self.__opts = ConfigReader.getOptions(self, "Definition", opts)
|
||||||
if updateMainOpt:
|
if updateMainOpt:
|
||||||
self.__opts.update(updateMainOpt)
|
self.__opts.update(updateMainOpt)
|
||||||
|
# check given log-level:
|
||||||
|
str2LogLevel(self.__opts.get('loglevel', 0))
|
||||||
|
|
||||||
def convert(self):
|
def convert(self):
|
||||||
# Ensure logtarget/level set first so any db errors are captured
|
# Ensure logtarget/level set first so any db errors are captured
|
||||||
|
|
|
@ -129,6 +129,16 @@ def getLogger(name):
|
||||||
name = "fail2ban.%s" % name.rpartition(".")[-1]
|
name = "fail2ban.%s" % name.rpartition(".")[-1]
|
||||||
return logging.getLogger(name)
|
return logging.getLogger(name)
|
||||||
|
|
||||||
|
def str2LogLevel(value):
|
||||||
|
try:
|
||||||
|
if isinstance(value, int) or value.isdigit():
|
||||||
|
ll = int(value)
|
||||||
|
else:
|
||||||
|
ll = getattr(logging, value)
|
||||||
|
except AttributeError:
|
||||||
|
raise ValueError("Invalid log level %r" % value)
|
||||||
|
return ll
|
||||||
|
|
||||||
|
|
||||||
def excepthook(exctype, value, traceback):
|
def excepthook(exctype, value, traceback):
|
||||||
"""Except hook used to log unhandled exceptions to Fail2Ban log
|
"""Except hook used to log unhandled exceptions to Fail2Ban log
|
||||||
|
|
|
@ -61,7 +61,8 @@ protocol = [
|
||||||
["help", "return this output"],
|
["help", "return this output"],
|
||||||
["version", "return the server version"],
|
["version", "return the server version"],
|
||||||
['', "LOGGING", ""],
|
['', "LOGGING", ""],
|
||||||
["set loglevel <LEVEL>", "sets logging level to <LEVEL>. Levels: CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG"],
|
["set loglevel <LEVEL>", "sets logging level to <LEVEL>. Levels: CRITICAL, ERROR, WARNING, NOTICE, INFO, "
|
||||||
|
"DEBUG, TRACEDEBUG, HEAVYDEBUG or corresponding numeric value (50-5)"],
|
||||||
["get loglevel", "gets the logging level"],
|
["get loglevel", "gets the logging level"],
|
||||||
["set logtarget <TARGET>", "sets logging target to <TARGET>. Can be STDOUT, STDERR, SYSLOG or a file"],
|
["set logtarget <TARGET>", "sets logging target to <TARGET>. Can be STDOUT, STDERR, SYSLOG or a file"],
|
||||||
["get logtarget", "gets logging target"],
|
["get logtarget", "gets logging target"],
|
||||||
|
|
|
@ -137,10 +137,10 @@ class FilterPoll(FileFilter):
|
||||||
logStats = os.stat(filename)
|
logStats = os.stat(filename)
|
||||||
stats = logStats.st_mtime, logStats.st_ino, logStats.st_size
|
stats = logStats.st_mtime, logStats.st_ino, logStats.st_size
|
||||||
pstats = self.__prevStats.get(filename, (0))
|
pstats = self.__prevStats.get(filename, (0))
|
||||||
if logSys.getEffectiveLevel() <= 7:
|
if logSys.getEffectiveLevel() <= 5:
|
||||||
# we do not want to waste time on strftime etc if not necessary
|
# we do not want to waste time on strftime etc if not necessary
|
||||||
dt = logStats.st_mtime - pstats[0]
|
dt = logStats.st_mtime - pstats[0]
|
||||||
logSys.log(7, "Checking %s for being modified. Previous/current stats: %s / %s. dt: %s",
|
logSys.log(5, "Checking %s for being modified. Previous/current stats: %s / %s. dt: %s",
|
||||||
filename, pstats, stats, dt)
|
filename, pstats, stats, dt)
|
||||||
# os.system("stat %s | grep Modify" % filename)
|
# os.system("stat %s | grep Modify" % filename)
|
||||||
self.__file404Cnt[filename] = 0
|
self.__file404Cnt[filename] = 0
|
||||||
|
|
|
@ -76,7 +76,7 @@ class FilterPyinotify(FileFilter):
|
||||||
logSys.debug("Created FilterPyinotify")
|
logSys.debug("Created FilterPyinotify")
|
||||||
|
|
||||||
def callback(self, event, origin=''):
|
def callback(self, event, origin=''):
|
||||||
logSys.debug("%sCallback for Event: %s", origin, event)
|
logSys.log(7, "[%s] %sCallback for Event: %s", self.jailName, origin, event)
|
||||||
path = event.pathname
|
path = event.pathname
|
||||||
if event.mask & ( pyinotify.IN_CREATE | pyinotify.IN_MOVED_TO ):
|
if event.mask & ( pyinotify.IN_CREATE | pyinotify.IN_MOVED_TO ):
|
||||||
# skip directories altogether
|
# skip directories altogether
|
||||||
|
|
|
@ -218,7 +218,7 @@ class FilterSystemd(JournalFilter): # pragma: systemd no cover
|
||||||
|
|
||||||
date = logentry.get('_SOURCE_REALTIME_TIMESTAMP',
|
date = logentry.get('_SOURCE_REALTIME_TIMESTAMP',
|
||||||
logentry.get('__REALTIME_TIMESTAMP'))
|
logentry.get('__REALTIME_TIMESTAMP'))
|
||||||
logSys.debug("[%s] Read systemd journal entry: %s %s", self.jailName,
|
logSys.log(5, "[%s] Read systemd journal entry: %s %s", self.jailName,
|
||||||
date.isoformat(), logline)
|
date.isoformat(), logline)
|
||||||
## use the same type for 1st argument:
|
## use the same type for 1st argument:
|
||||||
return ((logline[:0], date.isoformat(), logline),
|
return ((logline[:0], date.isoformat(), logline),
|
||||||
|
|
|
@ -38,7 +38,7 @@ from .filter import FileFilter, JournalFilter
|
||||||
from .transmitter import Transmitter
|
from .transmitter import Transmitter
|
||||||
from .asyncserver import AsyncServer, AsyncServerException
|
from .asyncserver import AsyncServer, AsyncServerException
|
||||||
from .. import version
|
from .. import version
|
||||||
from ..helpers import getLogger, excepthook
|
from ..helpers import getLogger, str2LogLevel, excepthook
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
@ -510,14 +510,11 @@ class Server:
|
||||||
with self.__loggingLock:
|
with self.__loggingLock:
|
||||||
if self.__logLevel == value:
|
if self.__logLevel == value:
|
||||||
return
|
return
|
||||||
try:
|
ll = str2LogLevel(value)
|
||||||
ll = getattr(logging, value)
|
# don't change real log-level if running from the test cases:
|
||||||
# don't change real log-level if running from the test cases:
|
getLogger("fail2ban").setLevel(
|
||||||
getLogger("fail2ban").setLevel(
|
ll if DEF_LOGTARGET != "INHERITED" or ll < logging.DEBUG else DEF_LOGLEVEL)
|
||||||
ll if DEF_LOGTARGET != "INHERITED" or ll < logging.DEBUG else DEF_LOGLEVEL)
|
self.__logLevel = value
|
||||||
self.__logLevel = value
|
|
||||||
except AttributeError:
|
|
||||||
raise ValueError("Invalid log level %r" % value)
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Get the logging level.
|
# Get the logging level.
|
||||||
|
|
|
@ -842,6 +842,8 @@ class TransmitterLogging(TransmitterBase):
|
||||||
|
|
||||||
def testLogLevel(self):
|
def testLogLevel(self):
|
||||||
self.setGetTest("loglevel", "HEAVYDEBUG")
|
self.setGetTest("loglevel", "HEAVYDEBUG")
|
||||||
|
self.setGetTest("loglevel", "TRACEDEBUG")
|
||||||
|
self.setGetTest("loglevel", "9")
|
||||||
self.setGetTest("loglevel", "DEBUG")
|
self.setGetTest("loglevel", "DEBUG")
|
||||||
self.setGetTest("loglevel", "INFO")
|
self.setGetTest("loglevel", "INFO")
|
||||||
self.setGetTest("loglevel", "NOTICE")
|
self.setGetTest("loglevel", "NOTICE")
|
||||||
|
|
|
@ -120,7 +120,9 @@ LOGGING
|
||||||
\fBset loglevel <LEVEL>\fR
|
\fBset loglevel <LEVEL>\fR
|
||||||
sets logging level to <LEVEL>.
|
sets logging level to <LEVEL>.
|
||||||
Levels: CRITICAL, ERROR, WARNING,
|
Levels: CRITICAL, ERROR, WARNING,
|
||||||
NOTICE, INFO, DEBUG
|
NOTICE, INFO, DEBUG, TRACEDEBUG,
|
||||||
|
HEAVYDEBUG or corresponding
|
||||||
|
numeric value (50\-5)
|
||||||
.TP
|
.TP
|
||||||
\fBget loglevel\fR
|
\fBget loglevel\fR
|
||||||
gets the logging level
|
gets the logging level
|
||||||
|
|
|
@ -51,6 +51,11 @@ File encoding. Default: system locale
|
||||||
\fB\-r\fR, \fB\-\-raw\fR
|
\fB\-r\fR, \fB\-\-raw\fR
|
||||||
Raw hosts, don't resolve dns
|
Raw hosts, don't resolve dns
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-\-usedns\fR=\fI\,USEDNS\/\fR
|
||||||
|
DNS specified replacement of tags <HOST> in regexp
|
||||||
|
('yes' \- matches all form of hosts, 'no' \- IP
|
||||||
|
addresses only)
|
||||||
|
.TP
|
||||||
\fB\-L\fR MAXLINES, \fB\-\-maxlines\fR=\fI\,MAXLINES\/\fR
|
\fB\-L\fR MAXLINES, \fB\-\-maxlines\fR=\fI\,MAXLINES\/\fR
|
||||||
maxlines for multi\-line regex
|
maxlines for multi\-line regex
|
||||||
.TP
|
.TP
|
||||||
|
|
|
@ -127,7 +127,7 @@ These files have one section, [Definition].
|
||||||
The items that can be set are:
|
The items that can be set are:
|
||||||
.TP
|
.TP
|
||||||
.B loglevel
|
.B loglevel
|
||||||
verbosity level of log output: CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG. Default: ERROR
|
verbosity level of log output: CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG, TRACEDEBUG, HEAVYDEBUG or corresponding numeric value (50-5). Default: ERROR (equal 40)
|
||||||
.TP
|
.TP
|
||||||
.B logtarget
|
.B logtarget
|
||||||
log target: filename, SYSLOG, STDERR or STDOUT. Default: STDERR
|
log target: filename, SYSLOG, STDERR or STDOUT. Default: STDERR
|
||||||
|
|
Loading…
Reference in New Issue