Skip to content

Commit

Permalink
fix: Update falcon instrumentation to follow semantic conventions (#1824
Browse files Browse the repository at this point in the history
)

* 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>
  • Loading branch information
3 people committed Jun 20, 2023
1 parent 60753e2 commit fe94057
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,6 @@ def process_resource(self, req, resp, resource, params):

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
Expand Down Expand Up @@ -483,6 +482,12 @@ def process_response(
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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ def on_get(self, _, resp):
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"):
Expand All @@ -76,4 +83,6 @@ def make_app():
app.add_route(
"/test_custom_response_headers", CustomResponseHeaderResource()
)
app.add_route("/user/{user_id}", UserResource())

return app
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def _test_method(self, method):
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,
Expand Down Expand Up @@ -145,7 +145,7 @@ def test_404(self):
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,
Expand Down Expand Up @@ -177,7 +177,7 @@ def test_500(self):
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(
Expand Down Expand Up @@ -206,6 +206,33 @@ def test_500(self):
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()
Expand Down

0 comments on commit fe94057

Please sign in to comment.