Skip to content

Commit c5bfe08

Browse files
committed
refactor(stack_trace): create helper functions to eliminate repetition
Signed-off-by: Varsha GS <[email protected]>
1 parent 929a7df commit c5bfe08

File tree

3 files changed

+278
-238
lines changed

3 files changed

+278
-238
lines changed

src/instana/options.py

Lines changed: 107 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
parse_ignored_endpoints,
3131
parse_ignored_endpoints_from_yaml,
3232
parse_span_disabling,
33+
parse_technology_stack_trace_config,
34+
validate_stack_trace_length,
35+
validate_stack_trace_level,
3336
)
3437
from instana.util.runtime import determine_service_name
3538

@@ -133,104 +136,73 @@ def set_trace_configurations(self) -> None:
133136
self.set_disable_trace_configurations()
134137
self.set_stack_trace_configurations()
135138

139+
def _apply_env_stack_trace_config(self) -> None:
140+
"""Apply stack trace configuration from environment variables."""
141+
if "INSTANA_STACK_TRACE" in os.environ:
142+
if validated_level := validate_stack_trace_level(
143+
os.environ["INSTANA_STACK_TRACE"], "from INSTANA_STACK_TRACE"
144+
):
145+
self.stack_trace_level = validated_level
146+
147+
if "INSTANA_STACK_TRACE_LENGTH" in os.environ:
148+
if validated_length := validate_stack_trace_length(
149+
os.environ["INSTANA_STACK_TRACE_LENGTH"], "from INSTANA_STACK_TRACE_LENGTH"
150+
):
151+
self.stack_trace_length = validated_length
152+
153+
def _apply_yaml_stack_trace_config(self) -> None:
154+
"""Apply stack trace configuration from YAML file."""
155+
yaml_level, yaml_length, yaml_tech_config = get_stack_trace_config_from_yaml()
156+
if "INSTANA_STACK_TRACE" not in os.environ:
157+
self.stack_trace_level = yaml_level
158+
if "INSTANA_STACK_TRACE_LENGTH" not in os.environ:
159+
self.stack_trace_length = yaml_length
160+
self.stack_trace_technology_config.update(yaml_tech_config)
161+
162+
def _apply_in_code_stack_trace_config(self) -> None:
163+
"""Apply stack trace configuration from in-code config."""
164+
if not isinstance(config.get("tracing"), dict) or "global" not in config["tracing"]:
165+
return
166+
167+
global_config = config["tracing"]["global"]
168+
169+
if "INSTANA_STACK_TRACE" not in os.environ and "stack_trace" in global_config:
170+
if validated_level := validate_stack_trace_level(global_config["stack_trace"], "from in-code config"):
171+
self.stack_trace_level = validated_level
172+
173+
if "INSTANA_STACK_TRACE_LENGTH" not in os.environ and "stack_trace_length" in global_config:
174+
if validated_length := validate_stack_trace_length(global_config["stack_trace_length"], "from in-code config"):
175+
self.stack_trace_length = validated_length
176+
177+
# Technology-specific overrides from in-code config
178+
for tech_name, tech_data in config["tracing"].items():
179+
if tech_name == "global" or not isinstance(tech_data, dict):
180+
continue
181+
182+
tech_stack_config = parse_technology_stack_trace_config(
183+
tech_data,
184+
level_key="stack_trace",
185+
length_key="stack_trace_length",
186+
tech_name=tech_name
187+
)
188+
189+
if tech_stack_config:
190+
self.stack_trace_technology_config[tech_name] = tech_stack_config
191+
136192
def set_stack_trace_configurations(self) -> None:
137193
"""
138194
Set stack trace configurations following precedence:
139195
environment variables > INSTANA_CONFIG_PATH > in-code config > agent config > defaults
140196
"""
141197
# 1. Environment variables (highest priority)
142-
if "INSTANA_STACK_TRACE" in os.environ:
143-
level = os.environ["INSTANA_STACK_TRACE"].lower()
144-
if level in ["all", "error", "none"]:
145-
self.stack_trace_level = level
146-
else:
147-
logger.warning(
148-
f"Invalid INSTANA_STACK_TRACE value: {level}. Must be 'all', 'error', or 'none'. Using default 'all'"
149-
)
150-
151-
if "INSTANA_STACK_TRACE_LENGTH" in os.environ:
152-
try:
153-
length = int(os.environ["INSTANA_STACK_TRACE_LENGTH"])
154-
if length >= 1:
155-
self.stack_trace_length = length
156-
else:
157-
logger.warning(
158-
"INSTANA_STACK_TRACE_LENGTH must be positive. Using default 30"
159-
)
160-
except ValueError:
161-
logger.warning(
162-
"Invalid INSTANA_STACK_TRACE_LENGTH value. Must be an integer. Using default 30"
163-
)
198+
self._apply_env_stack_trace_config()
164199

