From 5b12e66f6283962d96884e4aa3fa7db7d4e062fa Mon Sep 17 00:00:00 2001 From: Benjamin Reichel Date: Thu, 9 Apr 2020 15:02:20 +0200 Subject: [PATCH] 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 --- oslo_log/handlers.py | 16 ++++++++++++---- oslo_log/log.py | 6 ++++-- oslo_log/tests/unit/test_log.py | 8 ++++++-- ...add-facility-to-journal-e10bf7002cc19dd3.yaml | 7 +++++++ 4 files changed, 29 insertions(+), 8 deletions(-) create mode 100644 releasenotes/notes/add-facility-to-journal-e10bf7002cc19dd3.yaml diff --git a/oslo_log/handlers.py b/oslo_log/handlers.py index 00ce64cc..1ed4e0ca 100644 --- a/oslo_log/handlers.py +++ b/oslo_log/handlers.py @@ -82,13 +82,20 @@ class OSJournalHandler(logging.Handler): 'request_id', ) - def __init__(self): - # Do not use super() unless type(logging.Handler) is 'type' - # (i.e. >= Python 2.7). + def __init__(self, facility): if not journal: 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) self.binary_name = _get_binary_name() + self.facility = facility def emit(self, record): priority = SYSLOG_MAP.get(record.levelname, 7) @@ -103,7 +110,8 @@ class OSJournalHandler(logging.Handler): 'LOGGER_NAME': record.name, 'LOGGER_LEVEL': record.levelname, 'SYSLOG_IDENTIFIER': self.binary_name, - 'PRIORITY': priority + 'PRIORITY': priority, + 'SYSLOG_FACILITY': self.facility, } if record.exc_info: diff --git a/oslo_log/log.py b/oslo_log/log.py index 6c6c1ff1..365034ac 100644 --- a/oslo_log/log.py +++ b/oslo_log/log.py @@ -387,7 +387,10 @@ def _setup_logging_from_conf(conf, project, version): log_root.addHandler(streamlog) 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) if conf.use_eventlog: @@ -412,7 +415,6 @@ def _setup_logging_from_conf(conf, project, version): log_root.addHandler(handler) if conf.use_syslog: - global syslog if syslog is None: raise RuntimeError("syslog is not available on this platform") facility = _find_facility(conf.syslog_log_facility) diff --git a/oslo_log/tests/unit/test_log.py b/oslo_log/tests/unit/test_log.py index 9d18f415..40c0916c 100644 --- a/oslo_log/tests/unit/test_log.py +++ b/oslo_log/tests/unit/test_log.py @@ -398,6 +398,7 @@ class OSJournalHandlerTestCase(BaseTestCase): mock.call(mock.ANY, CODE_FILE=mock.ANY, CODE_FUNC='test_emit', CODE_LINE=mock.ANY, LOGGER_LEVEL='INFO', LOGGER_NAME='nova-test.foo', PRIORITY=6, + SYSLOG_FACILITY=syslog.LOG_USER, SYSLOG_IDENTIFIER=mock.ANY, REQUEST_ID=mock.ANY, PROJECT_NAME='mytenant', @@ -410,7 +411,8 @@ class OSJournalHandlerTestCase(BaseTestCase): self.assertIsInstance(args[0], str) self.assertIsInstance(kwargs['CODE_LINE'], 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(): self.assertIsInstance(key, str) self.assertIsInstance(arg, (bytes, str)) @@ -427,6 +429,7 @@ class OSJournalHandlerTestCase(BaseTestCase): CODE_FUNC='test_emit_exception', CODE_LINE=mock.ANY, LOGGER_LEVEL='ERROR', LOGGER_NAME='nova-exception.foo', PRIORITY=3, + SYSLOG_FACILITY=syslog.LOG_USER, SYSLOG_IDENTIFIER=mock.ANY, REQUEST_ID=mock.ANY, EXCEPTION_INFO=mock.ANY, @@ -441,7 +444,8 @@ class OSJournalHandlerTestCase(BaseTestCase): self.assertIsInstance(args[0], str) self.assertIsInstance(kwargs['CODE_LINE'], 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(): self.assertIsInstance(key, str) self.assertIsInstance(arg, (bytes, str)) diff --git a/releasenotes/notes/add-facility-to-journal-e10bf7002cc19dd3.yaml b/releasenotes/notes/add-facility-to-journal-e10bf7002cc19dd3.yaml new file mode 100644 index 00000000..09fdd686 --- /dev/null +++ b/releasenotes/notes/add-facility-to-journal-e10bf7002cc19dd3.yaml @@ -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)