Index: twisted/python/syslog.py =================================================================== --- twisted/python/syslog.py (revision 43557) +++ twisted/python/syslog.py (working copy) @@ -10,6 +10,7 @@ syslog = __import__('syslog') +import logging from twisted.python import log # These defaults come from the Python syslog docs. @@ -16,6 +17,18 @@ DEFAULT_OPTIONS = 0 DEFAULT_FACILITY = syslog.LOG_USER +# Mappings to Python's syslog module +toSyslogLevelMapping = { + logging.DEBUG: syslog.LOG_DEBUG, + logging.INFO: syslog.LOG_INFO, + logging.WARN: syslog.LOG_WARNING, + logging.ERROR: syslog.LOG_ERR, + logging.CRITICAL: syslog.LOG_ALERT, +} +fromSyslogLevelMapping = dict((value, key) + for (key, value) + in toSyslogLevelMapping.items() + ) class SyslogObserver: @@ -49,7 +62,6 @@ """ self.openlog(prefix, options, facility) - def emit(self, eventDict): """ Send a message event to the I{syslog}. @@ -71,10 +83,18 @@ # Figure out what syslog parameters we might need to use. priority = syslog.LOG_INFO facility = 0 - if eventDict['isError']: - priority = syslog.LOG_ALERT + + # Set priority by loglevel and eventually + # override it if isError or syslogPriority is defined if 'syslogPriority' in eventDict: priority = int(eventDict['syslogPriority']) + elif 'logLevel' in eventDict: + priority = toSyslogLevelMapping.get( + eventDict['logLevel'], syslog.LOG_INFO) + elif eventDict['isError']: + # custom priority ovverrides isError + priority = syslog.LOG_ALERT + if 'syslogFacility' in eventDict: facility = int(eventDict['syslogFacility']) @@ -93,7 +113,6 @@ '[%s] %s' % (eventDict['system'], line)) - def startLogging(prefix='Twisted', options=DEFAULT_OPTIONS, facility=DEFAULT_FACILITY, setStdout=1): """ Index: twisted/python/test/test_syslog.py =================================================================== --- twisted/python/test/test_syslog.py (revision 43557) +++ twisted/python/test/test_syslog.py (working copy) @@ -4,6 +4,7 @@ from twisted.trial.unittest import TestCase from twisted.python.failure import Failure +import logging try: import syslog as stdsyslog except ImportError: @@ -149,3 +150,91 @@ self.events, [(stdsyslog.LOG_INFO, '[-] hello,'), (stdsyslog.LOG_INFO, '[-] \tworld')]) + + + def logLevelHarness(self, expected, actual): + """ + Raises exception if the evaluated syslogPriority + does not match the expected value. + """ + m = { + 'message': ('hello,\nworld\n\n',), + 'isError': False, + 'system': '-', + } + m.update(actual) + self.observer.emit(m) + self.assertEqual( + self.events, + [(expected, '[-] hello,'), + (expected, '[-] \tworld')]) + + + def test_emitLevelMissingLevelUseDefault(self): + """ + On missing logLevel defaults to stdsyslog.LOG_INFO + """ + expected, actual = stdsyslog.LOG_INFO, {} + self.logLevelHarness(expected, actual) + + + def test_emitLevelInvalidLevelUseDefault(self): + """ + On invalid logLevel defaults to stdsyslog.LOG_INFO + """ + expected, actual = stdsyslog.LOG_INFO, {'logLevel':'INVALID'} + self.logLevelHarness(expected, actual) + + + def test_emitLevelWARN(self): + """ + Logging levels are nicely mapped to syslog priorities + https://twistedmatrix.com/documents/14.0.0/core/howto/logging.html + """ + expected, actual = stdsyslog.LOG_WARNING, {'logLevel':logging.WARN} + self.logLevelHarness(expected, actual) + + + def test_emitLevelERR(self): + """ + Logging levels are nicely mapped to syslog priorities + https://twistedmatrix.com/documents/14.0.0/core/howto/logging.html + """ + expected, actual = stdsyslog.LOG_ERR, {'logLevel':logging.ERROR} + self.logLevelHarness(expected, actual) + + + def test_emitLevelDEBUG(self): + """ + Logging levels are nicely mapped to syslog priorities + https://twistedmatrix.com/documents/14.0.0/core/howto/logging.html + """ + expected, actual = stdsyslog.LOG_DEBUG, {'logLevel':logging.DEBUG} + self.logLevelHarness(expected, actual) + + + def test_emitLevelIsError(self): + """ + Messages with isError=True are mapped to LOG_ALERT + """ + expected, actual = stdsyslog.LOG_ALERT, {'isError':True} + self.logLevelHarness(expected, actual) + + + def test_emitLevelOvverrideIsError(self): + """ + Using logLevel ovverrides isError + """ + expected, actual = stdsyslog.LOG_INFO, {'isError':True, + 'logLevel':logging.INFO} + self.logLevelHarness(expected, actual) + + + def test_emitLevelPriorityOverridesLogLevel(self): + """ + Using syslogPriority overrides logLevel + """ + expected, actual = stdsyslog.LOG_ALERT, {'isError':False, + 'logLevel':logging.INFO,'syslogPriority': stdsyslog.LOG_ALERT} + self.logLevelHarness(expected, actual) +