165200
# 2. INSTANA_CONFIG_PATH (YAML file) - includes tech-specific overrides
166-
elif "INSTANA_CONFIG_PATH" in os.environ:
167-
yaml_level, yaml_length, yaml_tech_config = get_stack_trace_config_from_yaml()
168-
if "INSTANA_STACK_TRACE" not in os.environ:
169-
self.stack_trace_level = yaml_level
170-
if "INSTANA_STACK_TRACE_LENGTH" not in os.environ:
171-
self.stack_trace_length = yaml_length
172-
# Technology-specific overrides from YAML
173-
self.stack_trace_technology_config.update(yaml_tech_config)
174-
201+
if "INSTANA_CONFIG_PATH" in os.environ:
202+
self._apply_yaml_stack_trace_config()
175203
# 3. In-code (local) configuration - includes tech-specific overrides
176-
elif isinstance(config.get("tracing"), dict) and "global" in config["tracing"]:
177-
global_config = config["tracing"]["global"]
178-
179-
if "INSTANA_STACK_TRACE" not in os.environ and "stack_trace" in global_config:
180-
level = str(global_config["stack_trace"]).lower()
181-
if level in ["all", "error", "none"]:
182-
self.stack_trace_level = level
183-
else:
184-
logger.warning(
185-
f"Invalid stack_trace value in config: {level}. Must be 'all', 'error', or 'none'. Using default 'all'"
186-
)
187-
188-
if "INSTANA_STACK_TRACE_LENGTH" not in os.environ and "stack_trace_length" in global_config:
189-
try:
190-
length = int(global_config["stack_trace_length"])
191-
if length >= 1:
192-
self.stack_trace_length = length
193-
else:
194-
logger.warning(
195-
"stack_trace_length must be positive. Using default 30"
196-
)
197-
except (ValueError, TypeError):
198-
logger.warning(
199-
"Invalid stack_trace_length in config. Must be an integer. Using default 30"
200-
)
201-
202-
# Technology-specific overrides from in-code config
203-
for tech_name, tech_data in config["tracing"].items():
204-
if tech_name == "global" or not isinstance(tech_data, dict):
205-
continue
206-
207-
tech_stack_config = {}
208-
209-
if "stack_trace" in tech_data:
210-
tech_level = str(tech_data["stack_trace"]).lower()
211-
if tech_level in ["all", "error", "none"]:
212-
tech_stack_config["level"] = tech_level
213-
else:
214-
logger.warning(
215-
f"Invalid stack_trace value for {tech_name}: {tech_level}. Ignoring."
216-
)
217-
218-
if "stack_trace_length" in tech_data:
219-
try:
220-
tech_length = int(tech_data["stack_trace_length"])
221-
if tech_length >= 1:
222-
tech_stack_config["length"] = tech_length
223-
else:
224-
logger.warning(
225-
f"stack_trace_length for {tech_name} must be positive. Ignoring."
226-
)
227-
except (ValueError, TypeError):
228-
logger.warning(
229-
f"Invalid stack_trace_length for {tech_name}. Must be an integer. Ignoring."
230-
)
231-
232-
if tech_stack_config:
233-
self.stack_trace_technology_config[tech_name] = tech_stack_config
204+
elif isinstance(config.get("tracing"), dict):
205+
self._apply_in_code_stack_trace_config()
234206

235207
def set_disable_trace_configurations(self) -> None:
236208
disabled_spans = []
@@ -393,90 +365,61 @@ def set_tracing(self, tracing: Dict[str, Any]) -> None:
393365
# Handle stack trace configuration from agent config
394366
self.set_stack_trace_from_agent(tracing)
395367

