Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

- `opentelemetry-instrumentation-aiohttp-server`: Use `canonical` attribute of the `Resource` as a span name.
([#3896](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3896))

### Added

- `opentelemetry-instrumentation-aiohttp-client`: add support for url exclusions via `OTEL_PYTHON_EXCLUDED_URLS` / `OTEL_PYTHON_AIOHTTP_CLIENT_EXCLUDED_URLS`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,14 +238,20 @@ def _parse_active_request_count_attrs(req_attrs):


def get_default_span_name(request: web.Request) -> str:
"""Default implementation for get_default_span_details
"""Returns the span name.
Args:
request: the request object itself.
Returns:
The span name.
The canonical name of a resource if possible or just request path.
"""
span_name = request.path.strip() or f"HTTP {request.method}"
return span_name
path = request.path.strip()
try:
resource = request.match_info.route.resource
if resource:
path = resource.canonical
except AttributeError:
pass
return f"{request.method} {path}"


def _get_view_func(request: web.Request) -> str:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from opentelemetry.semconv._incubating.attributes.http_attributes import (
HTTP_METHOD,
HTTP_STATUS_CODE,
HTTP_TARGET,
HTTP_URL,
)
from opentelemetry.test.globals_test import (
Expand Down Expand Up @@ -106,7 +107,15 @@ async def fixture_server_fixture(tracer, aiohttp_server, suppress):
AioHttpServerInstrumentor().instrument()

app = aiohttp.web.Application()
app.add_routes([aiohttp.web.get("/test-path", default_handler)])
app.add_routes(
[
aiohttp.web.get("/test-path", default_handler),
aiohttp.web.get("/test-path/{url_param}", default_handler),
aiohttp.web.get(
"/object/{object_id}/action/{another_param}", default_handler
),
]
)
if suppress:
with suppress_http_instrumentation():
server = await aiohttp_server(app)
Expand Down Expand Up @@ -170,6 +179,53 @@ async def test_status_code_instrumentation(
)


@pytest.mark.asyncio
@pytest.mark.parametrize(
"span_name, example_paths",
[
(
"GET /test-path/{url_param}",
(
"/test-path/foo",
"/test-path/bar",
),
),
(
"GET /object/{object_id}/action/{another_param}",
(
"/object/1/action/bar",
"/object/234/action/baz",
),
),
],
)
async def test_url_params_instrumentation(
tracer,
server_fixture,
aiohttp_client,
span_name,
example_paths,
):
_, memory_exporter = tracer
server, _ = server_fixture

assert len(memory_exporter.get_finished_spans()) == 0

client = await aiohttp_client(server)
for path in example_paths:
await client.get(path)

assert len(memory_exporter.get_finished_spans()) == 2

for request_path, span in zip(
example_paths, memory_exporter.get_finished_spans()
):
assert span_name == span.name
assert request_path == span.attributes[HTTP_TARGET]
full_url = f"http://{server.host}:{server.port}{request_path}"
assert full_url == span.attributes[HTTP_URL]


@pytest.mark.asyncio
@pytest.mark.parametrize("suppress", [True])
async def test_suppress_instrumentation(
Expand Down