Merge branch 'kwirk/harmonize-log-msgs'

Conflicts:
	ChangeLog - Keep all additions
pull/747/head
Steven Hiscocks 2014-06-22 12:57:49 +01:00
commit 2d54161696
39 changed files with 149 additions and 85 deletions

View File

@ -40,6 +40,9 @@ ver. 0.9.1 (2014/xx/xx) - better, faster, stronger
* Suppress fail2ban-client warnings for non-critical config options * Suppress fail2ban-client warnings for non-critical config options
* Match non "Bye Bye" disconnect messages for sshd locked account regex * Match non "Bye Bye" disconnect messages for sshd locked account regex
* Add <chain> tag to iptables-ipsets. * Add <chain> tag to iptables-ipsets.
* Realign fail2ban log output with white space to improve readability. Does
not affect SYSLOG output.
* Log unhandled exceptions
ver. 0.9.0 (2014/03/14) - beta ver. 0.9.0 (2014/03/14) - beta
---------- ----------

View File

@ -30,9 +30,10 @@ from fail2ban.protocol import printFormatted
from fail2ban.client.csocket import CSocket from fail2ban.client.csocket import CSocket
from fail2ban.client.configurator import Configurator from fail2ban.client.configurator import Configurator
from fail2ban.client.beautifier import Beautifier from fail2ban.client.beautifier import Beautifier
from fail2ban.helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger("fail2ban.client") logSys = getLogger("fail2ban")
## ##
# #

View File

