mirror of
https://github.com/open-telemetry/opentelemetry-python-contrib.git
synced 2025-07-28 20:52:57 +08:00
fix: Update falcon instrumentation to follow semantic conventions (#1824)
* fix: Update falcon instrumentation to follow semantic conventions * docs: Update changelog * fix linter errors * Disable falcon.HTTP_200 pylint checck --------- Co-authored-by: Shalev Roda <65566801+shalevr@users.noreply.github.com> Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
This commit is contained in:
@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Fixed
|
||||
|
||||
- Update falcon instrumentation to follow semantic conventions
|
||||
([#1824](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1824))
|
||||
|
||||
### Added
|
||||
|
||||
- Make Flask request span attributes available for `start_span`.
|
||||
|
@ -428,7 +428,6 @@ class _TraceMiddleware:
|
||||
|
||||
resource_name = resource.__class__.__name__
|
||||
span.set_attribute("falcon.resource", resource_name)
|
||||
span.update_name(f"{resource_name}.on_{req.method.lower()}")
|
||||
|
||||
def process_response(
|
||||
self, req, resp, resource, req_succeeded=None
|
||||
@ -483,6 +482,12 @@ class _TraceMiddleware:
|
||||
response_headers = resp.headers
|
||||
|
||||
if span.is_recording() and span.kind == trace.SpanKind.SERVER:
|
||||
# Check if low-cardinality route is available as per semantic-conventions
|
||||
if req.uri_template:
|
||||
span.update_name(f"{req.method} {req.uri_template}")
|
||||
else:
|
||||
span.update_name(f"{req.method}")
|
||||
|
||||
custom_attributes = (
|
||||
otel_wsgi.collect_custom_response_headers_attributes(
|
||||
response_headers.items()
|
||||
|
@ -61,6 +61,13 @@ class CustomResponseHeaderResource:
|
||||
resp.set_header("my-secret-header", "my-secret-value")
|
||||
|
||||
|
||||
class UserResource:
|
||||
def on_get(self, req, resp, user_id):
|
||||
# pylint: disable=no-member
|
||||
resp.status = falcon.HTTP_200
|
||||
resp.body = f"Hello user {user_id}"
|
||||
|
||||
|
||||
def make_app():
|
||||
_parsed_falcon_version = package_version.parse(falcon.__version__)
|
||||
if _parsed_falcon_version < package_version.parse("3.0.0"):
|
||||
@ -76,4 +83,6 @@ def make_app():
|
||||
app.add_route(
|
||||
"/test_custom_response_headers", CustomResponseHeaderResource()
|
||||
)
|
||||
app.add_route("/user/{user_id}", UserResource())
|
||||
|
||||
return app
|
||||
|
@ -110,7 +110,7 @@ class TestFalconInstrumentation(TestFalconBase, WsgiTestBase):
|
||||
spans = self.memory_exporter.get_finished_spans()
|
||||
self.assertEqual(len(spans), 1)
|
||||
span = spans[0]
|
||||
self.assertEqual(span.name, f"HelloWorldResource.on_{method.lower()}")
|
||||
self.assertEqual(span.name, f"{method} /hello")
|
||||
self.assertEqual(span.status.status_code, StatusCode.UNSET)
|
||||
self.assertEqual(
|
||||
span.status.description,
|
||||
@ -145,7 +145,7 @@ class TestFalconInstrumentation(TestFalconBase, WsgiTestBase):
|
||||
spans = self.memory_exporter.get_finished_spans()
|
||||
self.assertEqual(len(spans), 1)
|
||||
span = spans[0]
|
||||
self.assertEqual(span.name, "GET /does-not-exist")
|
||||
self.assertEqual(span.name, "GET")
|
||||
self.assertEqual(span.status.status_code, StatusCode.UNSET)
|
||||
self.assertSpanHasAttributes(
|
||||
span,
|
||||
@ -177,7 +177,7 @@ class TestFalconInstrumentation(TestFalconBase, WsgiTestBase):
|
||||
spans = self.memory_exporter.get_finished_spans()
|
||||
self.assertEqual(len(spans), 1)
|
||||
span = spans[0]
|
||||
self.assertEqual(span.name, "ErrorResource.on_get")
|
||||
self.assertEqual(span.name, "GET /error")
|
||||
self.assertFalse(span.status.is_ok)
|
||||
self.assertEqual(span.status.status_code, StatusCode.ERROR)
|
||||
self.assertEqual(
|
||||
@ -206,6 +206,33 @@ class TestFalconInstrumentation(TestFalconBase, WsgiTestBase):
|
||||
span.attributes[SpanAttributes.NET_PEER_IP], "127.0.0.1"
|
||||
)
|
||||
|
||||
def test_url_template(self):
|
||||
self.client().simulate_get("/user/123")
|
||||
spans = self.memory_exporter.get_finished_spans()
|
||||
self.assertEqual(len(spans), 1)
|
||||
span = spans[0]
|
||||
self.assertEqual(span.name, "GET /user/{user_id}")
|
||||
self.assertEqual(span.status.status_code, StatusCode.UNSET)
|
||||
self.assertEqual(
|
||||
span.status.description,
|
||||
None,
|
||||
)
|
||||
self.assertSpanHasAttributes(
|
||||
span,
|
||||
{
|
||||
SpanAttributes.HTTP_METHOD: "GET",
|
||||
SpanAttributes.HTTP_SERVER_NAME: "falconframework.org",
|
||||
SpanAttributes.HTTP_SCHEME: "http",
|
||||
SpanAttributes.NET_HOST_PORT: 80,
|
||||
SpanAttributes.HTTP_HOST: "falconframework.org",
|
||||
SpanAttributes.HTTP_TARGET: "/",
|
||||
SpanAttributes.NET_PEER_PORT: "65133",
|
||||
SpanAttributes.HTTP_FLAVOR: "1.1",
|
||||
"falcon.resource": "UserResource",
|
||||
SpanAttributes.HTTP_STATUS_CODE: 200,
|
||||
},
|
||||
)
|
||||
|
||||
def test_uninstrument(self):
|
||||
self.client().simulate_get(path="/hello")
|
||||
spans = self.memory_exporter.get_finished_spans()
|
||||
|
Reference in New Issue
Block a user