Skip to content

Commit eb8ecae

Browse files
committed
code change to resolve the bug open-telemetry#449
1 parent 76386a8 commit eb8ecae

File tree

2 files changed

+55
-9
lines changed

2 files changed

+55
-9
lines changed

Diff for: instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py

+23-9
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,20 @@
2020
from pyramid.tweens import EXCVIEW
2121

2222
import opentelemetry.instrumentation.wsgi as otel_wsgi
23-
from opentelemetry import context, trace
23+
from opentelemetry import context
2424
from opentelemetry.instrumentation.propagators import (
2525
get_global_response_propagator,
2626
)
2727
from opentelemetry.instrumentation.pyramid.version import __version__
2828
from opentelemetry.propagate import extract
2929
from opentelemetry.semconv.trace import SpanAttributes
30+
from opentelemetry.trace import (
31+
INVALID_SPAN,
32+
SpanKind,
33+
get_current_span,
34+
get_tracer,
35+
use_span,
36+
)
3037
from opentelemetry.util._time import _time_ns
3138
from opentelemetry.util.http import get_excluded_urls
3239

@@ -82,19 +89,24 @@ def _before_traversal(event):
8289

8390
start_time = request_environ.get(_ENVIRON_STARTTIME_KEY)
8491

85-
token = context.attach(
86-
extract(request_environ, getter=otel_wsgi.wsgi_getter)
87-
)
88-
tracer = trace.get_tracer(__name__, __version__)
92+
token = ctx = None
93+
span_kind = SpanKind.INTERNAL
94+
tracer = get_tracer(__name__, __version__)
8995

9096
if request.matched_route:
9197
span_name = request.matched_route.pattern
9298
else:
9399
span_name = otel_wsgi.get_default_span_name(request_environ)
94100

101+
if get_current_span() is INVALID_SPAN:
102+
ctx = extract(request_environ, getter=otel_wsgi.wsgi_getter)
103+
token = context.attach(ctx)
104+
span_kind = SpanKind.SERVER
105+
95106
span = tracer.start_span(
96107
span_name,
97-
kind=trace.SpanKind.SERVER,
108+
ctx,
109+
kind=span_kind,
98110
start_time=start_time,
99111
)
100112

@@ -107,11 +119,12 @@ def _before_traversal(event):
107119
for key, value in attributes.items():
108120
span.set_attribute(key, value)
109121

110-
activation = trace.use_span(span, end_on_exit=True)
122+
activation = use_span(span, end_on_exit=True)
111123
activation.__enter__() # pylint: disable=E1101
112124
request_environ[_ENVIRON_ACTIVATION_KEY] = activation
113125
request_environ[_ENVIRON_SPAN_KEY] = span
114-
request_environ[_ENVIRON_TOKEN] = token
126+
if token:
127+
request_environ[_ENVIRON_TOKEN] = token
115128

116129

117130
def trace_tween_factory(handler, registry):
@@ -180,7 +193,8 @@ def trace_tween(request):
180193
else:
181194
activation.__exit__(None, None, None)
182195

183-
context.detach(request.environ.get(_ENVIRON_TOKEN))
196+
if request.environ.get(_ENVIRON_TOKEN, None) is not None:
197+
context.detach(request.environ.get(_ENVIRON_TOKEN))
184198

185199
return response
186200

Diff for: instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py

+32
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from opentelemetry.instrumentation.pyramid import PyramidInstrumentor
1818
from opentelemetry.test.test_base import TestBase
1919
from opentelemetry.test.wsgitestutil import WsgiTestBase
20+
from opentelemetry.trace import SpanKind
2021

2122
# pylint: disable=import-error
2223
from .pyramid_base_test import InstrumentationTest
@@ -77,3 +78,34 @@ def test_tween_list(self):
7778
self.assertEqual([b"Hello: 123"], list(resp.response))
7879
span_list = self.memory_exporter.get_finished_spans()
7980
self.assertEqual(len(span_list), 1)
81+
82+
83+
class TestWrappedWithOtherFramework(
84+
InstrumentationTest, TestBase, WsgiTestBase
85+
):
86+
def setUp(self):
87+
super().setUp()
88+
PyramidInstrumentor().instrument()
89+
self.config = Configurator()
90+
self._common_initialization(self.config)
91+
92+
def tearDown(self) -> None:
93+
super().tearDown()
94+
with self.disable_logging():
95+
PyramidInstrumentor().uninstrument()
96+
97+
def test_with_existing_span(self):
98+
tracer_provider, _ = self.create_tracer_provider()
99+
tracer = tracer_provider.get_tracer(__name__)
100+
101+
with tracer.start_as_current_span(
102+
"test", kind=SpanKind.SERVER
103+
) as parent_span:
104+
resp = self.client.get("/hello/123")
105+
self.assertEqual(200, resp.status_code)
106+
span_list = self.memory_exporter.get_finished_spans()
107+
self.assertEqual(SpanKind.INTERNAL, span_list[0].kind)
108+
self.assertEqual(
109+
parent_span.get_span_context().span_id,
110+
span_list[0].parent.span_id,
111+
)

0 commit comments

Comments
 (0)