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:
		
							parent
							
								
									60753e2a55
								
							
						
					
					
						commit
						fe9405730f
					
				|  | @ -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() | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue