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

code changes to resolve conditional server span creation for WSGI and adding 'attributes' parameter to util function #903

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased](https://github.com/open-telemetry/opentelemetry-python/compare/v1.9.1-0.28b1...HEAD)

- `opentelemetry-instrumentation-wsgi` WSGI: Conditionally create SERVER spans
([#903](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/903))

### Fixed

- `opentelemetry-instrumentation-logging` retrieves service name defensively.
Expand All @@ -21,7 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `opentelemetry-instrumentation-pika` requires `packaging` dependency

- `opentelemetry-instrumentation-tornado` Tornado: Conditionally create SERVER spans
([#867](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/889))
([#889](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/889))

## [1.9.0-0.28b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.9.0-0.28b0) - 2022-01-26

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,11 @@ def response_hook(span: Span, environ: WSGIEnvironment, status: str, response_he
import wsgiref.util as wsgiref_util

from opentelemetry import context, trace
from opentelemetry.instrumentation.utils import http_status_to_status_code
from opentelemetry.instrumentation.utils import (
_start_internal_or_server_span,
http_status_to_status_code,
)
from opentelemetry.instrumentation.wsgi.version import __version__
from opentelemetry.propagate import extract
from opentelemetry.propagators.textmap import Getter
from opentelemetry.semconv.trace import SpanAttributes
from opentelemetry.trace.status import Status, StatusCode
Expand Down Expand Up @@ -279,12 +281,12 @@ def __call__(self, environ, start_response):
environ: A WSGI environment.
start_response: The WSGI start_response callable.
"""

token = context.attach(extract(environ, getter=wsgi_getter))
owais marked this conversation as resolved.
Show resolved Hide resolved

span = self.tracer.start_span(
get_default_span_name(environ),
kind=trace.SpanKind.SERVER,
span, token = _start_internal_or_server_span(
tracer=self.tracer,
span_name=get_default_span_name(environ),
start_time=None,
context_carrier=environ,
context_getter=wsgi_getter,
attributes=collect_request_attributes(environ),
)

Expand All @@ -308,7 +310,8 @@ def __call__(self, environ, start_response):
if span.is_recording():
span.set_status(Status(StatusCode.ERROR, str(ex)))
span.end()
context.detach(token)
if token is not None:
context.detach(token)
raise


Expand All @@ -324,7 +327,8 @@ def _end_span_after_iterating(iterable, span, tracer, token):
if close:
close()
span.end()
context.detach(token)
if token is not None:
context.detach(token)


# TODO: inherit from opentelemetry.instrumentation.propagators.Setter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -414,5 +414,35 @@ def test_basic_wsgi_call(self):
self.validate_response(response, exporter)


class TestWsgiMiddlewareWrappedWithAnotherFramework(WsgiTestBase):
def test_mark_span_internal_in_presence_of_span_from_other_framework(self):
tracer_provider, exporter = TestBase.create_tracer_provider()
tracer = tracer_provider.get_tracer(__name__)

with tracer.start_as_current_span(
"test", kind=trace_api.SpanKind.SERVER
) as parent_span:
app = otel_wsgi.OpenTelemetryMiddleware(
simple_wsgi, tracer_provider=tracer_provider
)
response = app(self.environ, self.start_response)
while True:
try:
value = next(response)
self.assertEqual(value, b"*")
except StopIteration:
break

span_list = exporter.get_finished_spans()

self.assertEqual(trace_api.SpanKind.INTERNAL, span_list[0].kind)
self.assertEqual(trace_api.SpanKind.SERVER, parent_span.kind)

# internal span should be child of the parent span we have provided
self.assertEqual(
parent_span.context.span_id, span_list[0].parent.span_id
)


if __name__ == "__main__":
unittest.main()
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@ def unwrap(obj, attr: str):


def _start_internal_or_server_span(
tracer, span_name, start_time, context_carrier, context_getter
tracer,
span_name,
start_time,
context_carrier,
context_getter,
attributes=None,
):
"""Returns internal or server span along with the token which can be used by caller to reset context

Expand Down Expand Up @@ -107,5 +112,6 @@ def _start_internal_or_server_span(
context=ctx,
kind=span_kind,
start_time=start_time,
attributes=attributes,
)
return span, token