Skip to content

Commit fe94057

Browse files
Nek0trkstrshalevrsrikanthccv
authored
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 <[email protected]> Co-authored-by: Srikanth Chekuri <[email protected]>
1 parent 60753e2 commit fe94057

File tree

4 files changed

+50
-4
lines changed

4 files changed

+50
-4
lines changed

Diff for: CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
### Fixed
11+
12+
- Update falcon instrumentation to follow semantic conventions
13+
([#1824](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1824))
14+
1015
### Added
1116

1217
- Make Flask request span attributes available for `start_span`.

Diff for: instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,6 @@ def process_resource(self, req, resp, resource, params):
428428

429429
resource_name = resource.__class__.__name__
430430
span.set_attribute("falcon.resource", resource_name)
431-
span.update_name(f"{resource_name}.on_{req.method.lower()}")
432431

433432
def process_response(
434433
self, req, resp, resource, req_succeeded=None
@@ -483,6 +482,12 @@ def process_response(
483482
response_headers = resp.headers
484483

485484
if span.is_recording() and span.kind == trace.SpanKind.SERVER:
485+
# Check if low-cardinality route is available as per semantic-conventions
486+
if req.uri_template:
487+
span.update_name(f"{req.method} {req.uri_template}")
488+
else:
489+
span.update_name(f"{req.method}")
490+
486491
custom_attributes = (
487492
otel_wsgi.collect_custom_response_headers_attributes(
488493
response_headers.items()

Diff for: instrumentation/opentelemetry-instrumentation-falcon/tests/app.py

+9
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ def on_get(self, _, resp):
6161
resp.set_header("my-secret-header", "my-secret-value")
6262

6363

64+
class UserResource:
65+
def on_get(self, req, resp, user_id):
66+
# pylint: disable=no-member
67+
resp.status = falcon.HTTP_200
68+
resp.body = f"Hello user {user_id}"
69+
70+
6471
def make_app():
6572
_parsed_falcon_version = package_version.parse(falcon.__version__)
6673
if _parsed_falcon_version < package_version.parse("3.0.0"):
@@ -76,4 +83,6 @@ def make_app():
7683
app.add_route(
7784
"/test_custom_response_headers", CustomResponseHeaderResource()
7885
)
86+
app.add_route("/user/{user_id}", UserResource())
87+
7988
return app

Diff for: instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py

+30-3
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def _test_method(self, method):
110110
spans = self.memory_exporter.get_finished_spans()
111111
self.assertEqual(len(spans), 1)
112112
span = spans[0]
113-
self.assertEqual(span.name, f"HelloWorldResource.on_{method.lower()}")
113+
self.assertEqual(span.name, f"{method} /hello")
114114
self.assertEqual(span.status.status_code, StatusCode.UNSET)
115115
self.assertEqual(
116116
span.status.description,
@@ -145,7 +145,7 @@ def test_404(self):
145145
spans = self.memory_exporter.get_finished_spans()
146146
self.assertEqual(len(spans), 1)
147147
span = spans[0]
148-
self.assertEqual(span.name, "GET /does-not-exist")
148+
self.assertEqual(span.name, "GET")
149149
self.assertEqual(span.status.status_code, StatusCode.UNSET)
150150
self.assertSpanHasAttributes(
151151
span,
@@ -177,7 +177,7 @@ def test_500(self):
177177
spans = self.memory_exporter.get_finished_spans()
178178
self.assertEqual(len(spans), 1)
179179
span = spans[0]
180-
self.assertEqual(span.name, "ErrorResource.on_get")
180+
self.assertEqual(span.name, "GET /error")
181181
self.assertFalse(span.status.is_ok)
182182
self.assertEqual(span.status.status_code, StatusCode.ERROR)
183183
self.assertEqual(
@@ -206,6 +206,33 @@ def test_500(self):
206206
span.attributes[SpanAttributes.NET_PEER_IP], "127.0.0.1"
207207
)
208208

209+
def test_url_template(self):
210+
self.client().simulate_get("/user/123")
211+
spans = self.memory_exporter.get_finished_spans()
212+
self.assertEqual(len(spans), 1)
213+
span = spans[0]
214+
self.assertEqual(span.name, "GET /user/{user_id}")
215+
self.assertEqual(span.status.status_code, StatusCode.UNSET)
216+
self.assertEqual(
217+
span.status.description,
218+
None,
219+
)
220+
self.assertSpanHasAttributes(
221+
span,
222+
{
223+
SpanAttributes.HTTP_METHOD: "GET",
224+
SpanAttributes.HTTP_SERVER_NAME: "falconframework.org",
225+
SpanAttributes.HTTP_SCHEME: "http",
226+
SpanAttributes.NET_HOST_PORT: 80,
227+
SpanAttributes.HTTP_HOST: "falconframework.org",
228+
SpanAttributes.HTTP_TARGET: "/",
229+
SpanAttributes.NET_PEER_PORT: "65133",
230+
SpanAttributes.HTTP_FLAVOR: "1.1",
231+
"falcon.resource": "UserResource",
232+
SpanAttributes.HTTP_STATUS_CODE: 200,
233+
},
234+
)
235+
209236
def test_uninstrument(self):
210237
self.client().simulate_get(path="/hello")
211238
spans = self.memory_exporter.get_finished_spans()

0 commit comments

Comments
 (0)