Skip to content

Commit

Permalink
pyramid: change from sdk span (http) to registered entry span (wsgi)
Browse files Browse the repository at this point in the history
Signed-off-by: Varsha GS <varsha.gs@ibm.com>
  • Loading branch information
Varsha GS authored and GSVarsha committed Sep 21, 2024
1 parent 480ff09 commit 863cf9b
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 129 deletions.
2 changes: 1 addition & 1 deletion src/instana/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,12 @@ def boot_agent():
psycopg2, # noqa: F401
pymongo, # noqa: F401
pymysql, # noqa: F401
pyramid, # noqa: F401
redis, # noqa: F401
sqlalchemy, # noqa: F401
starlette_inst, # noqa: F401
sanic_inst, # noqa: F401
urllib3, # noqa: F401
pyramid_inst,
)
from instana.instrumentation.aiohttp import (
client, # noqa: F401
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def _extract_custom_headers(
for custom_header in agent.options.extra_http_headers:
if custom_header in headers:
span.set_attribute(
"http.header.%s" % custom_header, headers[custom_header]
f"http.header.{custom_header}", headers[custom_header]
)

except Exception:
Expand All @@ -50,7 +50,7 @@ def _extract_custom_headers(
def __call__(self, request: "Request") -> "Response":
ctx = tracer.extract(Format.HTTP_HEADERS, dict(request.headers))

with tracer.start_as_current_span("http", span_context=ctx) as span:
with tracer.start_as_current_span("wsgi", span_context=ctx) as span:
span.set_attribute("span.kind", SpanKind.SERVER)
span.set_attribute("http.host", request.host)
span.set_attribute(SpanAttributes.HTTP_METHOD, request.method)
Expand Down Expand Up @@ -78,32 +78,29 @@ def __call__(self, request: "Request") -> "Response":

tracer.inject(span.context, Format.HTTP_HEADERS, response.headers)
response.headers["Server-Timing"] = (
"intid;desc=%s" % span.context.trace_id
f"intid;desc={span.context.trace_id}"
)
except HTTPException as e:
response = e
raise
logger.debug(
"Pyramid InstanaTweenFactory HTTPException: ", exc_info=True
)
except BaseException as e:
span.set_attribute("http.status", 500)

# we need to explicitly populate the `message` tag with an error here
# so that it's picked up from an SDK span
span.set_attribute("message", str(e))
span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, 500)
span.record_exception(e)

logger.debug("Pyramid Instana tween", exc_info=True)
logger.debug(
"Pyramid InstanaTweenFactory BaseException: ", exc_info=True
)
finally:
if response:
span.set_attribute("http.status", response.status_int)
span.set_attribute(
SpanAttributes.HTTP_STATUS_CODE, response.status_int
)

if 500 <= response.status_int:
if response.exception is not None:
message = str(response.exception)
if response.exception:
span.record_exception(response.exception)
else:
message = response.status

span.set_attribute("message", message)
span.assure_errored()

return response
Expand Down
169 changes: 58 additions & 111 deletions tests/frameworks/test_pyramid.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ def test_get_request(self) -> None:
urllib3_span = spans[1]
test_span = spans[2]

assert response
assert response.status == 200

assert "X-INSTANA-T" in response.headers
Expand Down Expand Up @@ -75,23 +74,14 @@ def test_get_request(self) -> None:
assert not urllib3_span.ec
assert not pyramid_span.ec

# HTTP SDK span
assert pyramid_span.n == "sdk"

assert pyramid_span.data["sdk"]
assert pyramid_span.data["sdk"]["name"] == "http"
assert pyramid_span.data["sdk"]["type"] == "entry"

sdk_custom_attributes = pyramid_span.data["sdk"]["custom"]["attributes"]
assert (
"127.0.0.1:" + str(testenv["pyramid_port"])
== sdk_custom_attributes["http.host"]
)
assert sdk_custom_attributes["http.url"] == "/"
assert sdk_custom_attributes["http.method"] == "GET"
assert sdk_custom_attributes["http.status"] == 200
assert "message" not in sdk_custom_attributes
assert sdk_custom_attributes["http.path_tpl"] == "/"
# wsgi
assert pyramid_span.n == "wsgi"
assert pyramid_span.data["http"]["host"] == "127.0.0.1:" + str(testenv["pyramid_port"])
assert pyramid_span.data["http"]["url"] == "/"
assert pyramid_span.data["http"]["method"] == "GET"
assert pyramid_span.data["http"]["status"] == 200
assert not pyramid_span.data["http"]["error"]
assert pyramid_span.data["http"]["path_tpl"] == "/"

# urllib3
assert test_span.data["sdk"]["name"] == "test"
Expand All @@ -118,7 +108,6 @@ def test_synthetic_request(self) -> None:
urllib3_span = spans[1]
test_span = spans[2]

assert response
assert response.status == 200

assert pyramid_span.sy
Expand All @@ -137,7 +126,6 @@ def test_500(self) -> None:
urllib3_span = spans[1]
test_span = spans[2]

assert response
assert response.status == 500

assert "X-INSTANA-T" in response.headers
Expand Down Expand Up @@ -171,20 +159,13 @@ def test_500(self) -> None:
assert pyramid_span.ec == 1

# wsgi
assert pyramid_span.n == "sdk"
assert pyramid_span.data["sdk"]["name"] == "http"
assert pyramid_span.data["sdk"]["type"] == "entry"

sdk_custom_attributes = pyramid_span.data["sdk"]["custom"]["attributes"]
assert (
"127.0.0.1:" + str(testenv["pyramid_port"])
== sdk_custom_attributes["http.host"]
)
assert sdk_custom_attributes["http.url"] == "/500"
assert sdk_custom_attributes["http.method"] == "GET"
assert sdk_custom_attributes["http.status"] == 500
assert sdk_custom_attributes["message"] == "internal error"
assert sdk_custom_attributes["http.path_tpl"] == "/500"
assert pyramid_span.n == "wsgi"
assert pyramid_span.data["http"]["host"] == "127.0.0.1:" + str(testenv["pyramid_port"])
assert pyramid_span.data["http"]["url"] == "/500"
assert pyramid_span.data["http"]["method"] == "GET"
assert pyramid_span.data["http"]["status"] == 500
assert pyramid_span.data["http"]["error"] == "internal error"
assert pyramid_span.data["http"]["path_tpl"] == "/500"

# urllib3
assert test_span.data["sdk"]["name"] == "test"
Expand All @@ -210,7 +191,6 @@ def test_exception(self) -> None:
urllib3_span = spans[1]
test_span = spans[2]

assert response
assert response.status == 500

assert not get_current_span().is_recording()
Expand All @@ -228,21 +208,14 @@ def test_exception(self) -> None:
assert urllib3_span.ec == 1
assert pyramid_span.ec == 1

# HTTP SDK span
assert pyramid_span.n == "sdk"
assert pyramid_span.data["sdk"]["name"] == "http"
assert pyramid_span.data["sdk"]["type"] == "entry"

sdk_custom_attributes = pyramid_span.data["sdk"]["custom"]["attributes"]
assert (
"127.0.0.1:" + str(testenv["pyramid_port"])
== sdk_custom_attributes["http.host"]
)
assert sdk_custom_attributes["http.url"] == "/exception"
assert sdk_custom_attributes["http.method"] == "GET"
assert sdk_custom_attributes["http.status"] == 500
assert sdk_custom_attributes["message"] == "fake exception"
assert "http.path_tpl" not in sdk_custom_attributes
# wsgi
assert pyramid_span.n == "wsgi"
assert pyramid_span.data["http"]["host"] == "127.0.0.1:" + str(testenv["pyramid_port"])
assert pyramid_span.data["http"]["url"] == "/exception"
assert pyramid_span.data["http"]["method"] == "GET"
assert pyramid_span.data["http"]["status"] == 500
assert pyramid_span.data["http"]["error"] == "fake exception"
assert not pyramid_span.data["http"]["path_tpl"]

# urllib3
assert test_span.data["sdk"]["name"] == "test"
Expand Down Expand Up @@ -294,22 +267,14 @@ def test_response_header_capture(self) -> None:
assert not urllib3_span.ec
assert not pyramid_span.ec

# HTTP SDK span
assert pyramid_span.n == "sdk"

assert pyramid_span.data["sdk"]
assert pyramid_span.data["sdk"]["name"] == "http"
assert pyramid_span.data["sdk"]["type"] == "entry"

sdk_custom_attributes = pyramid_span.data["sdk"]["custom"]["attributes"]
assert (
"127.0.0.1:" + str(testenv["pyramid_port"])
== sdk_custom_attributes["http.host"]
)
assert sdk_custom_attributes["http.url"] == "/response_headers"
assert sdk_custom_attributes["http.method"] == "GET"
assert sdk_custom_attributes["http.status"] == 200
assert "message" not in sdk_custom_attributes
# wsgi
assert pyramid_span.n == "wsgi"
assert pyramid_span.data["http"]["host"] == "127.0.0.1:" + str(testenv["pyramid_port"])
assert pyramid_span.data["http"]["url"] == "/response_headers"
assert pyramid_span.data["http"]["method"] == "GET"
assert pyramid_span.data["http"]["status"] == 200
assert not pyramid_span.data["http"]["error"]
assert pyramid_span.data["http"]["path_tpl"] == "/response_headers"

# urllib3
assert test_span.data["sdk"]["name"] == "test"
Expand All @@ -324,10 +289,11 @@ def test_response_header_capture(self) -> None:
assert type(urllib3_span.stack) is list
assert len(urllib3_span.stack) > 1

assert sdk_custom_attributes["http.header.X-Capture-This"]
assert sdk_custom_attributes["http.header.X-Capture-This"] == "Ok"
assert sdk_custom_attributes["http.header.X-Capture-That"]
assert sdk_custom_attributes["http.header.X-Capture-That"] == "Ok too"
# custom headers
assert "X-Capture-This" in pyramid_span.data["http"]["header"]
assert pyramid_span.data["http"]["header"]["X-Capture-This"] == "Ok"
assert "X-Capture-That" in pyramid_span.data["http"]["header"]
assert pyramid_span.data["http"]["header"]["X-Capture-That"] == "Ok too"

agent.options.extra_http_headers = original_extra_http_headers

Expand All @@ -352,7 +318,6 @@ def test_request_header_capture(self) -> None:
urllib3_span = spans[1]
test_span = spans[2]

assert response
assert response.status == 200

# Same traceId
Expand All @@ -373,23 +338,14 @@ def test_request_header_capture(self) -> None:
assert not urllib3_span.ec
assert not pyramid_span.ec

# HTTP SDK span
assert pyramid_span.n == "sdk"

assert pyramid_span.data["sdk"]
assert pyramid_span.data["sdk"]["name"] == "http"
assert pyramid_span.data["sdk"]["type"] == "entry"

sdk_custom_attributes = pyramid_span.data["sdk"]["custom"]["attributes"]
assert (
"127.0.0.1:" + str(testenv["pyramid_port"])
== sdk_custom_attributes["http.host"]
)
assert sdk_custom_attributes["http.url"] == "/"
assert sdk_custom_attributes["http.method"] == "GET"
assert sdk_custom_attributes["http.status"] == 200
assert "message" not in sdk_custom_attributes
assert sdk_custom_attributes["http.path_tpl"] == "/"
# wsgi
assert pyramid_span.n == "wsgi"
assert pyramid_span.data["http"]["host"] == "127.0.0.1:" + str(testenv["pyramid_port"])
assert pyramid_span.data["http"]["url"] == "/"
assert pyramid_span.data["http"]["method"] == "GET"
assert pyramid_span.data["http"]["status"] == 200
assert not pyramid_span.data["http"]["error"]
assert pyramid_span.data["http"]["path_tpl"] == "/"

# urllib3
assert test_span.data["sdk"]["name"] == "test"
Expand All @@ -402,10 +358,10 @@ def test_request_header_capture(self) -> None:
assert len(urllib3_span.stack) > 1

# custom headers
assert sdk_custom_attributes["http.header.X-Capture-This-Too"]
assert sdk_custom_attributes["http.header.X-Capture-This-Too"] == "this too"
assert sdk_custom_attributes["http.header.X-Capture-That-Too"]
assert sdk_custom_attributes["http.header.X-Capture-That-Too"] == "that too"
assert "X-Capture-This-Too" in pyramid_span.data["http"]["header"]
assert pyramid_span.data["http"]["header"]["X-Capture-This-Too"] == "this too"
assert "X-Capture-That-Too" in pyramid_span.data["http"]["header"]
assert pyramid_span.data["http"]["header"]["X-Capture-That-Too"] == "that too"

agent.options.extra_http_headers = original_extra_http_headers

Expand Down Expand Up @@ -460,31 +416,22 @@ def test_scrub_secret_path_template(self) -> None:
assert not urllib3_span.ec
assert not pyramid_span.ec

# HTTP SDK span
assert pyramid_span.n == "sdk"

assert pyramid_span.data["sdk"]
assert pyramid_span.data["sdk"]["name"] == "http"
assert pyramid_span.data["sdk"]["type"] == "entry"

sdk_custom_attributes = pyramid_span.data["sdk"]["custom"]["attributes"]
assert (
"127.0.0.1:" + str(testenv["pyramid_port"])
== sdk_custom_attributes["http.host"]
)
assert sdk_custom_attributes["http.url"] == "/hello_user/oswald"
assert sdk_custom_attributes["http.method"] == "GET"
assert sdk_custom_attributes["http.status"] == 200
assert sdk_custom_attributes["http.params"] == "secret=<redacted>"
assert "message" not in sdk_custom_attributes
assert sdk_custom_attributes["http.path_tpl"] == "/hello_user/{user}"
# wsgi
assert pyramid_span.n == "wsgi"
assert pyramid_span.data["http"]["host"] == "127.0.0.1:" + str(testenv["pyramid_port"])
assert pyramid_span.data["http"]["url"] == "/hello_user/oswald"
assert pyramid_span.data["http"]["method"] == "GET"
assert pyramid_span.data["http"]["status"] == 200
assert pyramid_span.data["http"]["params"] == "secret=<redacted>"
assert not pyramid_span.data["http"]["error"]
assert pyramid_span.data["http"]["path_tpl"] == "/hello_user/{user}"

# urllib3
assert test_span.data["sdk"]["name"] == "test"
assert urllib3_span.n == "urllib3"
assert urllib3_span.data["http"]["status"] == 200
assert (
testenv["pyramid_server"] + sdk_custom_attributes["http.url"]
testenv["pyramid_server"] + pyramid_span.data["http"]["url"]
== urllib3_span.data["http"]["url"]
)
assert urllib3_span.data["http"]["method"] == "GET"
Expand Down

0 comments on commit 863cf9b

Please sign in to comment.