summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Gerasimov <nikita.gerasimov@oracle.com>2018-11-08 19:26:03 +0300
committerHervé Beraud <hberaud@redhat.com>2020-09-01 09:14:10 +0200
commit7b39c0bdf3a52d66df363de2884434204a8efe3f (patch)
tree44dd6f18bdfe677c3d803701258fd96a0593c1c8
parent7900aa42a22ea8962fb33af680f636c20bf39119 (diff)
downloadoslo-log-7b39c0bdf3a52d66df363de2884434204a8efe3f.tar.gz
Fix handling of exc_info in OSJournalHandler
exc_info is exception tuple not intended to be printed. It's using to generate output by logging.Formatter().formatException() instead. exc_text used to cache this output. So we use handler formatter to get string from exc_info and send it as EXCEPTION_INFO. EXCEPTION_TEXT is kept for backward compatibility. Also adds type validation for journal.send fields to unit tests. Known types could be gotten from journal.DEFAULT_CONVERTERS. The rest payload must be either a string or bytes. Change-Id: Idc0b9edc61b4ec39dc9df0ea8282cc104e4d83c0 Closes-Bug: 1802142 (cherry picked from commit a2956d7ff08f7657dc68c78f860bcc9eb2e5a8fb)
-rw-r--r--oslo_log/handlers.py11
-rw-r--r--oslo_log/tests/unit/test_log.py26
2 files changed, 30 insertions, 7 deletions
diff --git a/oslo_log/handlers.py b/oslo_log/handlers.py
index e8bc594..d602842 100644
--- a/oslo_log/handlers.py
+++ b/oslo_log/handlers.py
@@ -131,12 +131,17 @@ class OSJournalHandler(logging.Handler):
'PRIORITY': priority
}
+ if record.exc_info:
+ # Cache the traceback text to avoid converting it multiple times
+ # (it's constant anyway)
+ if not record.exc_text:
+ record.exc_text = self.formatter.formatException(
+ record.exc_info)
if record.exc_text:
+ extras['EXCEPTION_INFO'] = record.exc_text
+ # Leave EXCEPTION_TEXT for backward compatibility
extras['EXCEPTION_TEXT'] = record.exc_text
- if record.exc_info:
- extras['EXCEPTION_INFO'] = record.exc_info
-
for field in self.custom_fields:
value = record.__dict__.get(field)
if value:
diff --git a/oslo_log/tests/unit/test_log.py b/oslo_log/tests/unit/test_log.py
index 84950a4..4d23daa 100644
--- a/oslo_log/tests/unit/test_log.py
+++ b/oslo_log/tests/unit/test_log.py
@@ -327,7 +327,6 @@ class OSJournalHandlerTestCase(BaseTestCase):
local_context = _fake_new_context()
l.info("Foo", context=local_context)
self.assertEqual(
- self.journal.send.call_args,
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,
@@ -336,7 +335,17 @@ class OSJournalHandlerTestCase(BaseTestCase):
PROJECT_NAME='mytenant',
PROCESS_NAME='MainProcess',
THREAD_NAME='MainThread',
- USER_NAME='myuser'))
+ USER_NAME='myuser'),
+ self.journal.send.call_args)
+ args, kwargs = self.journal.send.call_args
+ self.assertEqual(len(args), 1)
+ self.assertIsInstance(args[0], six.string_types)
+ self.assertIsInstance(kwargs['CODE_LINE'], int)
+ self.assertIsInstance(kwargs['PRIORITY'], int)
+ del kwargs['CODE_LINE'], kwargs['PRIORITY']
+ for key, arg in kwargs.items():
+ self.assertIsInstance(key, six.string_types)
+ self.assertIsInstance(arg, six.string_types + (six.binary_type,))
def test_emit_exception(self):
l = log.getLogger('nova-exception.foo')
@@ -346,7 +355,6 @@ class OSJournalHandlerTestCase(BaseTestCase):
except Exception:
l.exception("Foo", context=local_context)
self.assertEqual(
- self.journal.send.call_args,
mock.call(mock.ANY, CODE_FILE=mock.ANY,
CODE_FUNC='test_emit_exception',
CODE_LINE=mock.ANY, LOGGER_LEVEL='ERROR',
@@ -358,7 +366,17 @@ class OSJournalHandlerTestCase(BaseTestCase):
PROJECT_NAME='mytenant',
PROCESS_NAME='MainProcess',
THREAD_NAME='MainThread',
- USER_NAME='myuser'))
+ USER_NAME='myuser'),
+ self.journal.send.call_args)
+ args, kwargs = self.journal.send.call_args
+ self.assertEqual(len(args), 1)
+ self.assertIsInstance(args[0], six.string_types)
+ self.assertIsInstance(kwargs['CODE_LINE'], int)
+ self.assertIsInstance(kwargs['PRIORITY'], int)
+ del kwargs['CODE_LINE'], kwargs['PRIORITY']
+ for key, arg in kwargs.items():
+ self.assertIsInstance(key, six.string_types)
+ self.assertIsInstance(arg, six.string_types + (six.binary_type,))
class LogLevelTestCase(BaseTestCase):