allow to set default or preferred encoding for other filters (e.g. to decode bytes from journal)

# Conflicts:
#	fail2ban/server/filter.py
pull/1542/head
sebres 2016-09-06 13:03:14 +02:00
parent 3119f81705
commit 57458a462e
3 changed files with 31 additions and 25 deletions

View File

@ -83,6 +83,8 @@ class Filter(JailThread):
self.__lastDate = None self.__lastDate = None
## External command ## External command
self.__ignoreCommand = False self.__ignoreCommand = False
## Default or preferred encoding (to decode bytes from file or journal):
self.__encoding = locale.getpreferredencoding()
self.dateDetector = DateDetector() self.dateDetector = DateDetector()
self.dateDetector.addDefaultTemplate() self.dateDetector.addDefaultTemplate()
@ -280,6 +282,27 @@ class Filter(JailThread):
def getMaxLines(self): def getMaxLines(self):
return self.__lineBufferSize return self.__lineBufferSize
##
# Set the log file encoding
#
# @param encoding the encoding used with log files
def setLogEncoding(self, encoding):
if encoding.lower() == "auto":
encoding = locale.getpreferredencoding()
codecs.lookup(encoding) # Raise LookupError if invalid codec
self.__encoding = encoding
logSys.info("Set jail log file encoding to %s" % encoding)
return encoding
##
# Get the log file encoding
#
# @return log encoding value
def getLogEncoding(self):
return self.__encoding
## ##
# Main loop. # Main loop.
# #
@ -584,7 +607,6 @@ class FileFilter(Filter):
Filter.__init__(self, jail, **kwargs) Filter.__init__(self, jail, **kwargs)
## The log file path. ## The log file path.
self.__logs = dict() self.__logs = dict()
self.setLogEncoding("auto")
## ##
# Add a log file path # Add a log file path
@ -655,21 +677,9 @@ class FileFilter(Filter):
# @param encoding the encoding used with log files # @param encoding the encoding used with log files
def setLogEncoding(self, encoding): def setLogEncoding(self, encoding):
if encoding.lower() == "auto": encoding = super(FileFilter, self).setLogEncoding(encoding)
encoding = locale.getpreferredencoding()
codecs.lookup(encoding) # Raise LookupError if invalid codec
for log in self.__logs.itervalues(): for log in self.__logs.itervalues():
log.setEncoding(encoding) log.setEncoding(encoding)
self.__encoding = encoding
logSys.info("Set jail log file encoding to %s" % encoding)
##
# Get the log file encoding
#
# @return log encoding value
def getLogEncoding(self):
return self.__encoding
def getLog(self, path): def getLog(self, path):
return self.__logs.get(path, None) return self.__logs.get(path, None)

View File

@ -31,7 +31,7 @@ if LooseVersion(getattr(journal, '__version__', "0")) < '204':
raise ImportError("Fail2Ban requires systemd >= 204") raise ImportError("Fail2Ban requires systemd >= 204")
from .failmanager import FailManagerEmpty from .failmanager import FailManagerEmpty
from .filter import JournalFilter, Filter, locale from .filter import JournalFilter, Filter
from .mytime import MyTime from .mytime import MyTime
from ..helpers import getLogger, logging, splitwords from ..helpers import getLogger, logging, splitwords
@ -170,9 +170,8 @@ class FilterSystemd(JournalFilter): # pragma: systemd no cover
def getJournalMatch(self): def getJournalMatch(self):
return self.__matches return self.__matches
@staticmethod def uni_decode(self, x):
def uni_decode(x): v = Filter.uni_decode(x, self.getLogEncoding())
v = Filter.uni_decode(x, locale.getpreferredencoding())
return v return v
## ##
@ -181,10 +180,9 @@ class FilterSystemd(JournalFilter): # pragma: systemd no cover
# @param entry systemd journal entry dict # @param entry systemd journal entry dict
# @return format log line # @return format log line
@classmethod def formatJournalEntry(self, logentry):
def formatJournalEntry(cls, logentry):
# Be sure, all argument of line tuple should have the same type: # Be sure, all argument of line tuple should have the same type:
uni_decode = FilterSystemd.uni_decode uni_decode = self.uni_decode
logelements = [] logelements = []
v = logentry.get('_HOSTNAME') v = logentry.get('_HOSTNAME')
if v: if v:

View File

@ -237,13 +237,11 @@ class Server:
def setLogEncoding(self, name, encoding): def setLogEncoding(self, name, encoding):
filter_ = self.__jails[name].filter filter_ = self.__jails[name].filter
if isinstance(filter_, FileFilter): filter_.setLogEncoding(encoding)
filter_.setLogEncoding(encoding)
def getLogEncoding(self, name): def getLogEncoding(self, name):
filter_ = self.__jails[name].filter filter_ = self.__jails[name].filter
if isinstance(filter_, FileFilter): return filter_.getLogEncoding()
return filter_.getLogEncoding()
def setFindTime(self, name, value): def setFindTime(self, name, value):
self.__jails[name].filter.setFindTime(value) self.__jails[name].filter.setFindTime(value)