Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #1848 opentracing shim exception reporting #1878

4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Update protos to latest version release 0.9.0
([#1873](https://github.com/open-telemetry/opentelemetry-python/pull/1873))

### Fixed
- Updated `opentelementry-opentracing-shim` `ScopeShim` to report exceptions in
opentelemetry specification format, rather than opentracing spec format.

## [1.2.0, 0.21b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.2.0-0.21b0) - 2021-05-11

### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@
# pylint:disable=no-member

import logging
from typing import Optional, TypeVar, Union
from types import TracebackType
from typing import Optional, Type, TypeVar, Union

from deprecated import deprecated
from opentracing import (
Expand Down Expand Up @@ -401,16 +402,24 @@ def close(self):
ends the associated span**, regardless of the value passed in
*finish_on_close* when activating the span.
"""
self._end_span_scope(None, None, None)

detach(self._token)
def __exit__(self, exc_type, exc_val, exc_tb):
"""
Override the __exit__ method of `opentracing.scope.Scope` so we can report
exceptions correctly in opentelemetry specification format.
"""
self._end_span_scope(exc_type, exc_val, exc_tb)

def _end_span_scope(
self,
exc_type: Optional[Type[BaseException]],
exc_val: Optional[BaseException],
exc_tb: Optional[TracebackType],
) -> None:
detach(self._token)
if self._span_cm is not None:
# We don't have error information to pass to `__exit__()` so we
# pass `None` in all arguments. If the OpenTelemetry tracer
# implementation requires this information, the `__exit__()` method
# on `opentracing.Scope` should be overridden and modified to pass
# the relevant values to this `close()` method.
self._span_cm.__exit__(None, None, None)
self._span_cm.__exit__(exc_type, exc_val, exc_tb)
else:
self._span.unwrap().end()

Expand Down
25 changes: 22 additions & 3 deletions shim/opentelemetry-opentracing-shim/tests/test_shim.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# pylint:disable=no-member

import time
import traceback
from unittest import TestCase
from unittest.mock import Mock

Expand Down Expand Up @@ -475,12 +476,30 @@ def test_span_on_error(self):
"""

# Raise an exception while a span is active.
with self.assertRaises(Exception):
with self.assertRaises(Exception) as exc_ctx:
with self.shim.start_active_span("TestName") as scope:
raise Exception
raise Exception("bad thing")

ex = exc_ctx.exception
expected_stack = "".join(
traceback.format_exception(
etype=type(ex), value=ex, tb=ex.__traceback__
)
)
# Verify exception details have been added to span.
self.assertEqual(scope.span.unwrap().attributes["error"], True)
exc_event = scope.span.unwrap().events[0]

self.assertEqual(exc_event.name, "exception")
self.assertEqual(
exc_event.attributes["exception.message"], "bad thing"
)
self.assertEqual(
exc_event.attributes["exception.type"], Exception.__name__
)
# cannot get the whole stacktrace so just assert exception part is contained
self.assertIn(
expected_stack, exc_event.attributes["exception.stacktrace"]
)

def test_inject_http_headers(self):
"""Test `inject()` method for Format.HTTP_HEADERS."""
Expand Down