Skip to content

Commit bfc3460

Browse files
fix: PAAL-206 remove telemetry filter
1 parent 58d4a6f commit bfc3460

File tree

4 files changed

+7
-131
lines changed

4 files changed

+7
-131
lines changed

adk/agenticlayer/agent_to_a2a.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
from google.adk.memory.in_memory_memory_service import InMemoryMemoryService
1717
from google.adk.runners import Runner
1818
from google.adk.sessions.in_memory_session_service import InMemorySessionService
19+
from opentelemetry.instrumentation.starlette import StarletteInstrumentor
20+
from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware
1921
from starlette.applications import Starlette
2022

2123
from .callback_tracer_plugin import CallbackTracerPlugin
@@ -106,10 +108,12 @@ async def lifespan(app: Starlette) -> AsyncIterator[None]:
106108
# Create a Starlette app that will be configured during startup
107109
starlette_app = Starlette(lifespan=lifespan)
108110

109-
# Add TelemetryFilter to exclude health check telemetry
111+
# Add OpenTelemetryMiddleware to exclude health check telemetry
110112
starlette_app.add_middleware(
111-
TelemetryFilter, # type: ignore[arg-type]
112-
filtered_paths={AGENT_CARD_WELL_KNOWN_PATH},
113+
OpenTelemetryMiddleware,
114+
excluded_urls = AGENT_CARD_WELL_KNOWN_PATH,
113115
)
114116

117+
StarletteInstrumentor().instrument_app(starlette_app)
118+
115119
return starlette_app

adk/agenticlayer/otel.py

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import logging
2-
from typing import Any, Awaitable, Callable, MutableMapping, Set
32

43
from openinference.instrumentation.google_adk import GoogleADKInstrumentor
54
from opentelemetry import metrics, trace
65
from opentelemetry._logs import set_logger_provider
76
from opentelemetry.exporter.otlp.proto.http._log_exporter import OTLPLogExporter
87
from opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter
98
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
10-
from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware
119
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
1210
from opentelemetry.sdk import trace as trace_sdk
1311
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
@@ -17,48 +15,6 @@
1715
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
1816

1917

20-
class TelemetryFilter:
21-
""" This filter wraps OpenTelemetry's ASGI middleware and selectively applies
22-
telemetry based on request paths. Filtered paths bypass all telemetry
23-
generation (traces, metrics, logs) for optimal performance.
24-
"""
25-
26-
def __init__(
27-
self,
28-
app: Callable[..., Any],
29-
filtered_paths: Set[str],
30-
**otel_kwargs: Any
31-
) -> None:
32-
33-
self.app = app
34-
self.filtered_paths = filtered_paths
35-
36-
# Create the OpenTelemetry middleware for non-filtered requests
37-
self.otel_middleware = OpenTelemetryMiddleware(
38-
app,
39-
**otel_kwargs
40-
)
41-
42-
async def __call__(
43-
self,
44-
scope: MutableMapping[str, Any],
45-
receive: Callable[[], Awaitable[MutableMapping[str, Any]]],
46-
send: Callable[[MutableMapping[str, Any]], Awaitable[None]],
47-
) -> None:
48-
49-
# Only filter HTTP requests
50-
if scope["type"] == "http":
51-
path = scope.get("path", "")
52-
53-
# If path is filtered, bypass OpenTelemetry entirely
54-
if path in self.filtered_paths:
55-
await self.app(scope, receive, send)
56-
return
57-
58-
# For all other requests, use OpenTelemetry middleware
59-
await self.otel_middleware(scope, receive, send)
60-
61-
6218
def setup_otel() -> None:
6319
"""Set up OpenTelemetry tracing, logging and metrics."""
6420

adk/tests/conftest.py

Lines changed: 0 additions & 9 deletions
This file was deleted.

adk/tests/test_a2a_starlette.py

Lines changed: 0 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
from typing import Any
2-
from unittest.mock import AsyncMock, Mock
3-
41
import pytest
52
from agenticlayer.agent_to_a2a import to_a2a
6-
from agenticlayer.otel import TelemetryFilter
73
from google.adk.agents.base_agent import BaseAgent
84
from starlette.applications import Starlette
95
from starlette.testclient import TestClient
@@ -40,74 +36,3 @@ def test_agent_card_endpoint(self, starlette_app: Starlette, client: TestClient)
4036

4137
# Verify it contains expected agent card fields
4238
assert len(data) > 0, "Agent card should not be empty"
43-
44-
45-
class TestTelemetryFilter:
46-
"""Test suite for the TelemetryFilter class."""
47-
async def create_telemetry_filter(self, app_mock: AsyncMock) -> TelemetryFilter:
48-
return TelemetryFilter(
49-
app=app_mock,
50-
filtered_paths={"/.well-known/agent-card.json"}
51-
)
52-
53-
async def simulate_request(self, path: str) -> tuple[Mock, dict[str, Any], Mock]:
54-
scope = {"type": "http", "path": path}
55-
receive = Mock()
56-
send = Mock()
57-
return receive, scope, send
58-
59-
@pytest.mark.anyio
60-
async def test_telemetry_filter_bypasses_health_checks(self) -> None:
61-
"""Verify TelemetryFilter bypasses OpenTelemetry for health checks."""
62-
# Create mocks
63-
app_mock = AsyncMock()
64-
otel_middleware_mock = AsyncMock()
65-
66-
# Create filter with health check path
67-
telemetry_filter = await self.create_telemetry_filter(app_mock)
68-
telemetry_filter.otel_middleware = otel_middleware_mock
69-
70-
# Simulate health check request
71-
receive, scope, send = await self.simulate_request("/.well-known/agent-card.json")
72-
# Call the filter
73-
await telemetry_filter(scope, receive, send)
74-
75-
# Assert: app was called directly (bypassed OTEL)
76-
app_mock.assert_called_once_with(scope, receive, send)
77-
otel_middleware_mock.assert_not_called()
78-
79-
@pytest.mark.anyio
80-
async def test_telemetry_filter_allows_regular_requests(self) -> None:
81-
"""Verify TelemetryFilter applies OpenTelemetry for regular requests."""
82-
# Create mocks
83-
app_mock = AsyncMock()
84-
otel_middleware_mock = AsyncMock()
85-
86-
telemetry_filter = await self.create_telemetry_filter(app_mock)
87-
telemetry_filter.otel_middleware = otel_middleware_mock
88-
89-
# Simulate regular request
90-
receive, scope, send = await self.simulate_request("/a2a/v1/tasks")
91-
# Call the filter
92-
await telemetry_filter(scope, receive, send)
93-
94-
# Assert: OTEL middleware was used
95-
otel_middleware_mock.assert_called_once_with(scope, receive, send)
96-
97-
@pytest.mark.anyio
98-
async def test_telemetry_filter_handles_non_http_requests(self) -> None:
99-
"""Verify TelemetryFilter passes non-HTTP requests to OTEL middleware."""
100-
# Create mocks
101-
app_mock = AsyncMock()
102-
otel_middleware_mock = AsyncMock()
103-
104-
telemetry_filter = await self.create_telemetry_filter(app_mock)
105-
telemetry_filter.otel_middleware = otel_middleware_mock
106-
107-
# Simulate WebSocket request (non-HTTP)
108-
receive, scope, send = await self.simulate_request("/ws")
109-
# Call the filter
110-
await telemetry_filter(scope, receive, send)
111-
112-
# Assert: OTEL middleware was used (non-HTTP requests go through)
113-
otel_middleware_mock.assert_called_once_with(scope, receive, send)

0 commit comments

Comments
 (0)