8000 fix(telemetry): correct environment variable precedence for OTEL conf… · lgigit200/sdk-python@73dae72 · GitHub
[go: up one dir, main page]

Skip to content

Commit 73dae72

Browse files
JackYPCOnlineJack Yuan
andauthored
fix(telemetry): correct environment variable precedence for OTEL config (strands-agents#86)
* fix(telemetry): correct environment variable precedence for OTEL configuration * fix(telemetry): update get_tracer function to adapt the changes * fix(telemetry): fix tracer initialization --------- Co-authored-by: Jack Yuan <jackypc@amazon.com>
1 parent 5d785a1 commit 73dae72

File tree

2 files changed

+104
-12
lines changed

2 files changed

+104
-12
lines changed

src/strands/telemetry/tracer.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def __init__(
9393
service_name: str = "strands-agents",
9494
otlp_endpoint: Optional[str] = None,
9595
otlp_headers: Optional[Dict[str, str]] = None,
96-
enable_console_export: bool = False,
96+
enable_console_export: Optional[bool] = None,
9797
):
9898
"""Initialize the tracer.
9999
@@ -105,13 +105,17 @@ def __init__(
105105
"""
106106
# Check environment variables first
107107
env_endpoint = os.environ.get("OTEL_EXPORTER_OTLP_ENDPOINT")
< 8000 /td>
108-
env_console_export = os.environ.get("STRANDS_OTEL_ENABLE_CONSOLE_EXPORT", "").lower() in ("true", "1", "yes")
108+
env_console_export_str = os.environ.get("STRANDS_OTEL_ENABLE_CONSOLE_EXPORT")
109109

110-
# Environment variables take precedence over constructor parameters
111-
if env_endpoint:
112-
otlp_endpoint = env_endpoint
113-
if env_console_export:
114-
enable_console_export = True
110+
# Constructor parameters take precedence over environment variables
111+
self.otlp_endpoint = otlp_endpoint or env_endpoint
112+
113+
if enable_console_export is not None:
114+
self.enable_console_export = enable_console_export
115+
elif env_console_export_str:
116+
self.enable_console_export = env_console_export_str.lower() in ("true", "1", "yes")
117+
else:
118+
self.enable_console_export = False
115119

116120
# Parse headers from environment if available
117121
env_headers = os.environ.get("OTEL_EXPORTER_OTLP_HEADERS")
@@ -128,14 +132,11 @@ def __init__(
128132
logger.warning("error=<%s> | failed to parse OTEL_EXPORTER_OTLP_HEADERS", e)
129133

130134
self.service_name = service_name
131-
self.otlp_endpoint = otlp_endpoint
132135
self.otlp_headers = otlp_headers or {}
133-
self.enable_console_export = enable_console_export
134-
135136
self.tracer_provider: Optional[TracerProvider] = None
136137
self.tracer: Optional[trace.Tracer] = None
137138

138-
if otlp_endpoint or enable_console_export:
139+
if self.otlp_endpoint or self.enable_console_export:
139140
self._initialize_tracer()
140141

141142
def _initialize_tracer(self) -> None:
@@ -547,7 +548,7 @@ def get_tracer(
547548
service_name: str = "strands-agents",
548549
otlp_endpoint: Optional[str] = None,
549550
otlp_headers: Optional[Dict[str, str]] = None,
550-
enable_console_export: bool = False,
551+
enable_console_export: Optional[bool] = None,
551552
) -> Tracer:
552553
"""Get or create the global tracer.
553554

tests/strands/telemetry/test_tracer.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,50 @@ def mock_resource():
6060
yield mock_resource
6161

6262

63+
@pytest.fixture
64+
def clean_env():
65+
"""Fixture to provide a clean environment for each test."""
66+
with mock.patch.dict(os.environ, {}, clear=True):
67+
yield
68+
69+
70+
@pytest.fixture
71+
def env_with_otlp():
72+
"""Fixture with OTLP environment variables."""
73+
with mock.patch.dict(
74+
os.environ,
75+
{
76+
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://env-endpoint",
77+
},
78+
):
79+
yield
80+
81+
82+
@pytest.fixture
83+
def env_with_console():
84+
"""Fixture with console export environment variables."""
85+
with mock.patch.dict(
86+
os.environ,
87+
{
88+
"STRANDS_OTEL_ENABLE_CONSOLE_EXPORT": "true",
89+
},
90+
):
91+
yield
92+
93+
94+
@pytest.fixture
95+
def env_with_both():
96+
"""Fixture with both OTLP and console export environment variables."""
97+
with mock.patch.dict(
98+
os.environ,
99+
{
100+
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://env-endpoint",
101+
"STRANDS_OTEL_ENABLE_CONSOLE_EXPORT": "true",
102+
},
103+
):
104+
yield
105+
106+
63107
def test_init_default():
64108
"""Test initializing the Tracer with default parameters."""
65109
tracer = Tracer()
@@ -681,3 +725,50 @@ def test_serialize_vs_json_dumps():
681725
custom_result = serialize({"text": japanese_text})
682726
assert japanese_text in custom_result
683727
assert "\\u" not in custom_result
728+
729+
730+
def test_init_with_no_env_or_param(clean_env):
731+
"""Test initializing with neither environment variable nor constructor parameter."""
732+
tracer = Tracer()
733+
assert tracer.otlp_endpoint is None
734+
assert tracer.enable_console_export is False
735+
736+
tracer = Tracer(otlp_endpoint="http://param-endpoint")
737+
assert tracer.otlp_endpoint == "http://param-endpoint"
738+
739+
tracer = Tracer(enable_console_export=True)
740+
assert tracer.enable_console_export is True
741+
742+
743+
def test_constructor_params_with_otlp_env(env_with_otlp):
744+
"""Test constructor parameters precedence over OTLP environment variable."""
745+
# Constructor parameter should take precedence
746+
tracer = Tracer(otlp_endpoint="http://constructor-endpoint")
747+
assert tracer.otlp_endpoint == "http://constructor-endpoint"
748+
749+
# Without constructor parameter, should use env var
750+
tracer = Tracer()
751+
assert tracer.otlp_endpoint == "http://env-endpoint"
752+
753+
754+
def test_constructor_params_with_console_env(env_with_console):
755+
"""Test constructor parameters precedence over console environment variable."""
756+
# Constructor parameter should take precedence
757+
tracer = Tracer(enable_console_export=False)
758+
assert tracer.enable_console_export is False
759+
760+
# Without explicit constructor parameter, should use env var
761+
tracer = Tracer()
762+
assert tracer.enable_console_export is True
763+
764+
765+
def test_fallback_to_env_vars(env_with_both):
766+
"""Test fallback to environment variables when no constructor parameters."""
767+
tracer = Tracer()
768+
assert tracer.otlp_endpoint == "http://env-endpoint"
769+
assert tracer.enable_console_export is True
770+
771+
# Constructor parameters should still take precedence
772+
tracer = Tracer(otlp_endpoint="http://constructor-endpoint", enable_console_export=False)
773+
assert tracer.otlp_endpoint == "http://constructor-endpoint"
774+
assert tracer.enable_console_export is False

0 commit comments

Comments
 (0)
0