From 1bf66364462ff0d4c224cce83315d1b29d41b06a Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 5 Dec 2017 18:54:21 +0100 Subject: [PATCH] Introduced new parameters for logging within fail2ban-server; Usage `logtarget = target[facility=..., datetime=on|off, format="..."]`: - `facility` - specify syslog facility (default `daemon`, see https://docs.python.org/2/library/logging.handlers.html#sysloghandler for the list of facilities); - `datetime` - add date-time to the message (default on, ignored if `format` specified); - `format` - specify own format how it will be logged, for example for short-log into STDOUT: `fail2ban-server -f --logtarget 'stdout[format="%(relativeCreated)5d | %(message)s"]' start`; Closes gh-1980 --- fail2ban/server/server.py | 21 +++++++++++++++++---- fail2ban/tests/fail2banclienttestcase.py | 5 +++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/fail2ban/server/server.py b/fail2ban/server/server.py index 9cb6f320..4a491903 100644 --- a/fail2ban/server/server.py +++ b/fail2ban/server/server.py @@ -37,7 +37,7 @@ from .filter import FileFilter, JournalFilter from .transmitter import Transmitter from .asyncserver import AsyncServer, AsyncServerException from .. import version -from ..helpers import getLogger, str2LogLevel, getVerbosityFormat, excepthook +from ..helpers import getLogger, extractOptions, str2LogLevel, getVerbosityFormat, excepthook # Gets the instance of the logger. logSys = getLogger(__name__) @@ -547,6 +547,7 @@ class Server: def setLogTarget(self, target): # check reserved targets in uppercase, don't change target, because it can be file: + target, logOptions = extractOptions(target) systarget = target.upper() with self.__loggingLock: # don't set new handlers if already the same @@ -559,7 +560,12 @@ class Server: # set a format which is simpler for console use fmt = "%(name)-24s[%(process)d]: %(levelname)-7s %(message)s" if systarget == "SYSLOG": - facility = logging.handlers.SysLogHandler.LOG_DAEMON + facility = logOptions.get('facility', 'DAEMON').upper() + try: + facility = getattr(logging.handlers.SysLogHandler, 'LOG_' + facility) + except AttributeError: # pragma: no cover + logSys.error("Unable to set facility %r, using 'DAEMON'", logOptions.get('facility')) + facility = logging.handlers.SysLogHandler.LOG_DAEMON if self.__syslogSocket == "auto": import platform self.__syslogSocket = self.__autoSyslogSocketPaths.get( @@ -610,9 +616,16 @@ class Server: if self.__verbose is None: self.__verbose = logging.DEBUG - logger.getEffectiveLevel() + 1 # If handler don't already add date to the message: - addtime = systarget not in ("SYSLOG", "SYSOUT") + addtime = logOptions.get('datetime') + if addtime is not None: + addtime = addtime in ('1', 'on', 'true', 'yes') + else: + addtime = systarget not in ("SYSLOG", "SYSOUT") + # If log-format is redefined in options: + if logOptions.get('format', '') != '': + fmt = logOptions.get('format') # verbose log-format: - if self.__verbose is not None and self.__verbose > 2: # pragma: no cover + elif self.__verbose is not None and self.__verbose > 2: # pragma: no cover fmt = getVerbosityFormat(self.__verbose-1, addtime=addtime) elif addtime: diff --git a/fail2ban/tests/fail2banclienttestcase.py b/fail2ban/tests/fail2banclienttestcase.py index 11b67fb2..76e35856 100644 --- a/fail2ban/tests/fail2banclienttestcase.py +++ b/fail2ban/tests/fail2banclienttestcase.py @@ -171,7 +171,7 @@ def _start_params(tmp, use_stock=False, use_stock_cfg=None, _write_file(pjoin(cfg, "fail2ban.conf"), "w", "[Definition]", "loglevel = INFO", - "logtarget = " + logtarget, + "logtarget = " + logtarget.replace('%', '%%'), "syslogsocket = auto", "socket = " + pjoin(tmp, "f2b.sock"), "pidfile = " + pjoin(tmp, "f2b.pid"), @@ -735,7 +735,8 @@ class Fail2banServerTest(Fail2banClientServerBase): def testKillAfterStart(self, tmp): try: # to prevent fork of test-cases process, start server in background via command: - startparams = _start_params(tmp, logtarget=pjoin(tmp, "f2b.log")) + startparams = _start_params(tmp, logtarget=pjoin(tmp, + 'f2b.log[format="SRV: %(relativeCreated)3d | %(message)s", datetime=off]')) # start (in new process, using the same python version): cmd = (sys.executable, pjoin(BIN, SERVER)) logSys.debug('Start %s ...', cmd)