@ -45,9 +45,9 @@ from fail2ban.client.filterreader import FilterReader
from fail2ban.server.filter import Filter from fail2ban.server.filter import Filter
from fail2ban.server.failregex import RegexException from fail2ban.server.failregex import RegexException
from fail2ban.helpers import FormatterWithTraceBack from fail2ban.helpers import FormatterWithTraceBack, getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger("fail2ban") logSys = getLogger("fail2ban")
def debuggexURL(sample, regex): def debuggexURL(sample, regex):
q = urllib.urlencode({ 're': regex.replace('<HOST>', '(?&.ipv4)'), q = urllib.urlencode({ 're': regex.replace('<HOST>', '(?&.ipv4)'),

View File

@ -22,13 +22,14 @@ __author__ = "Cyril Jaquier"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
import getopt, sys, logging, os import getopt, sys, os
from fail2ban.version import version from fail2ban.version import version
from fail2ban.server.server import Server from fail2ban.server.server import Server
from fail2ban.helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger("fail2ban") logSys = getLogger("fail2ban")
## ##
# \mainpage Fail2Ban # \mainpage Fail2Ban

View File

@ -25,7 +25,7 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2012- Yaroslav Halchenko"
__license__ = "GPL" __license__ = "GPL"
import unittest, logging, sys, time, os import unittest, sys, time, os
# Check if local fail2ban module exists, and use if it exists by # Check if local fail2ban module exists, and use if it exists by
# modifying the path. This is such that tests can be used in dev # modifying the path. This is such that tests can be used in dev
@ -35,7 +35,7 @@ if os.path.exists("fail2ban/__init__.py"):
from fail2ban.version import version from fail2ban.version import version
from fail2ban.tests.utils import gatherTests from fail2ban.tests.utils import gatherTests
from fail2ban.helpers import FormatterWithTraceBack from fail2ban.helpers import FormatterWithTraceBack, getLogger
from fail2ban.server.mytime import MyTime from fail2ban.server.mytime import MyTime
from optparse import OptionParser, Option from optparse import OptionParser, Option
@ -70,7 +70,7 @@ parser = get_opt_parser()
# #
# Logging # Logging
# #
logSys = logging.getLogger("fail2ban") logSys = getLogger("fail2ban")
# Numerical level of verbosity corresponding to a log "level" # Numerical level of verbosity corresponding to a log "level"
verbosity = {'heavydebug': 4, verbosity = {'heavydebug': 4,

View File

@ -21,7 +21,7 @@ before = common.conf
[Definition] [Definition]
_daemon = fail2ban\.server\.actions _daemon = fail2ban\.actions\s*
# The name of the jail that this filter is used for. In jail.conf, name the # The name of the jail that this filter is used for. In jail.conf, name the
# jail using this filter 'recidive', or change this line! # jail using this filter 'recidive', or change this line!

View File

@ -24,12 +24,13 @@ __author__ = "Cyril Jaquier"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
import logging, os import os
from .configreader import ConfigReader, DefinitionInitConfigReader from .configreader import ConfigReader, DefinitionInitConfigReader
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
class ActionReader(DefinitionInitConfigReader): class ActionReader(DefinitionInitConfigReader):

View File

@ -21,12 +21,11 @@ __author__ = "Cyril Jaquier, Yaroslav Halchenko"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2013- Yaroslav Halchenko" __copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2013- Yaroslav Halchenko"
__license__ = "GPL" __license__ = "GPL"
import logging
from ..exceptions import UnknownJailException, DuplicateJailException from ..exceptions import UnknownJailException, DuplicateJailException
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
## ##
# Beautify the output of the client. # Beautify the output of the client.

View File

@ -24,7 +24,8 @@ __author__ = 'Yaroslav Halhenko'
__copyright__ = 'Copyright (c) 2007 Yaroslav Halchenko' __copyright__ = 'Copyright (c) 2007 Yaroslav Halchenko'
__license__ = 'GPL' __license__ = 'GPL'
import logging, os, sys import os, sys
from ..helpers import getLogger
if sys.version_info >= (3,2): # pragma: no cover if sys.version_info >= (3,2): # pragma: no cover
@ -60,7 +61,7 @@ else: # pragma: no cover
from ConfigParser import SafeConfigParser from ConfigParser import SafeConfigParser
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
__all__ = ['SafeConfigParserWithIncludes'] __all__ = ['SafeConfigParserWithIncludes']

View File

@ -24,13 +24,14 @@ __author__ = "Cyril Jaquier"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
import glob, logging, os import glob, os
from ConfigParser import NoOptionError, NoSectionError from ConfigParser import NoOptionError, NoSectionError
from .configparserinc import SafeConfigParserWithIncludes from .configparserinc import SafeConfigParserWithIncludes
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
class ConfigReader(SafeConfigParserWithIncludes): class ConfigReader(SafeConfigParserWithIncludes):

View File

@ -24,13 +24,12 @@ __author__ = "Cyril Jaquier"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
import logging
from .fail2banreader import Fail2banReader from .fail2banreader import Fail2banReader
from .jailsreader import JailsReader from .jailsreader import JailsReader
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
class Configurator: class Configurator:

View File

@ -24,12 +24,11 @@ __author__ = "Cyril Jaquier"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
import logging
from .configreader import ConfigReader from .configreader import ConfigReader
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
class Fail2banReader(ConfigReader): class Fail2banReader(ConfigReader):

View File

@ -24,13 +24,14 @@ __author__ = "Cyril Jaquier"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
import logging, os, shlex import os, shlex
from .configreader import ConfigReader, DefinitionInitConfigReader from .configreader import ConfigReader, DefinitionInitConfigReader
from ..server.action import CommandAction from ..server.action import CommandAction
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
class FilterReader(DefinitionInitConfigReader): class FilterReader(DefinitionInitConfigReader):

View File

@ -24,15 +24,16 @@ __author__ = "Cyril Jaquier"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
import logging, re, glob, os.path import re, glob, os.path
import json import json
from .configreader import ConfigReader from .configreader import ConfigReader
from .filterreader import FilterReader from .filterreader import FilterReader
from .actionreader import ActionReader from .actionreader import ActionReader
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
class JailReader(ConfigReader): class JailReader(ConfigReader):

View File

@ -24,13 +24,12 @@ __author__ = "Cyril Jaquier"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
import logging
from .configreader import ConfigReader from .configreader import ConfigReader
from .jailreader import JailReader from .jailreader import JailReader
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
class JailsReader(ConfigReader): class JailsReader(ConfigReader):

View File

@ -107,3 +107,17 @@ class FormatterWithTraceBack(logging.Formatter):
def format(self, record): def format(self, record):
record.tbc = record.tb = self._tb() record.tbc = record.tb = self._tb()
return logging.Formatter.format(self, record) return logging.Formatter.format(self, record)
def getLogger(name):
"""Get logging.Logger instance with Fail2Ban logger name convention
"""
if "." in name:
name = "fail2ban.%s" % name.rpartition(".")[-1]
return logging.getLogger(name)
def excepthook(exctype, value, traceback):
"""Except hook used to log unhandled exceptions to Fail2Ban log
"""
getLogger("fail2ban").critical(
"Unhandled exception in Fail2Ban:", exc_info=True)
return sys.__excepthook__(exctype, value, traceback)

View File

@ -25,10 +25,11 @@ import logging, os, subprocess, time, signal, tempfile
import threading, re import threading, re
from abc import ABCMeta from abc import ABCMeta
from collections import MutableMapping from collections import MutableMapping
#from subprocess import call
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
# Create a lock for running system commands # Create a lock for running system commands
_cmd_lock = threading.Lock() _cmd_lock = threading.Lock()
@ -135,8 +136,7 @@ class ActionBase(object):
def __init__(self, jail, name): def __init__(self, jail, name):
self._jail = jail self._jail = jail
self._name = name self._name = name
self._logSys = logging.getLogger( self._logSys = getLogger("fail2ban.%s" % self.__class__.__name__)
'%s.%s' % (__name__, self.__class__.__name__))
def start(self): def start(self):
"""Executed when the jail/action is started. """Executed when the jail/action is started.

View File

@ -41,9 +41,10 @@ from .banmanager import BanManager
from .jailthread import JailThread from .jailthread import JailThread
from .action import ActionBase, CommandAction, CallingMap from .action import ActionBase, CommandAction, CallingMap
from .mytime import MyTime from .mytime import MyTime
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
class Actions(JailThread, Mapping): class Actions(JailThread, Mapping):
"""Handles jail actions. """Handles jail actions.

View File

@ -25,12 +25,12 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
from pickle import dumps, loads, HIGHEST_PROTOCOL from pickle import dumps, loads, HIGHEST_PROTOCOL
import asyncore, asynchat, socket, os, logging, sys, traceback, fcntl import asyncore, asynchat, socket, os, sys, traceback, fcntl
from .. import helpers from ..helpers import getLogger,formatExceptionInfo
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
if sys.version_info >= (3,): if sys.version_info >= (3,):
# b"" causes SyntaxError in python <= 2.5, so below implements equivalent # b"" causes SyntaxError in python <= 2.5, so below implements equivalent
@ -81,7 +81,7 @@ class RequestHandler(asynchat.async_chat):
self.close_when_done() self.close_when_done()
def handle_error(self): def handle_error(self):
e1, e2 = helpers.formatExceptionInfo() e1, e2 = formatExceptionInfo()
logSys.error("Unexpected communication error: %s" % str(e2)) logSys.error("Unexpected communication error: %s" % str(e2))
logSys.error(traceback.format_exc().splitlines()) logSys.error(traceback.format_exc().splitlines())
self.close() self.close()

View File

@ -24,14 +24,14 @@ __author__ = "Cyril Jaquier"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
import logging
from threading import Lock from threading import Lock
from .ticket import BanTicket from .ticket import BanTicket
from .mytime import MyTime from .mytime import MyTime
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
## ##
# Banning Manager. # Banning Manager.

View File

@ -21,7 +21,6 @@ __author__ = "Steven Hiscocks"
__copyright__ = "Copyright (c) 2013 Steven Hiscocks" __copyright__ = "Copyright (c) 2013 Steven Hiscocks"
__license__ = "GPL" __license__ = "GPL"
import logging
import sys import sys
import shutil, time import shutil, time
import sqlite3 import sqlite3
@ -32,9 +31,10 @@ from threading import Lock
from .mytime import MyTime from .mytime import MyTime
from .ticket import FailTicket from .ticket import FailTicket
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
if sys.version_info >= (3,): if sys.version_info >= (3,):
sqlite3.register_adapter( sqlite3.register_adapter(

View File

@ -21,13 +21,13 @@ __author__ = "Cyril Jaquier and Fail2Ban Contributors"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
import logging
from threading import Lock from threading import Lock
from .datetemplate import DatePatternRegex, DateTai64n, DateEpoch from .datetemplate import DatePatternRegex, DateTai64n, DateEpoch
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
class DateDetector(object): class DateDetector(object):
"""Manages one or more date templates to find a date within a log line. """Manages one or more date templates to find a date within a log line.

View File

@ -25,12 +25,12 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
import re import re
import logging
from abc import abstractmethod from abc import abstractmethod
from .strptime import reGroupDictStrptime, timeRE from .strptime import reGroupDictStrptime, timeRE
from ..helpers import getLogger
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
class DateTemplate(object): class DateTemplate(object):

View File

@ -24,10 +24,10 @@ __author__ = "Cyril Jaquier"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
import logging from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
class FailData: class FailData:

View File

@ -29,9 +29,10 @@ import logging
from .faildata import FailData from .faildata import FailData
from .ticket import FailTicket from .ticket import FailTicket
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
class FailManager: class FailManager:

View File

@ -21,7 +21,7 @@ __author__ = "Cyril Jaquier and Fail2Ban Contributors"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenko" __copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenko"
__license__ = "GPL" __license__ = "GPL"
import logging, re, os, fcntl, sys, locale, codecs import re, os, fcntl, sys, locale, codecs
from .failmanager import FailManagerEmpty, FailManager from .failmanager import FailManagerEmpty, FailManager
from .ticket import FailTicket from .ticket import FailTicket
@ -31,9 +31,10 @@ from .datetemplate import DatePatternRegex, DateEpoch, DateTai64n
from .mytime import MyTime from .mytime import MyTime
from .failregex import FailRegex, Regex, RegexException from .failregex import FailRegex, Regex, RegexException
from .action import CommandAction from .action import CommandAction
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
## ##
# Log reader class. # Log reader class.

View File

@ -23,16 +23,17 @@ __author__ = "Cyril Jaquier, Yaroslav Halchenko"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2012 Yaroslav Halchenko" __copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2012 Yaroslav Halchenko"
__license__ = "GPL" __license__ = "GPL"
import time, logging, fcntl import time, fcntl
import gamin import gamin
from .failmanager import FailManagerEmpty from .failmanager import FailManagerEmpty
from .filter import FileFilter from .filter import FileFilter
from .mytime import MyTime from .mytime import MyTime
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
## ##
# Log reader class. # Log reader class.

View File

@ -24,14 +24,15 @@ __author__ = "Cyril Jaquier, Yaroslav Halchenko"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier; 2012 Yaroslav Halchenko" __copyright__ = "Copyright (c) 2004 Cyril Jaquier; 2012 Yaroslav Halchenko"
__license__ = "GPL" __license__ = "GPL"
import time, logging, os import time, os
from .failmanager import FailManagerEmpty from .failmanager import FailManagerEmpty
from .filter import FileFilter from .filter import FileFilter
from .mytime import MyTime from .mytime import MyTime
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
## ##
# Log reader class. # Log reader class.

View File

@ -32,6 +32,7 @@ import pyinotify
from .failmanager import FailManagerEmpty from .failmanager import FailManagerEmpty
from .filter import FileFilter from .filter import FileFilter
from .mytime import MyTime from .mytime import MyTime
from ..helpers import getLogger
if not hasattr(pyinotify, '__version__') \ if not hasattr(pyinotify, '__version__') \
@ -48,7 +49,7 @@ except Exception, e:
% str(e)) % str(e))
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
## ##
# Log reader class. # Log reader class.

View File

@ -22,7 +22,7 @@ __author__ = "Steven Hiscocks"
__copyright__ = "Copyright (c) 2013 Steven Hiscocks" __copyright__ = "Copyright (c) 2013 Steven Hiscocks"
__license__ = "GPL" __license__ = "GPL"
import logging, datetime, time import datetime, time
from distutils.version import LooseVersion from distutils.version import LooseVersion
from systemd import journal from systemd import journal
@ -32,10 +32,10 @@ if LooseVersion(getattr(journal, '__version__', "0")) < '204':
from .failmanager import FailManagerEmpty from .failmanager import FailManagerEmpty
from .filter import JournalFilter from .filter import JournalFilter
from .mytime import MyTime from .mytime import MyTime
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger("fail2ban.filter") logSys = getLogger(__name__)
## ##
# Journal reader class. # Journal reader class.

View File

@ -26,9 +26,10 @@ __license__ = "GPL"
import Queue, logging import Queue, logging
from .actions import Actions from .actions import Actions
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
class Jail: class Jail:
"""Fail2Ban jail, which manages a filter and associated actions. """Fail2Ban jail, which manages a filter and associated actions.

View File

@ -24,9 +24,12 @@ __author__ = "Cyril Jaquier"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
import sys
from threading import Thread from threading import Thread
from abc import abstractproperty, abstractmethod from abc import abstractproperty, abstractmethod
from ..helpers import excepthook
class JailThread(Thread): class JailThread(Thread):
"""Abstract class for threading elements in Fail2Ban. """Abstract class for threading elements in Fail2Ban.
@ -53,6 +56,16 @@ class JailThread(Thread):
## The time the thread sleeps in the loop. ## The time the thread sleeps in the loop.
self.sleeptime = 1 self.sleeptime = 1
# excepthook workaround for threads, derived from:
# http://bugs.python.org/issue1230540#msg91244
run = self.run
def run_with_except_hook(*args, **kwargs):
try:
run(*args, **kwargs)
except:
excepthook(*sys.exc_info())
self.run = run_with_except_hook
@abstractproperty @abstractproperty
def status(self): # pragma: no cover - abstract def status(self): # pragma: no cover - abstract
"""Abstract - Should provide status information. """Abstract - Should provide status information.

View File

@ -32,9 +32,10 @@ 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
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
try: try:
from .database import Fail2BanDb from .database import Fail2BanDb
@ -69,6 +70,9 @@ class Server:
signal.signal(signal.SIGTERM, self.__sigTERMhandler) signal.signal(signal.SIGTERM, self.__sigTERMhandler)
signal.signal(signal.SIGINT, self.__sigTERMhandler) signal.signal(signal.SIGINT, self.__sigTERMhandler)
# Ensure unhandled exceptions are logged
sys.excepthook = excepthook
# First set the mask to only allow access to owner # First set the mask to only allow access to owner
os.umask(0077) os.umask(0077)
if self.__daemon: # pragma: no cover if self.__daemon: # pragma: no cover
@ -335,7 +339,7 @@ class Server:
def setLogLevel(self, value): def setLogLevel(self, value):
try: try:
self.__loggingLock.acquire() self.__loggingLock.acquire()
logging.getLogger(__name__).parent.parent.setLevel( getLogger("fail2ban").setLevel(
getattr(logging, value.upper())) getattr(logging, value.upper()))
except AttributeError: except AttributeError:
raise ValueError("Invalid log level") raise ValueError("Invalid log level")
@ -367,7 +371,7 @@ class Server:
try: try:
self.__loggingLock.acquire() self.__loggingLock.acquire()
# set a format which is simpler for console use # set a format which is simpler for console use
formatter = logging.Formatter("%(asctime)s %(name)-16s[%(process)d]: %(levelname)-7s %(message)s") formatter = logging.Formatter("%(asctime)s %(name)-24s[%(process)d]: %(levelname)-7s %(message)s")
if target == "SYSLOG": if target == "SYSLOG":
# Syslog daemons already add date to the message. # Syslog daemons already add date to the message.
formatter = logging.Formatter("%(name)s[%(process)d]: %(levelname)s %(message)s") formatter = logging.Formatter("%(name)s[%(process)d]: %(levelname)s %(message)s")
@ -388,7 +392,7 @@ class Server:
return False return False
# Removes previous handlers -- in reverse order since removeHandler # Removes previous handlers -- in reverse order since removeHandler
# alter the list in-place and that can confuses the iterable # alter the list in-place and that can confuses the iterable
logger = logging.getLogger(__name__).parent.parent logger = getLogger("fail2ban")
for handler in logger.handlers[::-1]: for handler in logger.handlers[::-1]:
# Remove the handler. # Remove the handler.
logger.removeHandler(handler) logger.removeHandler(handler)
@ -425,7 +429,7 @@ class Server:
def flushLogs(self): def flushLogs(self):
if self.__logTarget not in ['STDERR', 'STDOUT', 'SYSLOG']: if self.__logTarget not in ['STDERR', 'STDOUT', 'SYSLOG']:
for handler in logging.getLogger(__name__).parent.parent.handlers: for handler in getLogger("fail2ban").handlers:
try: try:
handler.doRollover() handler.doRollover()
logSys.info("rollover performed on %s" % self.__logTarget) logSys.info("rollover performed on %s" % self.__logTarget)
@ -434,7 +438,7 @@ class Server:
logSys.info("flush performed on %s" % self.__logTarget) logSys.info("flush performed on %s" % self.__logTarget)
return "rolled over" return "rolled over"
else: else:
for handler in logging.getLogger(__name__).parent.parent.handlers: for handler in getLogger("fail2ban").handlers:
handler.flush() handler.flush()
logSys.info("flush performed on %s" % self.__logTarget) logSys.info("flush performed on %s" % self.__logTarget)
return "flushed" return "flushed"

View File

@ -24,10 +24,10 @@ __author__ = "Cyril Jaquier"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
import logging from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
class Ticket: class Ticket:

View File

@ -24,11 +24,13 @@ __author__ = "Cyril Jaquier"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
import logging, time import time
import json import json
from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
class Transmitter: class Transmitter:

View File

@ -1,14 +1,14 @@
# failJSON: { "time": "2006-02-13T15:52:30", "match": true , "host": "1.2.3.4" } # failJSON: { "time": "2006-02-13T15:52:30", "match": true , "host": "1.2.3.4" }
2006-02-13 15:52:30,388 fail2ban.server.actions: NOTICE [sendmail] Ban 1.2.3.4 2006-02-13 15:52:30,388 fail2ban.actions: NOTICE [sendmail] Ban 1.2.3.4
# failJSON: { "time": "2006-02-13T15:52:30", "match": true , "host": "1.2.3.4", "desc": "Extended with [PID]" } # failJSON: { "time": "2006-02-13T15:52:30", "match": true , "host": "1.2.3.4", "desc": "Extended with [PID]" }
2006-02-13 15:52:30,388 fail2ban.server.actions[123]: NOTICE [sendmail] Ban 1.2.3.4 2006-02-13 15:52:30,388 fail2ban.actions[123]: NOTICE [sendmail] Ban 1.2.3.4
# failJSON: { "match": false } # failJSON: { "match": false }
2006-02-13 16:07:31,183 fail2ban.server.actions: NOTICE [sendmail] Unban 1.2.3.4 2006-02-13 16:07:31,183 fail2ban.actions: NOTICE [sendmail] Unban 1.2.3.4
# failJSON: { "match": false } # failJSON: { "match": false }
2006-02-13 15:52:30,388 fail2ban.server.actions: NOTICE [recidive] Ban 1.2.3.4 2006-02-13 15:52:30,388 fail2ban.actions: NOTICE [recidive] Ban 1.2.3.4
# syslog example # syslog example
# failJSON: { "time": "2004-09-16T00:44:55", "match": true , "host": "10.0.0.7" } # failJSON: { "time": "2004-09-16T00:44:55", "match": true , "host": "10.0.0.7" }
Sep 16 00:44:55 spaceman fail2ban.server.actions: NOTICE [jail] Ban 10.0.0.7 Sep 16 00:44:55 spaceman fail2ban.actions: NOTICE [jail] Ban 10.0.0.7
# failJSON: { "time": "2006-02-13T15:52:30", "match": true , "host": "1.2.3.4", "desc": "Extended with [PID] and padding" } # failJSON: { "time": "2006-02-13T15:52:30", "match": true , "host": "1.2.3.4", "desc": "Extended with [PID] and padding" }
2006-02-13 15:52:30,388 fail2ban.server.actions[123]: NOTICE [sendmail] Ban 1.2.3.4 2006-02-13 15:52:30,388 fail2ban.actions [123]: NOTICE [sendmail] Ban 1.2.3.4

View File

@ -32,7 +32,7 @@ import datetime
from glob import glob from glob import glob
from StringIO import StringIO from StringIO import StringIO
from ..helpers import formatExceptionInfo, mbasename, TraceBack, FormatterWithTraceBack from ..helpers import formatExceptionInfo, mbasename, TraceBack, FormatterWithTraceBack, getLogger
from ..server.datetemplate import DatePatternRegex from ..server.datetemplate import DatePatternRegex
@ -159,7 +159,7 @@ class TestsUtilsTest(unittest.TestCase):
# and both types of traceback at once # and both types of traceback at once
fmt = ' %(tb)s | %(tbc)s : %(message)s' fmt = ' %(tb)s | %(tbc)s : %(message)s'
logSys = logging.getLogger("fail2ban_tests") logSys = getLogger("fail2ban_tests")
out = logging.StreamHandler(strout) out = logging.StreamHandler(strout)
out.setFormatter(Formatter(fmt)) out.setFormatter(Formatter(fmt))
logSys.addHandler(out) logSys.addHandler(out)

View File

@ -30,11 +30,13 @@ import tempfile
import os import os
import locale import locale
import sys import sys
import logging
from ..server.failregex import Regex, FailRegex, RegexException from ..server.failregex import Regex, FailRegex, RegexException
from ..server.server import Server from ..server.server import Server
from ..server.jail import Jail from ..server.jail import Jail
from ..server.jailthread import JailThread
from .utils import LogCaptureTestCase
from ..helpers import getLogger
try: try:
from ..server import filtersystemd from ..server import filtersystemd
@ -722,7 +724,7 @@ class TransmitterLogging(TransmitterBase):
os.close(f) os.close(f)
self.server.setLogLevel("WARNING") self.server.setLogLevel("WARNING")
self.assertEqual(self.transm.proceed(["set", "logtarget", fn]), (0, fn)) self.assertEqual(self.transm.proceed(["set", "logtarget", fn]), (0, fn))
l = logging.getLogger('fail2ban.server.server').parent.parent l = getLogger('fail2ban')
l.warning("Before file moved") l.warning("Before file moved")
try: try:
f2, fn2 = tempfile.mkstemp("fail2ban.log") f2, fn2 = tempfile.mkstemp("fail2ban.log")
@ -796,5 +798,19 @@ class RegexTests(unittest.TestCase):
self.assertTrue(fr.hasMatched()) self.assertTrue(fr.hasMatched())
self.assertRaises(RegexException, fr.getHost) self.assertRaises(RegexException, fr.getHost)
class _BadThread(JailThread):
def run(self):
int("cat")
class LoggingTests(LogCaptureTestCase):
def testGetF2BLogger(self):
testLogSys = getLogger("fail2ban.some.string.with.name")
self.assertEqual(testLogSys.parent.name, "fail2ban")
self.assertEqual(testLogSys.name, "fail2ban.name")
def testFail2BanExceptHook(self):
badThread = _BadThread()
badThread.start()
badThread.join()
self.assertTrue(self._is_logged("Unhandled exception"))

View File

@ -30,8 +30,9 @@ import unittest
from StringIO import StringIO from StringIO import StringIO
from ..server.mytime import MyTime from ..server.mytime import MyTime
from ..helpers import getLogger
logSys = logging.getLogger(__name__) logSys = getLogger(__name__)
def mtimesleep(): def mtimesleep():
# no sleep now should be necessary since polling tracks now not only # no sleep now should be necessary since polling tracks now not only
@ -89,6 +90,7 @@ def gatherTests(regexps=None, no_network=False):
tests.addTest(unittest.makeSuite(servertestcase.Transmitter)) tests.addTest(unittest.makeSuite(servertestcase.Transmitter))
tests.addTest(unittest.makeSuite(servertestcase.JailTests)) tests.addTest(unittest.makeSuite(servertestcase.JailTests))
tests.addTest(unittest.makeSuite(servertestcase.RegexTests)) tests.addTest(unittest.makeSuite(servertestcase.RegexTests))
tests.addTest(unittest.makeSuite(servertestcase.LoggingTests))
tests.addTest(unittest.makeSuite(actiontestcase.CommandActionTest)) tests.addTest(unittest.makeSuite(actiontestcase.CommandActionTest))
tests.addTest(unittest.makeSuite(actionstestcase.ExecuteActions)) tests.addTest(unittest.makeSuite(actionstestcase.ExecuteActions))
# FailManager # FailManager
@ -185,7 +187,7 @@ class LogCaptureTestCase(unittest.TestCase):
# For extended testing of what gets output into logging # For extended testing of what gets output into logging
# system, we will redirect it to a string # system, we will redirect it to a string
logSys = logging.getLogger("fail2ban") logSys = getLogger("fail2ban")
# Keep old settings # Keep old settings
self._old_level = logSys.level self._old_level = logSys.level
@ -198,7 +200,7 @@ class LogCaptureTestCase(unittest.TestCase):
def tearDown(self): def tearDown(self):
"""Call after every test case.""" """Call after every test case."""
# print "O: >>%s<<" % self._log.getvalue() # print "O: >>%s<<" % self._log.getvalue()
logSys = logging.getLogger("fail2ban") logSys = getLogger("fail2ban")
logSys.handlers = self._old_handlers logSys.handlers = self._old_handlers
logSys.level = self._old_level logSys.level = self._old_level