368+
def _should_apply_agent_global_config(self) -> bool:
369+
"""Check if agent global config should be applied (lowest priority)."""
370+
has_env_vars = (
371+
"INSTANA_STACK_TRACE" in os.environ
372+
or "INSTANA_STACK_TRACE_LENGTH" in os.environ
373+
)
374+
has_yaml_config = "INSTANA_CONFIG_PATH" in os.environ
375+
has_in_code_config = (
376+
isinstance(config.get("tracing"), dict)
377+
and "global" in config["tracing"]
378+
and ("stack_trace" in config["tracing"]["global"]
379+
or "stack_trace_length" in config["tracing"]["global"])
380+
)
381+
return not (has_env_vars or has_yaml_config or has_in_code_config)
382+
383+
def _apply_agent_global_stack_trace_config(self, global_config: Dict[str, Any]) -> None:
384+
"""Apply global stack trace configuration from agent config."""
385+
if "stack-trace" in global_config:
386+
if validated_level := validate_stack_trace_level(global_config["stack-trace"], "in agent config"):
387+
self.stack_trace_level = validated_level
388+
389+
if "stack-trace-length" in global_config:
390+
if validated_length := validate_stack_trace_length(global_config["stack-trace-length"], "in agent config"):
391+
self.stack_trace_length = validated_length
392+
393+
def _apply_agent_tech_stack_trace_config(self, tracing: Dict[str, Any]) -> None:
394+
"""Apply technology-specific stack trace configuration from agent config."""
395+
for tech_name, tech_config in tracing.items():
396+
if tech_name == "global" or not isinstance(tech_config, dict):
397+
continue
398+
399+
tech_stack_config = parse_technology_stack_trace_config(
400+
tech_config,
401+
level_key="stack-trace",
402+
length_key="stack-trace-length",
403+
tech_name=tech_name
404+
)
405+
406+
if tech_stack_config:
407+
self.stack_trace_technology_config[tech_name] = tech_stack_config
408+
396409
def set_stack_trace_from_agent(self, tracing: Dict[str, Any]) -> None:
397410
"""
398411
Set stack trace configuration from agent config (configuration.yaml).
399412
Only applies if not already set by higher priority sources.
400413
401414
@param tracing: tracing configuration dictionary from agent
402415
"""
403-
# Check if we should apply agent config (lowest priority)
404-
should_apply_agent_config = (
405-
"INSTANA_STACK_TRACE" not in os.environ
406-
and "INSTANA_STACK_TRACE_LENGTH" not in os.environ
407-
and "INSTANA_CONFIG_PATH" not in os.environ
408-
and not (
409-
isinstance(config.get("tracing"), dict)
410-
and "global" in config["tracing"]
411-
and ("stack_trace" in config["tracing"]["global"] or "stack_trace_length" in config["tracing"]["global"])
412-
)
413-
)
414-
415-
if should_apply_agent_config and "global" in tracing:
416-
global_config = tracing["global"]
417-
418-
# Set stack-trace level from agent config
419-
if "stack-trace" in global_config:
420-
level = str(global_config["stack-trace"]).lower()
421-
if level in ["all", "error", "none"]:
422-
self.stack_trace_level = level
423-
else:
424-
logger.warning(
425-
f"Invalid stack-trace value in agent config: {level}. Must be 'all', 'error', or 'none'. Using default 'all'"
426-
)
427-
428-
# Set stack-trace length from agent config
429-
if "stack-trace-length" in global_config:
430-
try:
431-
length = int(global_config["stack-trace-length"])
432-
if length >= 1:
433-
self.stack_trace_length = length
434-
else:
435-
logger.warning(
436-
"stack-trace-length must be positive. Using default 30"
437-
)
438-
except (ValueError, TypeError):
439-
logger.warning(
440-
"Invalid stack-trace-length in agent config. Must be an integer. Using default 30"
441-
)
416+
# Apply global config if no higher priority source exists
417+
if self._should_apply_agent_global_config() and "global" in tracing:
418+
self._apply_agent_global_stack_trace_config(tracing["global"])
442419

443-
# Technology-specific stack trace configuration from agent config
444-
# Only apply if not already set by higher priority sources (YAML or in-code config)
445-
# If stack_trace_technology_config is already populated, it means YAML or in-code config set it
420+
# Apply technology-specific config if not already set by YAML or in-code config
446421
if not self.stack_trace_technology_config:
447-
# Apply technology-specific overrides from agent config
448-
# Example: kafka, redis, mysql, postgres, mongo, etc.
449-
for tech_name, tech_config in tracing.items():
450-
if tech_name == "global" or not isinstance(tech_config, dict):
451-
continue
452-
453-
tech_stack_config = {}
454-
455-
if "stack-trace" in tech_config:
456-
level = str(tech_config["stack-trace"]).lower()
457-
if level in ["all", "error", "none"]:
458-
tech_stack_config["level"] = level
459-
else:
460-
logger.warning(
461-
f"Invalid stack-trace value for {tech_name}: {level}. Ignoring."
462-
)
463-
464-
if "stack-trace-length" in tech_config:
465-
try:
466-
length = int(tech_config["stack-trace-length"])
467-
if length >= 1:
468-
tech_stack_config["length"] = length
469-
else:
470-
logger.warning(
471-
f"stack-trace-length for {tech_name} must be positive. Ignoring."
472-
)
473-
except (ValueError, TypeError):
474-
logger.warning(
475-
f"Invalid stack-trace-length for {tech_name}. Must be an integer. Ignoring."
476-
)
477-
478-
if tech_stack_config:
479-
self.stack_trace_technology_config[tech_name] = tech_stack_config
422+
self._apply_agent_tech_stack_trace_config(tracing)
480423

481424
def set_disable_tracing(self, tracing_config: Sequence[Dict[str, Any]]) -> None:
482425
# The precedence is as follows:

0 commit comments

Comments
 (0)