1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

[opentelemetry][callback] enrich stacktrace errors (#3496)

* [opentelemetry][callback] refactor get_error_message and add UTs

* [opentelemetry][callback] enrich exception with msg, exception and stderr fields

* [opentelemetry] fix linting

* [opentelemetry][callback] add changelog fragment

* Apply suggestions from code review

Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* [opentelemetry][callback] chore: remove comment

* [opentelemetry][callback] refactor tests

* [opentelemetry] refactor UTs

Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
This commit is contained in:
Victor Martinez 2021-10-07 05:59:03 +01:00 committed by GitHub
parent 57e5f8c7be
commit e22fff2b12
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 7 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- opentelemetry callback plugin - enriched the stacktrace information with the ``message``, ``exception`` and ``stderr`` fields from the failed task (https://github.com/ansible-collections/community.general/pull/3496).

View file

@ -241,15 +241,10 @@ class OpenTelemetrySource(object):
res = host_data.result._result res = host_data.result._result
rc = res.get('rc', 0) rc = res.get('rc', 0)
if host_data.status == 'failed': if host_data.status == 'failed':
if res.get('exception') is not None: message = self.get_error_message(res)
message = res['exception'].strip().split('\n')[-1]
elif 'msg' in res:
message = res['msg']
else:
message = 'failed'
status = Status(status_code=StatusCode.ERROR, description=message) status = Status(status_code=StatusCode.ERROR, description=message)
# Record an exception with the task message # Record an exception with the task message
span.record_exception(BaseException(message)) span.record_exception(BaseException(self.enrich_error_message(res)))
elif host_data.status == 'skipped': elif host_data.status == 'skipped':
if 'skip_reason' in res: if 'skip_reason' in res:
message = res['skip_reason'] message = res['skip_reason']
@ -276,6 +271,24 @@ class OpenTelemetrySource(object):
if attributeValue is not None: if attributeValue is not None:
span.set_attribute(attributeName, attributeValue) span.set_attribute(attributeName, attributeValue)
@staticmethod
def get_error_message(result):
if result.get('exception') is not None:
return OpenTelemetrySource._last_line(result['exception'])
return result.get('msg', 'failed')
@staticmethod
def _last_line(text):
lines = text.strip().split('\n')
return lines[-1]
@staticmethod
def enrich_error_message(result):
message = result.get('msg', 'failed')
exception = result.get('exception')
stderr = result.get('stderr')
return ('message: "{0}"\nexception: "{1}"\nstderr: "{2}"').format(message, exception, stderr)
class CallbackModule(CallbackBase): class CallbackModule(CallbackBase):
""" """

View file

@ -91,3 +91,38 @@ class TestOpentelemetry(unittest.TestCase):
self.assertEqual(host_data.uuid, 'include') self.assertEqual(host_data.uuid, 'include')
self.assertEqual(host_data.name, 'include') self.assertEqual(host_data.name, 'include')
self.assertEqual(host_data.status, 'ok') self.assertEqual(host_data.status, 'ok')
def test_get_error_message(self):
test_cases = (
('my-exception', 'my-msg', None, 'my-exception'),
(None, 'my-msg', None, 'my-msg'),
(None, None, None, 'failed'),
)
for tc in test_cases:
result = self.opentelemetry.get_error_message(generate_test_data(tc[0], tc[1], tc[2]))
self.assertEqual(result, tc[3])
def test_enrich_error_message(self):
test_cases = (
('my-exception', 'my-msg', 'my-stderr', 'message: "my-msg"\nexception: "my-exception"\nstderr: "my-stderr"'),
('my-exception', None, 'my-stderr', 'message: "failed"\nexception: "my-exception"\nstderr: "my-stderr"'),
(None, 'my-msg', 'my-stderr', 'message: "my-msg"\nexception: "None"\nstderr: "my-stderr"'),
('my-exception', 'my-msg', None, 'message: "my-msg"\nexception: "my-exception"\nstderr: "None"'),
('my-exception', 'my-msg', '\nline1\nline2', 'message: "my-msg"\nexception: "my-exception"\nstderr: "\nline1\nline2"')
)
for tc in test_cases:
result = self.opentelemetry.enrich_error_message(generate_test_data(tc[0], tc[1], tc[2]))
self.assertEqual(result, tc[3])
def generate_test_data(exception=None, msg=None, stderr=None):
res_data = OrderedDict()
if exception:
res_data['exception'] = exception
if msg:
res_data['msg'] = msg
if stderr:
res_data['stderr'] = stderr
return res_data