Skip to content

Commit 1c68c79

Browse files
Merge branch 'main' into docs/google-genai-config-recording
2 parents 4cbeb1c + 2caa924 commit 1c68c79

3 files changed

Lines changed: 78 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2828
([#4341](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4341))
2929
- `opentelemetry-instrumentation-flask`: Stop reading the deprecated (from 3.1) `flask.__version__` attribute; resolve the Flask version via `importlib.metadata`
3030
([#4422](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4422))
31+
- `opentelemetry-instrumentation-celery`: Coerce non-string values to strings in `CeleryGetter.get()` to prevent `TypeError` in `TraceState.from_header()` when Celery request attributes contain ints
32+
([#4360](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4360))
33+
- `opentelemetry-instrumentation-aiohttp-server`: Use `canonical` attribute of the `Resource` as a span name
34+
([#3896](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3896))
3135

3236
### Breaking changes
3337

@@ -53,8 +57,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5357

5458
### Fixed
5559

56-
- `opentelemetry-instrumentation-celery`: Coerce non-string values to strings in `CeleryGetter.get()` to prevent `TypeError` in `TraceState.from_header()` when Celery request attributes contain ints
57-
([#4360](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4360))
5860
- `opentelemetry-docker-tests`: Replace deprecated `SpanAttributes` from `opentelemetry.semconv.trace` with `opentelemetry.semconv._incubating.attributes`
5961
([#4339](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4339))
6062
- `opentelemetry-instrumentation-confluent-kafka`: Skip `recv` span creation when `poll()` returns no message or `consume()` returns an empty list, avoiding empty spans on idle polls

instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/__init__.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,14 +252,21 @@ def _parse_duration_attrs(
252252

253253

254254
def get_default_span_name(request: web.Request) -> str:
255-
"""Default implementation for get_default_span_details
255+
"""Returns the span name.
256256
Args:
257257
request: the request object itself.
258258
Returns:
259-
The span name.
259+
The span name as "{method} {canonical_name}" of a resource if possible or just "{method}".
260260
"""
261-
span_name = request.path.strip() or f"HTTP {request.method}"
262-
return span_name
261+
try:
262+
resource = request.match_info.route.resource
263+
path = resource.canonical
264+
except AttributeError:
265+
path = ""
266+
267+
if path:
268+
return f"{request.method} {path}"
269+
return f"{request.method}"
263270

264271

265272
def _get_view_func(request: web.Request) -> str:

instrumentation/opentelemetry-instrumentation-aiohttp-server/tests/test_aiohttp_server_integration.py

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,15 @@ async def fixture_server_fixture(tracer, aiohttp_server, suppress):
143143
AioHttpServerInstrumentor().instrument(tracer_provider=tracer_provider)
144144

145145
app = aiohttp.web.Application()
146-
app.add_routes([aiohttp.web.get("/test-path", default_handler)])
146+
app.add_routes(
147+
[
148+
aiohttp.web.get("/test-path", default_handler),
149+
aiohttp.web.get("/test-path/{url_param}", default_handler),
150+
aiohttp.web.get(
151+
"/object/{object_id}/action/{another_param}", default_handler
152+
),
153+
]
154+
)
147155
if suppress:
148156
with suppress_http_instrumentation():
149157
server = await aiohttp_server(app)
@@ -198,6 +206,60 @@ async def test_status_code_instrumentation(
198206
assert url == span.attributes[HTTP_TARGET]
199207

200208

209+
@pytest.mark.asyncio
210+
@pytest.mark.parametrize(
211+
"span_name, example_paths",
212+
[
213+
(
214+
"GET /test-path/{url_param}",
215+
(
216+
"/test-path/foo",
217+
"/test-path/bar",
218+
),
219+
),
220+
(
221+
"GET /object/{object_id}/action/{another_param}",
222+
(
223+
"/object/1/action/bar",
224+
"/object/234/action/baz",
225+
),
226+
),
227+
(
228+
"GET",
229+
(
230+
"/i/dont/exist",
231+
"/me-neither",
232+
),
233+
),
234+
],
235+
)
236+
async def test_url_params_instrumentation(
237+
tracer,
238+
server_fixture,
239+
aiohttp_client,
240+
span_name,
241+
example_paths,
242+
):
243+
_, memory_exporter = tracer
244+
server, _ = server_fixture
245+
246+
assert len(memory_exporter.get_finished_spans()) == 0
247+
248+
client = await aiohttp_client(server)
249+
for path in example_paths:
250+
await client.get(path)
251+
252+
assert len(memory_exporter.get_finished_spans()) == 2
253+
254+
for request_path, span in zip(
255+
example_paths, memory_exporter.get_finished_spans()
256+
):
257+
assert span_name == span.name
258+
assert request_path == span.attributes[HTTP_TARGET]
259+
full_url = f"http://{server.host}:{server.port}{request_path}"
260+
assert full_url == span.attributes[HTTP_URL]
261+
262+
201263
@pytest.mark.asyncio
202264
@pytest.mark.parametrize("suppress", [True])
203265
async def test_suppress_instrumentation(

0 commit comments

Comments
 (0)