Add missing SYSLOG_FACILITY to JournalHandler

Without SYSLOG_FACILITY log messages from journald forwards the message
to kern.log. This seems to be default behaviour as it treats the message
as kernel message.

This option provides a proper facility to the log message and kern.log
will not be filled up anymore.

Change-Id: I62a32ed46a400b62ead8c1e6e64acee658e2a769
Closes-Bug: #1871840
This commit is contained in:
Benjamin Reichel 2020-04-09 15:02:20 +02:00
parent 105eadbbac
commit 5b12e66f62
4 changed files with 29 additions and 8 deletions

View File

@ -82,13 +82,20 @@ class OSJournalHandler(logging.Handler):
'request_id', 'request_id',
) )
def __init__(self): def __init__(self, facility):
# Do not use super() unless type(logging.Handler) is 'type'
# (i.e. >= Python 2.7).
if not journal: if not journal:
raise RuntimeError("Systemd bindings do not exist") raise RuntimeError("Systemd bindings do not exist")
if not facility:
if not syslog:
raise RuntimeError("syslog is not available on this platform")
facility = syslog.LOG_USER
# Do not use super() unless type(logging.Handler) is 'type'
# (i.e. >= Python 2.7).
logging.Handler.__init__(self) logging.Handler.__init__(self)
self.binary_name = _get_binary_name() self.binary_name = _get_binary_name()
self.facility = facility
def emit(self, record): def emit(self, record):
priority = SYSLOG_MAP.get(record.levelname, 7) priority = SYSLOG_MAP.get(record.levelname, 7)
@ -103,7 +110,8 @@ class OSJournalHandler(logging.Handler):
'LOGGER_NAME': record.name, 'LOGGER_NAME': record.name,
'LOGGER_LEVEL': record.levelname, 'LOGGER_LEVEL': record.levelname,
'SYSLOG_IDENTIFIER': self.binary_name, 'SYSLOG_IDENTIFIER': self.binary_name,
'PRIORITY': priority 'PRIORITY': priority,
'SYSLOG_FACILITY': self.facility,
} }
if record.exc_info: if record.exc_info:

View File

@ -387,7 +387,10 @@ def _setup_logging_from_conf(conf, project, version):
log_root.addHandler(streamlog) log_root.addHandler(streamlog)
if conf.use_journal: if conf.use_journal:
journal = handlers.OSJournalHandler() if syslog is None:
raise RuntimeError("syslog is not available on this platform")
facility = _find_facility(conf.syslog_log_facility)
journal = handlers.OSJournalHandler(facility=facility)
log_root.addHandler(journal) log_root.addHandler(journal)
if conf.use_eventlog: if conf.use_eventlog:
@ -412,7 +415,6 @@ def _setup_logging_from_conf(conf, project, version):
log_root.addHandler(handler) log_root.addHandler(handler)
if conf.use_syslog: if conf.use_syslog:
global syslog
if syslog is None: if syslog is None:
raise RuntimeError("syslog is not available on this platform") raise RuntimeError("syslog is not available on this platform")
facility = _find_facility(conf.syslog_log_facility) facility = _find_facility(conf.syslog_log_facility)

View File

@ -398,6 +398,7 @@ class OSJournalHandlerTestCase(BaseTestCase):
mock.call(mock.ANY, CODE_FILE=mock.ANY, CODE_FUNC='test_emit', mock.call(mock.ANY, CODE_FILE=mock.ANY, CODE_FUNC='test_emit',
CODE_LINE=mock.ANY, LOGGER_LEVEL='INFO', CODE_LINE=mock.ANY, LOGGER_LEVEL='INFO',
LOGGER_NAME='nova-test.foo', PRIORITY=6, LOGGER_NAME='nova-test.foo', PRIORITY=6,
SYSLOG_FACILITY=syslog.LOG_USER,
SYSLOG_IDENTIFIER=mock.ANY, SYSLOG_IDENTIFIER=mock.ANY,
REQUEST_ID=mock.ANY, REQUEST_ID=mock.ANY,
PROJECT_NAME='mytenant', PROJECT_NAME='mytenant',
@ -410,7 +411,8 @@ class OSJournalHandlerTestCase(BaseTestCase):
self.assertIsInstance(args[0], str) self.assertIsInstance(args[0], str)
self.assertIsInstance(kwargs['CODE_LINE'], int) self.assertIsInstance(kwargs['CODE_LINE'], int)
self.assertIsInstance(kwargs['PRIORITY'], int) self.assertIsInstance(kwargs['PRIORITY'], int)
del kwargs['CODE_LINE'], kwargs['PRIORITY'] self.assertIsInstance(kwargs['SYSLOG_FACILITY'], int)
del kwargs['CODE_LINE'], kwargs['PRIORITY'], kwargs['SYSLOG_FACILITY']
for key, arg in kwargs.items(): for key, arg in kwargs.items():
self.assertIsInstance(key, str) self.assertIsInstance(key, str)
self.assertIsInstance(arg, (bytes, str)) self.assertIsInstance(arg, (bytes, str))
@ -427,6 +429,7 @@ class OSJournalHandlerTestCase(BaseTestCase):
CODE_FUNC='test_emit_exception', CODE_FUNC='test_emit_exception',
CODE_LINE=mock.ANY, LOGGER_LEVEL='ERROR', CODE_LINE=mock.ANY, LOGGER_LEVEL='ERROR',
LOGGER_NAME='nova-exception.foo', PRIORITY=3, LOGGER_NAME='nova-exception.foo', PRIORITY=3,
SYSLOG_FACILITY=syslog.LOG_USER,
SYSLOG_IDENTIFIER=mock.ANY, SYSLOG_IDENTIFIER=mock.ANY,
REQUEST_ID=mock.ANY, REQUEST_ID=mock.ANY,
EXCEPTION_INFO=mock.ANY, EXCEPTION_INFO=mock.ANY,
@ -441,7 +444,8 @@ class OSJournalHandlerTestCase(BaseTestCase):
self.assertIsInstance(args[0], str) self.assertIsInstance(args[0], str)
self.assertIsInstance(kwargs['CODE_LINE'], int) self.assertIsInstance(kwargs['CODE_LINE'], int)
self.assertIsInstance(kwargs['PRIORITY'], int) self.assertIsInstance(kwargs['PRIORITY'], int)
del kwargs['CODE_LINE'], kwargs['PRIORITY'] self.assertIsInstance(kwargs['SYSLOG_FACILITY'], int)
del kwargs['CODE_LINE'], kwargs['PRIORITY'], kwargs['SYSLOG_FACILITY']
for key, arg in kwargs.items(): for key, arg in kwargs.items():
self.assertIsInstance(key, str) self.assertIsInstance(key, str)
self.assertIsInstance(arg, (bytes, str)) self.assertIsInstance(arg, (bytes, str))

View File

@ -0,0 +1,7 @@
---
fixes:
- |
Using systemd journal handler, logs ending up in kern.log because
SYSLOG_FACILITY is missing. This fix uses the same facility configuration
option 'syslog-log-facility' as from syslog handler to provide the
missing value. (Bug #1871840)