Coverage for /home/admin/Documents/AI/applications/lexigram-dev/lexigram/experimental/ai/lexigram-ai-observability/src/lexigram/ai/observability/config.py: 68%

28 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-25 07:19 +0800

1"""Observability configuration for Lexigram.""" 

2 

3from __future__ import annotations 

4 

5from dataclasses import dataclass 

6from typing import ClassVar, cast 

7 

8from lexigram.ai.observability import constants as const 

9from lexigram.config import ( 

10 BaseConfig, 

11) 

12from lexigram.contracts.core.config import ConfigIssue, Environment 

13from lexigram.validation import ConfigDict, Field 

14 

15 

16@dataclass(init=False) 

17class ObservabilityConfig(BaseConfig): 

18 """Configuration for AI observability. 

19 

20 Loaded from the ``ai_observability:`` key in application.yaml, with environment 

21 variable overrides via ``LEX_AI_OBSERVABILITY__*`` prefix. 

22 """ 

23 

24 config_section: ClassVar[str] = "ai_observability" 

25 

26 model_config: ClassVar[ConfigDict] = cast( 

27 "ConfigDict", 

28 { 

29 "env_prefix": const.ENV_PREFIX, 

30 "env_nested_delimiter": const.ENV_NESTED_DELIMITER, 

31 "extra": "ignore", 

32 }, 

33 ) 

34 

35 enabled: bool = Field( 

36 default=True, description="Master on/off switch for all observability" 

37 ) 

38 metrics_enabled: bool = Field(default=True, description="Enable metrics collection") 

39 tracing_enabled: bool = Field( 

40 default=True, description="Enable distributed tracing" 

41 ) 

42 health_checks_enabled: bool = Field( 

43 default=True, 

44 description="Enable background health checking for AI components", 

45 ) 

46 trace_redaction_enabled: bool = Field( 

47 default=False, 

48 description=( 

49 "Redact secret-shaped keys (e.g. token, password, api_key) from " 

50 "trace span attributes and audit metadata. Strongly recommended " 

51 "for production tracing." 

52 ), 

53 ) 

54 trace_max_attribute_length: int = Field( 

55 default=0, 

56 description=( 

57 "Cap on string attribute values written to trace spans, in " 

58 "characters. 0 disables the cap." 

59 ), 

60 ) 

61 

62 def validate_for_environment( 

63 self, env: Environment | None = None 

64 ) -> list[ConfigIssue]: 

65 """Check config is safe for the target environment.""" 

66 issues: list[ConfigIssue] = [] 

67 

68 if env == Environment.PRODUCTION: 

69 if not self.tracing_enabled: 

70 issues.append( 

71 ConfigIssue( 

72 severity="warning", 

73 field="tracing_enabled", 

74 message="Distributed tracing disabled in production", 

75 suggestion=( 

76 f"Set {const.ENV_PREFIX}TRACING_ENABLED=true for " 

77 "production observability." 

78 ), 

79 ) 

80 ) 

81 if not self.metrics_enabled: 

82 issues.append( 

83 ConfigIssue( 

84 severity="warning", 

85 field="metrics_enabled", 

86 message="Metrics collection disabled in production", 

87 suggestion=( 

88 f"Set {const.ENV_PREFIX}METRICS_ENABLED=true to collect " 

89 "operational metrics." 

90 ), 

91 ) 

92 ) 

93 if self.tracing_enabled and not self.trace_redaction_enabled: 

94 issues.append( 

95 ConfigIssue( 

96 severity="warning", 

97 field="trace_redaction_enabled", 

98 message=( 

99 "Trace payload redaction disabled in production; " 

100 "secrets in tool arguments, agent actions, or " 

101 "retriever queries may be exported to the tracing " 

102 "backend." 

103 ), 

104 suggestion=( 

105 f"Set {const.ENV_PREFIX}TRACE_REDACTION_ENABLED=true " 

106 "to redact secret-shaped keys from trace spans." 

107 ), 

108 ) 

109 ) 

110 

111 return issues 

112 

113 

114__all__ = ["ObservabilityConfig"]