Skip to content

Commit 1894857

Browse files
authored
Allow setting env var to turn off traces (#30)
* Allow setting env var to turn off traces * Refactor disabling traces
1 parent e702a24 commit 1894857

File tree

5 files changed

+140
-2
lines changed

5 files changed

+140
-2
lines changed

gradient_adk/runtime/helpers.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
from gradient_adk.runtime.network_interceptor import setup_digitalocean_interception
1919

2020

21+
def _is_tracing_disabled() -> bool:
22+
"""Check if tracing is globally disabled via DISABLE_TRACES env var."""
23+
val = os.environ.get("DISABLE_TRACES", "").lower()
24+
return val in ("true", "1", "yes")
25+
26+
2127
class InstrumentorProtocol(Protocol):
2228
"""Protocol for instrumentor classes."""
2329

@@ -88,6 +94,10 @@ def _ensure_tracker(self) -> Optional[DigitalOceanTracesTracker]:
8894
self._tracker_initialized = True
8995

9096
try:
97+
# Check if tracing is globally disabled
98+
if _is_tracing_disabled():
99+
return None
100+
91101
api_token = os.environ.get("DIGITALOCEAN_API_TOKEN")
92102
if not api_token:
93103
return None

gradient_adk/runtime/network_interceptor.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,12 @@ def get_network_interceptor() -> NetworkInterceptor:
468468

469469

470470
def setup_digitalocean_interception() -> None:
471+
# Check if tracing is globally disabled
472+
# Import here to avoid circular imports
473+
from .helpers import _is_tracing_disabled
474+
if _is_tracing_disabled():
475+
return
476+
471477
intr = get_network_interceptor()
472478

473479
# Add inference (LLM) endpoint patterns

gradient_adk/tracing.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ async def my_agent(input: dict, context: RequestContext):
4141
from typing import Any, Callable, Dict, List, Optional, Tuple, TypeVar
4242

4343
from .runtime.interfaces import NodeExecution
44-
from .runtime.helpers import get_tracker
44+
from .runtime.helpers import get_tracker, _is_tracing_disabled
4545
from .runtime.network_interceptor import get_network_interceptor
4646

4747
F = TypeVar("F", bound=Callable[..., Any])
@@ -178,6 +178,10 @@ def _trace_base(
178178
"""
179179

180180
def decorator(func: F) -> F:
181+
# If tracing is disabled, return the original function unchanged
182+
if _is_tracing_disabled():
183+
return func
184+
181185
span_name = name or func.__name__
182186

183187
# Handle async generator functions (functions with `yield` that are async)
@@ -535,6 +539,9 @@ def add_llm_span(
535539
num_output_tokens=5,
536540
)
537541
"""
542+
if _is_tracing_disabled():
543+
return
544+
538545
tracker = get_tracker()
539546
if not tracker:
540547
return
@@ -613,6 +620,9 @@ def add_tool_span(
613620
tool_call_id="call_abc123",
614621
)
615622
"""
623+
if _is_tracing_disabled():
624+
return
625+
616626
tracker = get_tracker()
617627
if not tracker:
618628
return
@@ -669,6 +679,9 @@ def add_agent_span(
669679
metadata={"model": "gpt-4"},
670680
)
671681
"""
682+
if _is_tracing_disabled():
683+
return
684+
672685
tracker = get_tracker()
673686
if not tracker:
674687
return

integration_tests/run/test_adk_agents_run.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,3 +704,64 @@ def test_streaming_agent_with_evaluation_id_returns_single_response(
704704

705705
finally:
706706
cleanup_process(process)
707+
708+
@pytest.mark.cli
709+
def test_agent_run_with_disable_traces(self, setup_agent_in_temp):
710+
"""
711+
Test that an agent can run successfully with DISABLE_TRACES=1.
712+
Verifies:
713+
- Server starts successfully with tracing disabled
714+
- Health endpoint responds
715+
- /run endpoint works and echoes input
716+
"""
717+
logger = logging.getLogger(__name__)
718+
temp_dir = setup_agent_in_temp
719+
port = find_free_port()
720+
process = None
721+
722+
try:
723+
logger.info(f"Starting agent with DISABLE_TRACES=1 on port {port}")
724+
725+
# Set up environment with DISABLE_TRACES=1
726+
env = os.environ.copy()
727+
env["DISABLE_TRACES"] = "1"
728+
729+
process = subprocess.Popen(
730+
[
731+
"gradient",
732+
"agent",
733+
"run",
734+
"--port",
735+
str(port),
736+
"--no-dev",
737+
],
738+
cwd=temp_dir,
739+
env=env,
740+
start_new_session=True,
741+
)
742+
743+
# Wait for server to be ready
744+
server_ready = wait_for_server(port, timeout=30)
745+
assert server_ready, "Server did not start within timeout"
746+
747+
# Test health endpoint
748+
health_response = requests.get(f"http://localhost:{port}/health", timeout=5)
749+
assert health_response.status_code == 200
750+
health_data = health_response.json()
751+
assert health_data["status"] == "healthy"
752+
logger.info(f"Health check passed with DISABLE_TRACES=1: {health_data}")
753+
754+
# Test /run endpoint
755+
run_response = requests.post(
756+
f"http://localhost:{port}/run",
757+
json={"prompt": "Hello with tracing disabled!"},
758+
timeout=10,
759+
)
760+
assert run_response.status_code == 200
761+
run_data = run_response.json()
762+
assert run_data["echo"] == "Hello with tracing disabled!"
763+
assert run_data["received"]["prompt"] == "Hello with tracing disabled!"
764+
logger.info(f"Agent ran successfully with DISABLE_TRACES=1: {run_data}")
765+
766+
finally:
767+
cleanup_process(process)

tests/runtime/helpers_test.py

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
register_all_instrumentors,
1313
_register_langgraph,
1414
_register_pydanticai,
15+
_is_tracing_disabled,
1516
)
1617

1718

@@ -290,4 +291,51 @@ def test_pydanticai_availability_check():
290291
check = test_registry._registrations["pydanticai"]["availability_check"]
291292

292293
# Since we're running tests with pydantic-ai installed, it should be available
293-
assert check() is True
294+
assert check() is True
295+
296+
297+
# -----------------------------
298+
# DISABLE_TRACES Tests
299+
# -----------------------------
300+
301+
302+
def test_is_tracing_disabled_true_values():
303+
"""Test _is_tracing_disabled returns True for truthy env var values."""
304+
for val in ["true", "TRUE", "True", "1", "yes", "YES", "Yes"]:
305+
with patch.dict(os.environ, {"DISABLE_TRACES": val}):
306+
assert _is_tracing_disabled() is True, f"Expected True for DISABLE_TRACES={val}"
307+
308+
309+
def test_is_tracing_disabled_false_values():
310+
"""Test _is_tracing_disabled returns False for falsy env var values."""
311+
for val in ["false", "FALSE", "0", "no", "", "anything", "disabled"]:
312+
with patch.dict(os.environ, {"DISABLE_TRACES": val}):
313+
assert _is_tracing_disabled() is False, f"Expected False for DISABLE_TRACES={val}"
314+
315+
316+
def test_is_tracing_disabled_missing_var():
317+
"""Test _is_tracing_disabled returns False when env var is not set."""
318+
with patch.dict(os.environ, {}, clear=True):
319+
assert _is_tracing_disabled() is False
320+
321+
322+
def test_ensure_tracker_returns_none_when_tracing_disabled(fresh_registry):
323+
"""Test that _ensure_tracker returns None when DISABLE_TRACES=1, even with valid API token."""
324+
with patch.dict(os.environ, {"DISABLE_TRACES": "1", "DIGITALOCEAN_API_TOKEN": "test-token"}):
325+
result = fresh_registry._ensure_tracker()
326+
327+
assert result is None
328+
assert fresh_registry._tracker is None
329+
330+
331+
def test_install_all_returns_none_when_tracing_disabled():
332+
"""Test that install_all returns None and installs nothing when DISABLE_TRACES=1."""
333+
test_registry = InstrumentorRegistry()
334+
335+
with patch("gradient_adk.runtime.helpers.registry", test_registry):
336+
with patch.dict(os.environ, {"DISABLE_TRACES": "1", "DIGITALOCEAN_API_TOKEN": "test-token"}):
337+
register_all_instrumentors()
338+
result = test_registry.install_all()
339+
340+
assert result is None
341+
assert test_registry.get_installed_names() == []

0 commit comments

Comments
 (0)