runbooks 1.1.4__py3-none-any.whl → 1.1.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. runbooks/__init__.py +31 -2
  2. runbooks/__init___optimized.py +18 -4
  3. runbooks/_platform/__init__.py +1 -5
  4. runbooks/_platform/core/runbooks_wrapper.py +141 -138
  5. runbooks/aws2/accuracy_validator.py +812 -0
  6. runbooks/base.py +7 -0
  7. runbooks/cfat/assessment/compliance.py +1 -1
  8. runbooks/cfat/assessment/runner.py +1 -0
  9. runbooks/cfat/cloud_foundations_assessment.py +227 -239
  10. runbooks/cli/__init__.py +1 -1
  11. runbooks/cli/commands/cfat.py +64 -23
  12. runbooks/cli/commands/finops.py +1005 -54
  13. runbooks/cli/commands/inventory.py +138 -35
  14. runbooks/cli/commands/operate.py +9 -36
  15. runbooks/cli/commands/security.py +42 -18
  16. runbooks/cli/commands/validation.py +432 -18
  17. runbooks/cli/commands/vpc.py +81 -17
  18. runbooks/cli/registry.py +22 -10
  19. runbooks/cloudops/__init__.py +20 -27
  20. runbooks/cloudops/base.py +96 -107
  21. runbooks/cloudops/cost_optimizer.py +544 -542
  22. runbooks/cloudops/infrastructure_optimizer.py +5 -4
  23. runbooks/cloudops/interfaces.py +224 -225
  24. runbooks/cloudops/lifecycle_manager.py +5 -4
  25. runbooks/cloudops/mcp_cost_validation.py +252 -235
  26. runbooks/cloudops/models.py +78 -53
  27. runbooks/cloudops/monitoring_automation.py +5 -4
  28. runbooks/cloudops/notebook_framework.py +177 -213
  29. runbooks/cloudops/security_enforcer.py +125 -159
  30. runbooks/common/accuracy_validator.py +11 -0
  31. runbooks/common/aws_pricing.py +349 -326
  32. runbooks/common/aws_pricing_api.py +211 -212
  33. runbooks/common/aws_profile_manager.py +40 -36
  34. runbooks/common/aws_utils.py +74 -79
  35. runbooks/common/business_logic.py +126 -104
  36. runbooks/common/cli_decorators.py +36 -60
  37. runbooks/common/comprehensive_cost_explorer_integration.py +455 -463
  38. runbooks/common/cross_account_manager.py +197 -204
  39. runbooks/common/date_utils.py +27 -39
  40. runbooks/common/decorators.py +29 -19
  41. runbooks/common/dry_run_examples.py +173 -208
  42. runbooks/common/dry_run_framework.py +157 -155
  43. runbooks/common/enhanced_exception_handler.py +15 -4
  44. runbooks/common/enhanced_logging_example.py +50 -64
  45. runbooks/common/enhanced_logging_integration_example.py +65 -37
  46. runbooks/common/env_utils.py +16 -16
  47. runbooks/common/error_handling.py +40 -38
  48. runbooks/common/lazy_loader.py +41 -23
  49. runbooks/common/logging_integration_helper.py +79 -86
  50. runbooks/common/mcp_cost_explorer_integration.py +476 -493
  51. runbooks/common/mcp_integration.py +63 -74
  52. runbooks/common/memory_optimization.py +140 -118
  53. runbooks/common/module_cli_base.py +37 -58
  54. runbooks/common/organizations_client.py +175 -193
  55. runbooks/common/patterns.py +23 -25
  56. runbooks/common/performance_monitoring.py +67 -71
  57. runbooks/common/performance_optimization_engine.py +283 -274
  58. runbooks/common/profile_utils.py +111 -37
  59. runbooks/common/rich_utils.py +201 -141
  60. runbooks/common/sre_performance_suite.py +177 -186
  61. runbooks/enterprise/__init__.py +1 -1
  62. runbooks/enterprise/logging.py +144 -106
  63. runbooks/enterprise/security.py +187 -204
  64. runbooks/enterprise/validation.py +43 -56
  65. runbooks/finops/__init__.py +26 -30
  66. runbooks/finops/account_resolver.py +1 -1
  67. runbooks/finops/advanced_optimization_engine.py +980 -0
  68. runbooks/finops/automation_core.py +268 -231
  69. runbooks/finops/business_case_config.py +184 -179
  70. runbooks/finops/cli.py +660 -139
  71. runbooks/finops/commvault_ec2_analysis.py +157 -164
  72. runbooks/finops/compute_cost_optimizer.py +336 -320
  73. runbooks/finops/config.py +20 -20
  74. runbooks/finops/cost_optimizer.py +484 -618
  75. runbooks/finops/cost_processor.py +332 -214
  76. runbooks/finops/dashboard_runner.py +1006 -172
  77. runbooks/finops/ebs_cost_optimizer.py +991 -657
  78. runbooks/finops/elastic_ip_optimizer.py +317 -257
  79. runbooks/finops/enhanced_mcp_integration.py +340 -0
  80. runbooks/finops/enhanced_progress.py +32 -29
  81. runbooks/finops/enhanced_trend_visualization.py +3 -2
  82. runbooks/finops/enterprise_wrappers.py +223 -285
  83. runbooks/finops/executive_export.py +203 -160
  84. runbooks/finops/helpers.py +130 -288
  85. runbooks/finops/iam_guidance.py +1 -1
  86. runbooks/finops/infrastructure/__init__.py +80 -0
  87. runbooks/finops/infrastructure/commands.py +506 -0
  88. runbooks/finops/infrastructure/load_balancer_optimizer.py +866 -0
  89. runbooks/finops/infrastructure/vpc_endpoint_optimizer.py +832 -0
  90. runbooks/finops/markdown_exporter.py +337 -174
  91. runbooks/finops/mcp_validator.py +1952 -0
  92. runbooks/finops/nat_gateway_optimizer.py +1512 -481
  93. runbooks/finops/network_cost_optimizer.py +657 -587
  94. runbooks/finops/notebook_utils.py +226 -188
  95. runbooks/finops/optimization_engine.py +1136 -0
  96. runbooks/finops/optimizer.py +19 -23
  97. runbooks/finops/rds_snapshot_optimizer.py +367 -411
  98. runbooks/finops/reservation_optimizer.py +427 -363
  99. runbooks/finops/scenario_cli_integration.py +64 -65
  100. runbooks/finops/scenarios.py +1277 -438
  101. runbooks/finops/schemas.py +218 -182
  102. runbooks/finops/snapshot_manager.py +2289 -0
  103. runbooks/finops/types.py +3 -3
  104. runbooks/finops/validation_framework.py +259 -265
  105. runbooks/finops/vpc_cleanup_exporter.py +189 -144
  106. runbooks/finops/vpc_cleanup_optimizer.py +591 -573
  107. runbooks/finops/workspaces_analyzer.py +171 -182
  108. runbooks/integration/__init__.py +89 -0
  109. runbooks/integration/mcp_integration.py +1920 -0
  110. runbooks/inventory/CLAUDE.md +816 -0
  111. runbooks/inventory/__init__.py +2 -2
  112. runbooks/inventory/cloud_foundations_integration.py +144 -149
  113. runbooks/inventory/collectors/aws_comprehensive.py +1 -1
  114. runbooks/inventory/collectors/aws_networking.py +109 -99
  115. runbooks/inventory/collectors/base.py +4 -0
  116. runbooks/inventory/core/collector.py +495 -313
  117. runbooks/inventory/drift_detection_cli.py +69 -96
  118. runbooks/inventory/inventory_mcp_cli.py +48 -46
  119. runbooks/inventory/list_rds_snapshots_aggregator.py +192 -208
  120. runbooks/inventory/mcp_inventory_validator.py +549 -465
  121. runbooks/inventory/mcp_vpc_validator.py +359 -442
  122. runbooks/inventory/organizations_discovery.py +55 -51
  123. runbooks/inventory/rich_inventory_display.py +33 -32
  124. runbooks/inventory/unified_validation_engine.py +278 -251
  125. runbooks/inventory/vpc_analyzer.py +732 -695
  126. runbooks/inventory/vpc_architecture_validator.py +293 -348
  127. runbooks/inventory/vpc_dependency_analyzer.py +382 -378
  128. runbooks/inventory/vpc_flow_analyzer.py +1 -1
  129. runbooks/main.py +49 -34
  130. runbooks/main_final.py +91 -60
  131. runbooks/main_minimal.py +22 -10
  132. runbooks/main_optimized.py +131 -100
  133. runbooks/main_ultra_minimal.py +7 -2
  134. runbooks/mcp/__init__.py +36 -0
  135. runbooks/mcp/integration.py +679 -0
  136. runbooks/monitoring/performance_monitor.py +9 -4
  137. runbooks/operate/dynamodb_operations.py +3 -1
  138. runbooks/operate/ec2_operations.py +145 -137
  139. runbooks/operate/iam_operations.py +146 -152
  140. runbooks/operate/networking_cost_heatmap.py +29 -8
  141. runbooks/operate/rds_operations.py +223 -254
  142. runbooks/operate/s3_operations.py +107 -118
  143. runbooks/operate/vpc_operations.py +646 -616
  144. runbooks/remediation/base.py +1 -1
  145. runbooks/remediation/commons.py +10 -7
  146. runbooks/remediation/commvault_ec2_analysis.py +70 -66
  147. runbooks/remediation/ec2_unattached_ebs_volumes.py +1 -0
  148. runbooks/remediation/multi_account.py +24 -21
  149. runbooks/remediation/rds_snapshot_list.py +86 -60
  150. runbooks/remediation/remediation_cli.py +92 -146
  151. runbooks/remediation/universal_account_discovery.py +83 -79
  152. runbooks/remediation/workspaces_list.py +46 -41
  153. runbooks/security/__init__.py +19 -0
  154. runbooks/security/assessment_runner.py +1150 -0
  155. runbooks/security/baseline_checker.py +812 -0
  156. runbooks/security/cloudops_automation_security_validator.py +509 -535
  157. runbooks/security/compliance_automation_engine.py +17 -17
  158. runbooks/security/config/__init__.py +2 -2
  159. runbooks/security/config/compliance_config.py +50 -50
  160. runbooks/security/config_template_generator.py +63 -76
  161. runbooks/security/enterprise_security_framework.py +1 -1
  162. runbooks/security/executive_security_dashboard.py +519 -508
  163. runbooks/security/multi_account_security_controls.py +959 -1210
  164. runbooks/security/real_time_security_monitor.py +422 -444
  165. runbooks/security/security_baseline_tester.py +1 -1
  166. runbooks/security/security_cli.py +143 -112
  167. runbooks/security/test_2way_validation.py +439 -0
  168. runbooks/security/two_way_validation_framework.py +852 -0
  169. runbooks/sre/production_monitoring_framework.py +167 -177
  170. runbooks/tdd/__init__.py +15 -0
  171. runbooks/tdd/cli.py +1071 -0
  172. runbooks/utils/__init__.py +14 -17
  173. runbooks/utils/logger.py +7 -2
  174. runbooks/utils/version_validator.py +50 -47
  175. runbooks/validation/__init__.py +6 -6
  176. runbooks/validation/cli.py +9 -3
  177. runbooks/validation/comprehensive_2way_validator.py +745 -704
  178. runbooks/validation/mcp_validator.py +906 -228
  179. runbooks/validation/terraform_citations_validator.py +104 -115
  180. runbooks/validation/terraform_drift_detector.py +447 -451
  181. runbooks/vpc/README.md +617 -0
  182. runbooks/vpc/__init__.py +8 -1
  183. runbooks/vpc/analyzer.py +577 -0
  184. runbooks/vpc/cleanup_wrapper.py +476 -413
  185. runbooks/vpc/cli_cloudtrail_commands.py +339 -0
  186. runbooks/vpc/cli_mcp_validation_commands.py +480 -0
  187. runbooks/vpc/cloudtrail_audit_integration.py +717 -0
  188. runbooks/vpc/config.py +92 -97
  189. runbooks/vpc/cost_engine.py +411 -148
  190. runbooks/vpc/cost_explorer_integration.py +553 -0
  191. runbooks/vpc/cross_account_session.py +101 -106
  192. runbooks/vpc/enhanced_mcp_validation.py +917 -0
  193. runbooks/vpc/eni_gate_validator.py +961 -0
  194. runbooks/vpc/heatmap_engine.py +185 -160
  195. runbooks/vpc/mcp_no_eni_validator.py +680 -639
  196. runbooks/vpc/nat_gateway_optimizer.py +358 -0
  197. runbooks/vpc/networking_wrapper.py +15 -8
  198. runbooks/vpc/pdca_remediation_planner.py +528 -0
  199. runbooks/vpc/performance_optimized_analyzer.py +219 -231
  200. runbooks/vpc/runbooks_adapter.py +1167 -241
  201. runbooks/vpc/tdd_red_phase_stubs.py +601 -0
  202. runbooks/vpc/test_data_loader.py +358 -0
  203. runbooks/vpc/tests/conftest.py +314 -4
  204. runbooks/vpc/tests/test_cleanup_framework.py +1022 -0
  205. runbooks/vpc/tests/test_cost_engine.py +0 -2
  206. runbooks/vpc/topology_generator.py +326 -0
  207. runbooks/vpc/unified_scenarios.py +1297 -1124
  208. runbooks/vpc/vpc_cleanup_integration.py +1943 -1115
  209. runbooks-1.1.5.dist-info/METADATA +328 -0
  210. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/RECORD +214 -193
  211. runbooks/finops/README.md +0 -414
  212. runbooks/finops/accuracy_cross_validator.py +0 -647
  213. runbooks/finops/business_cases.py +0 -950
  214. runbooks/finops/dashboard_router.py +0 -922
  215. runbooks/finops/ebs_optimizer.py +0 -973
  216. runbooks/finops/embedded_mcp_validator.py +0 -1629
  217. runbooks/finops/enhanced_dashboard_runner.py +0 -527
  218. runbooks/finops/finops_dashboard.py +0 -584
  219. runbooks/finops/finops_scenarios.py +0 -1218
  220. runbooks/finops/legacy_migration.py +0 -730
  221. runbooks/finops/multi_dashboard.py +0 -1519
  222. runbooks/finops/single_dashboard.py +0 -1113
  223. runbooks/finops/unlimited_scenarios.py +0 -393
  224. runbooks-1.1.4.dist-info/METADATA +0 -800
  225. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/WHEEL +0 -0
  226. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/entry_points.txt +0 -0
  227. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/licenses/LICENSE +0 -0
  228. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/top_level.txt +0 -0
@@ -326,7 +326,7 @@ class EnterpriseExceptionHandler:
326
326
  # Defensive check for None values
327
327
  if execution_time is None or performance_target is None or performance_target == 0:
328
328
  return None
329
-
329
+
330
330
  performance_ratio = execution_time / performance_target
331
331
 
332
332
  # Only create error if performance significantly exceeded (>150% of target)
@@ -974,11 +974,21 @@ class EnterpriseExceptionHandler:
974
974
  def _initialize_profile_recommendations(self) -> Dict[str, List[str]]:
975
975
  """Initialize profile recommendations for different operations with universal support."""
976
976
  import os
977
+
977
978
  # Environment variable-driven profile recommendations
978
979
  return {
979
- "inventory": [os.getenv("MANAGEMENT_PROFILE", "management-profile"), os.getenv("CENTRALISED_OPS_PROFILE", "ops-profile")],
980
- "operate": [os.getenv("CENTRALISED_OPS_PROFILE", "ops-profile"), os.getenv("MANAGEMENT_PROFILE", "management-profile")],
981
- "finops": [os.getenv("BILLING_PROFILE", "billing-profile"), os.getenv("MANAGEMENT_PROFILE", "management-profile")],
980
+ "inventory": [
981
+ os.getenv("MANAGEMENT_PROFILE", "management-profile"),
982
+ os.getenv("CENTRALISED_OPS_PROFILE", "ops-profile"),
983
+ ],
984
+ "operate": [
985
+ os.getenv("CENTRALISED_OPS_PROFILE", "ops-profile"),
986
+ os.getenv("MANAGEMENT_PROFILE", "management-profile"),
987
+ ],
988
+ "finops": [
989
+ os.getenv("BILLING_PROFILE", "billing-profile"),
990
+ os.getenv("MANAGEMENT_PROFILE", "management-profile"),
991
+ ],
982
992
  "security": [os.getenv("MANAGEMENT_PROFILE", "management-profile")],
983
993
  "cfat": [os.getenv("MANAGEMENT_PROFILE", "management-profile")],
984
994
  }
@@ -994,6 +1004,7 @@ class EnterpriseExceptionHandler:
994
1004
  if service == "ce" and error_code == "AccessDenied":
995
1005
  # Cost Explorer requires special billing permissions
996
1006
  import os
1007
+
997
1008
  base_analysis["recommended_profiles"] = [os.getenv("BILLING_PROFILE", "billing-profile")]
998
1009
 
999
1010
  return base_analysis
@@ -15,158 +15,144 @@ from runbooks.enterprise.logging import get_context_logger, EnterpriseRichLogger
15
15
 
16
16
  class EnhancedLoggingExample:
17
17
  """Demonstrates enhanced logging integration patterns for different user types."""
18
-
18
+
19
19
  def __init__(self, log_level: str = "INFO", json_output: bool = False):
20
20
  """
21
21
  Initialize with enhanced logger.
22
-
22
+
23
23
  Args:
24
24
  log_level: Logging level (DEBUG, INFO, WARNING, ERROR)
25
25
  json_output: Enable structured JSON output
26
26
  """
27
27
  self.logger = get_context_logger(level=log_level, json_output=json_output)
28
28
  self.log_level = log_level.upper()
29
-
29
+
30
30
  def demonstrate_debug_logging(self):
31
31
  """Demonstrate DEBUG level logging for tech users (SRE/DevOps)."""
32
32
  print("\n=== DEBUG Level Logging (Tech Users) ===")
33
-
33
+
34
34
  # AWS API tracing example
35
35
  start_time = time.time()
36
-
36
+
37
37
  # Simulate AWS API call
38
38
  time.sleep(0.1)
39
39
  duration = time.time() - start_time
40
-
40
+
41
41
  self.logger.debug_tech(
42
42
  "EC2 instances discovered in region us-east-1",
43
- aws_api={
44
- "service": "ec2",
45
- "operation": "describe_instances",
46
- "region": "us-east-1"
47
- },
43
+ aws_api={"service": "ec2", "operation": "describe_instances", "region": "us-east-1"},
48
44
  duration=duration,
49
45
  request_id="12345-abcde-67890",
50
- resource_count=42
46
+ resource_count=42,
51
47
  )
52
-
48
+
53
49
  # Performance metrics
54
50
  self.logger.debug_tech(
55
51
  "Cost analysis query executed",
56
- aws_api={
57
- "service": "ce",
58
- "operation": "get_cost_and_usage"
59
- },
52
+ aws_api={"service": "ce", "operation": "get_cost_and_usage"},
60
53
  duration=2.435,
61
54
  data_points=1500,
62
- cache_hit=False
55
+ cache_hit=False,
63
56
  )
64
-
57
+
65
58
  def demonstrate_info_logging(self):
66
59
  """Demonstrate INFO level logging for standard users."""
67
60
  print("\n=== INFO Level Logging (Standard Users) ===")
68
-
61
+
69
62
  # Standard operation status
70
63
  self.logger.info_standard("Starting cost analysis for account 123456789012")
71
-
64
+
72
65
  # Progress indication
73
66
  self.logger.info_standard("Processing 15 AWS services across 3 regions")
74
-
67
+
75
68
  # Completion status
76
69
  self.logger.info_standard(
77
- "Cost analysis completed successfully",
78
- execution_time="12.3s",
79
- resources_analyzed=245
70
+ "Cost analysis completed successfully", execution_time="12.3s", resources_analyzed=245
80
71
  )
81
-
72
+
82
73
  def demonstrate_warning_logging(self):
83
74
  """Demonstrate WARNING level logging for business users."""
84
75
  print("\n=== WARNING Level Logging (Business Users) ===")
85
-
76
+
86
77
  # Cost alerts with recommendations
87
78
  self.logger.warning_business(
88
79
  "High storage costs detected in S3",
89
80
  recommendation="Consider implementing lifecycle policies for objects older than 90 days",
90
81
  cost_impact=2847.50,
91
- affected_buckets=12
82
+ affected_buckets=12,
92
83
  )
93
-
84
+
94
85
  # Resource optimization alerts
95
86
  self.logger.warning_business(
96
87
  "Underutilized EC2 instances found",
97
88
  recommendation="Review instance sizing for potential rightsizing opportunities",
98
89
  cost_impact=1250.00,
99
- instance_count=8
90
+ instance_count=8,
100
91
  )
101
-
92
+
102
93
  # Budget threshold warnings
103
94
  self.logger.warning_business(
104
95
  "Monthly budget threshold exceeded",
105
96
  recommendation="Review cost allocation and consider implementing cost controls",
106
97
  cost_impact=450.75,
107
- budget_utilization="105%"
98
+ budget_utilization="105%",
108
99
  )
109
-
100
+
110
101
  def demonstrate_error_logging(self):
111
102
  """Demonstrate ERROR level logging for all users."""
112
103
  print("\n=== ERROR Level Logging (All Users) ===")
113
-
104
+
114
105
  # AWS authentication errors
115
106
  self.logger.error_all(
116
107
  "Unable to access Cost Explorer API",
117
108
  solution="Run 'aws sso login' to refresh your authentication tokens",
118
109
  aws_error="ExpiredToken: Token has expired",
119
- profile="billing-profile"
110
+ profile="billing-profile",
120
111
  )
121
-
112
+
122
113
  # Configuration errors
123
114
  self.logger.error_all(
124
115
  "Invalid AWS profile configuration",
125
116
  solution="Check your ~/.aws/config file or contact your AWS administrator",
126
- aws_error="ProfileNotFound: The config profile (invalid-profile) could not be found"
117
+ aws_error="ProfileNotFound: The config profile (invalid-profile) could not be found",
127
118
  )
128
-
119
+
129
120
  # Service access errors
130
121
  self.logger.error_all(
131
122
  "Insufficient permissions for Organizations API",
132
123
  solution="Request 'organizations:ListAccounts' permission or use a different profile",
133
- aws_error="AccessDenied: User is not authorized to perform organizations:ListAccounts"
124
+ aws_error="AccessDenied: User is not authorized to perform organizations:ListAccounts",
134
125
  )
135
-
126
+
136
127
  def demonstrate_structured_logging(self):
137
128
  """Demonstrate structured JSON logging for programmatic use."""
138
129
  print("\n=== Structured JSON Logging (Programmatic Use) ===")
139
-
130
+
140
131
  # Create JSON logger
141
132
  json_logger = get_context_logger(level=self.log_level, json_output=True)
142
-
133
+
143
134
  # JSON structured logs
144
135
  json_logger.info_standard(
145
136
  "Cost analysis completed",
146
137
  total_cost=15432.75,
147
138
  account_count=5,
148
- service_breakdown={
149
- "EC2": 8750.25,
150
- "S3": 3200.50,
151
- "RDS": 2482.00,
152
- "Lambda": 1000.00
153
- }
139
+ service_breakdown={"EC2": 8750.25, "S3": 3200.50, "RDS": 2482.00, "Lambda": 1000.00},
154
140
  )
155
-
141
+
156
142
  json_logger.warning_business(
157
143
  "Budget variance detected",
158
144
  recommendation="Implement cost controls",
159
145
  cost_impact=2500.00,
160
- variance_percentage=15.2
146
+ variance_percentage=15.2,
161
147
  )
162
-
148
+
163
149
  def demonstrate_contextual_logging(self):
164
150
  """Demonstrate context-aware logging based on execution environment."""
165
151
  print("\n=== Context-Aware Logging ===")
166
-
152
+
167
153
  # Logging adapts to CLI vs Jupyter vs CI/CD environments
168
154
  self.logger.info_standard("Environment-aware logging initialized")
169
-
155
+
170
156
  # Performance logging with context
171
157
  with self.logger_performance_context("cost_analysis_operation") as perf:
172
158
  # Simulate work
@@ -181,27 +167,27 @@ def demo_user_type_scenarios():
181
167
  """
182
168
  print("Enhanced Multi-Level Logging System Demo")
183
169
  print("=" * 50)
184
-
170
+
185
171
  # Tech users (DEBUG level)
186
172
  print("\n🔧 TECH USER SCENARIO (--log-level DEBUG)")
187
173
  tech_demo = EnhancedLoggingExample(log_level="DEBUG")
188
174
  tech_demo.demonstrate_debug_logging()
189
-
190
- # Standard users (INFO level)
175
+
176
+ # Standard users (INFO level)
191
177
  print("\n👥 STANDARD USER SCENARIO (--log-level INFO)")
192
178
  standard_demo = EnhancedLoggingExample(log_level="INFO")
193
179
  standard_demo.demonstrate_info_logging()
194
-
180
+
195
181
  # Business users (WARNING level)
196
182
  print("\n💼 BUSINESS USER SCENARIO (--log-level WARNING)")
197
183
  business_demo = EnhancedLoggingExample(log_level="WARNING")
198
184
  business_demo.demonstrate_warning_logging()
199
-
185
+
200
186
  # Error scenarios (ERROR level)
201
187
  print("\n🚨 ERROR SCENARIOS (--log-level ERROR)")
202
188
  error_demo = EnhancedLoggingExample(log_level="ERROR")
203
189
  error_demo.demonstrate_error_logging()
204
-
190
+
205
191
  # JSON output for automation
206
192
  print("\n📄 STRUCTURED JSON OUTPUT (--json-output)")
207
193
  json_demo = EnhancedLoggingExample(log_level="INFO", json_output=True)
@@ -211,21 +197,21 @@ def demo_user_type_scenarios():
211
197
  # Performance context manager for demonstration
212
198
  class MockPerformanceContext:
213
199
  """Mock performance context for demonstration."""
214
-
200
+
215
201
  def __init__(self, operation_name: str):
216
202
  self.operation_name = operation_name
217
203
  self.metrics = {}
218
204
  self.start_time = time.time()
219
-
205
+
220
206
  def __enter__(self):
221
207
  return self
222
-
208
+
223
209
  def __exit__(self, exc_type, exc_val, exc_tb):
224
210
  duration = time.time() - self.start_time
225
211
  print(f"Performance: {self.operation_name} completed in {duration:.3f}s")
226
212
  if self.metrics:
227
213
  print(f"Metrics: {self.metrics}")
228
-
214
+
229
215
  def add_metric(self, key: str, value: Any):
230
216
  self.metrics[key] = value
231
217
 
@@ -236,4 +222,4 @@ EnhancedLoggingExample.logger_performance_context = lambda self, name: MockPerfo
236
222
 
237
223
  if __name__ == "__main__":
238
224
  """Run the enhanced logging demonstration."""
239
- demo_user_type_scenarios()
225
+ demo_user_type_scenarios()
@@ -12,14 +12,14 @@ multi-level logging architecture for user-type specific content.
12
12
  runbooks finops --log-level DEBUG --profile my-profile
13
13
  ```
14
14
 
15
- ### Standard Users (INFO level - default)
15
+ ### Standard Users (INFO level - default)
16
16
  ```bash
17
17
  runbooks finops --profile my-profile
18
18
  ```
19
19
 
20
20
  ### Business Users (WARNING level)
21
21
  ```bash
22
- runbooks finops --log-level WARNING --profile my-profile
22
+ runbooks finops --log-level WARNING --profile my-profile
23
23
  ```
24
24
 
25
25
  ### Error Focus (ERROR level)
@@ -47,7 +47,7 @@ class EnhancedLoggingIntegrationExample:
47
47
  def __init__(self, module_name: str = "example", log_level: str = "INFO", json_output: bool = False):
48
48
  """
49
49
  Initialize with enhanced logging.
50
-
50
+
51
51
  Args:
52
52
  module_name: Name of the module
53
53
  log_level: Logging level (DEBUG, INFO, WARNING, ERROR)
@@ -63,21 +63,39 @@ class EnhancedLoggingIntegrationExample:
63
63
 
64
64
  # Simulate AWS operations with different outcomes
65
65
  operations = [
66
- {"service": "cost-explorer", "operation": "get_cost_and_usage", "duration": 0.8, "success": True, "resource_count": 25},
67
- {"service": "ec2", "operation": "describe_instances", "duration": 1.2, "success": True, "resource_count": 10},
66
+ {
67
+ "service": "cost-explorer",
68
+ "operation": "get_cost_and_usage",
69
+ "duration": 0.8,
70
+ "success": True,
71
+ "resource_count": 25,
72
+ },
73
+ {
74
+ "service": "ec2",
75
+ "operation": "describe_instances",
76
+ "duration": 1.2,
77
+ "success": True,
78
+ "resource_count": 10,
79
+ },
68
80
  {"service": "s3", "operation": "list_buckets", "duration": 0.3, "success": True, "resource_count": 5},
69
- {"service": "iam", "operation": "get_account_summary", "duration": 15.2, "success": False, "error": "AccessDenied: Insufficient permissions"}
81
+ {
82
+ "service": "iam",
83
+ "operation": "get_account_summary",
84
+ "duration": 15.2,
85
+ "success": False,
86
+ "error": "AccessDenied: Insufficient permissions",
87
+ },
70
88
  ]
71
89
 
72
90
  for op in operations:
73
91
  self.logger.log_aws_operation(
74
92
  operation=op["operation"],
75
- service=op["service"],
93
+ service=op["service"],
76
94
  duration=op["duration"],
77
95
  success=op["success"],
78
96
  resource_count=op.get("resource_count"),
79
97
  error=op.get("error"),
80
- request_id=f"req-{int(time.time())}-{hash(op['service']) % 10000}"
98
+ request_id=f"req-{int(time.time())}-{hash(op['service']) % 10000}",
81
99
  )
82
100
  time.sleep(0.1) # Brief pause for demonstration
83
101
 
@@ -88,23 +106,23 @@ class EnhancedLoggingIntegrationExample:
88
106
 
89
107
  cost_scenarios = [
90
108
  {
91
- "operation": "monthly_ec2_spend_analysis",
92
- "cost_impact": 2500.0,
109
+ "operation": "monthly_ec2_spend_analysis",
110
+ "cost_impact": 2500.0,
93
111
  "savings_opportunity": 750.0,
94
- "recommendation": "Consider Reserved Instances for consistent workloads"
112
+ "recommendation": "Consider Reserved Instances for consistent workloads",
95
113
  },
96
114
  {
97
115
  "operation": "s3_storage_optimization",
98
116
  "cost_impact": 150.0,
99
- "savings_opportunity": 45.0,
100
- "recommendation": "Implement lifecycle policies for infrequent access data"
117
+ "savings_opportunity": 45.0,
118
+ "recommendation": "Implement lifecycle policies for infrequent access data",
101
119
  },
102
120
  {
103
121
  "operation": "unused_eip_analysis",
104
122
  "cost_impact": 50.0,
105
123
  "savings_opportunity": 50.0,
106
- "recommendation": "Release 10 unused Elastic IPs immediately"
107
- }
124
+ "recommendation": "Release 10 unused Elastic IPs immediately",
125
+ },
108
126
  ]
109
127
 
110
128
  for scenario in cost_scenarios:
@@ -117,9 +135,19 @@ class EnhancedLoggingIntegrationExample:
117
135
  print("=" * 60)
118
136
 
119
137
  performance_scenarios = [
120
- {"operation": "inventory_collection", "duration": 2.1, "threshold": 5.0, "memory_usage": 52428800}, # Fast operation
121
- {"operation": "large_cost_analysis", "duration": 8.5, "threshold": 5.0, "memory_usage": 104857600}, # Slow operation
122
- {"operation": "security_scan", "duration": 0.8, "threshold": 2.0, "memory_usage": 26214400} # Quick scan
138
+ {
139
+ "operation": "inventory_collection",
140
+ "duration": 2.1,
141
+ "threshold": 5.0,
142
+ "memory_usage": 52428800,
143
+ }, # Fast operation
144
+ {
145
+ "operation": "large_cost_analysis",
146
+ "duration": 8.5,
147
+ "threshold": 5.0,
148
+ "memory_usage": 104857600,
149
+ }, # Slow operation
150
+ {"operation": "security_scan", "duration": 0.8, "threshold": 2.0, "memory_usage": 26214400}, # Quick scan
123
151
  ]
124
152
 
125
153
  for scenario in performance_scenarios:
@@ -137,9 +165,9 @@ class EnhancedLoggingIntegrationExample:
137
165
  "severity": "high",
138
166
  "remediation_steps": [
139
167
  "Review bucket policy for public access",
140
- "Remove public read permissions if not required",
141
- "Enable bucket logging for audit trail"
142
- ]
168
+ "Remove public read permissions if not required",
169
+ "Enable bucket logging for audit trail",
170
+ ],
143
171
  },
144
172
  {
145
173
  "finding": "IAM user without MFA enabled",
@@ -147,14 +175,14 @@ class EnhancedLoggingIntegrationExample:
147
175
  "remediation_steps": [
148
176
  "Enable MFA for the affected user",
149
177
  "Review IAM policies for excessive permissions",
150
- "Consider using IAM roles instead of users"
151
- ]
178
+ "Consider using IAM roles instead of users",
179
+ ],
152
180
  },
153
181
  {
154
182
  "finding": "Security group with overly permissive rules",
155
183
  "severity": "low",
156
- "remediation_steps": ["Review and tighten security group rules"]
157
- }
184
+ "remediation_steps": ["Review and tighten security group rules"],
185
+ },
158
186
  ]
159
187
 
160
188
  for finding in security_findings:
@@ -185,16 +213,16 @@ class EnhancedLoggingIntegrationExample:
185
213
  """Demonstrate JSON output for programmatic use."""
186
214
  print(f"\n📋 JSON OUTPUT EXAMPLE ({self.log_level} level)")
187
215
  print("=" * 60)
188
-
216
+
189
217
  # Create a JSON logger
190
218
  json_logger = get_module_logger("example_json", level=self.log_level, json_output=True)
191
-
219
+
192
220
  json_logger.info_standard("JSON output demonstration", resource_count=42, operation_status="completed")
193
221
  json_logger.log_cost_analysis(
194
222
  "json_cost_analysis",
195
223
  cost_impact=1200.0,
196
224
  savings_opportunity=360.0,
197
- recommendation="Optimize resource allocation for cost efficiency"
225
+ recommendation="Optimize resource allocation for cost efficiency",
198
226
  )
199
227
 
200
228
  def run_all_demonstrations(self):
@@ -209,8 +237,8 @@ class EnhancedLoggingIntegrationExample:
209
237
  self.demonstrate_performance_logging()
210
238
  self.demonstrate_security_logging()
211
239
  self.demonstrate_operation_context()
212
-
213
- if not hasattr(self.logger, 'json_output') or not self.logger.json_output:
240
+
241
+ if not hasattr(self.logger, "json_output") or not self.logger.json_output:
214
242
  self.demonstrate_json_output()
215
243
 
216
244
  def _get_user_type_description(self) -> str:
@@ -218,8 +246,8 @@ class EnhancedLoggingIntegrationExample:
218
246
  descriptions = {
219
247
  "DEBUG": "Tech Users (SRE/DevOps) - Full technical details, API traces, performance metrics",
220
248
  "INFO": "Standard Users - Clean operation status, progress indicators, business-friendly output",
221
- "WARNING": "Business Users - Cost insights, recommendations, optimization opportunities",
222
- "ERROR": "All Users - Clear error messages with solutions and troubleshooting steps"
249
+ "WARNING": "Business Users - Cost insights, recommendations, optimization opportunities",
250
+ "ERROR": "All Users - Clear error messages with solutions and troubleshooting steps",
223
251
  }
224
252
  return descriptions.get(self.log_level, "Unknown user type")
225
253
 
@@ -230,28 +258,28 @@ def main():
230
258
  print("=" * 80)
231
259
  print("This demonstration shows how logging adapts content based on user type:")
232
260
  print("• DEBUG Level: Technical users (SRE/DevOps)")
233
- print("• INFO Level: Standard users (default)")
261
+ print("• INFO Level: Standard users (default)")
234
262
  print("• WARNING Level: Business users")
235
263
  print("• ERROR Level: All users (minimal output)")
236
264
  print("=" * 80)
237
265
 
238
266
  # Test all log levels
239
267
  log_levels = ["DEBUG", "INFO", "WARNING", "ERROR"]
240
-
268
+
241
269
  for level in log_levels:
242
270
  demo = EnhancedLoggingIntegrationExample("enhanced_logging_demo", level)
243
271
  demo.run_all_demonstrations()
244
-
272
+
245
273
  if level != "ERROR": # Add separator except for last level
246
274
  print(f"\n{'=' * 80}\n")
247
275
 
248
276
  print("\n✅ DEMONSTRATION COMPLETE")
249
277
  print("\nTo use enhanced logging in your module:")
250
- print("1. from runbooks.enterprise.logging import get_module_logger")
278
+ print("1. from runbooks.enterprise.logging import get_module_logger")
251
279
  print("2. logger = get_module_logger('your_module_name')")
252
280
  print("3. Use logger.info_standard(), logger.debug_tech(), logger.warning_business(), etc.")
253
281
  print("4. Use logger.log_aws_operation(), logger.log_cost_analysis() for convenience")
254
282
 
255
283
 
256
284
  if __name__ == "__main__":
257
- main()
285
+ main()
@@ -12,13 +12,13 @@ from typing import Union
12
12
  def get_required_env(var_name: str) -> str:
13
13
  """
14
14
  Get required string environment variable - NO hardcoded defaults.
15
-
15
+
16
16
  Args:
17
17
  var_name: Environment variable name
18
-
18
+
19
19
  Returns:
20
20
  Environment variable value
21
-
21
+
22
22
  Raises:
23
23
  ValueError: If environment variable is not set
24
24
  """
@@ -31,13 +31,13 @@ def get_required_env(var_name: str) -> str:
31
31
  def get_required_env_int(var_name: str) -> int:
32
32
  """
33
33
  Get required integer environment variable - NO hardcoded defaults.
34
-
34
+
35
35
  Args:
36
36
  var_name: Environment variable name
37
-
37
+
38
38
  Returns:
39
39
  Environment variable value as integer
40
-
40
+
41
41
  Raises:
42
42
  ValueError: If environment variable is not set or not a valid integer
43
43
  """
@@ -51,13 +51,13 @@ def get_required_env_int(var_name: str) -> int:
51
51
  def get_required_env_float(var_name: str) -> float:
52
52
  """
53
53
  Get required float environment variable - NO hardcoded defaults.
54
-
54
+
55
55
  Args:
56
56
  var_name: Environment variable name
57
-
57
+
58
58
  Returns:
59
59
  Environment variable value as float
60
-
60
+
61
61
  Raises:
62
62
  ValueError: If environment variable is not set or not a valid float
63
63
  """
@@ -71,20 +71,20 @@ def get_required_env_float(var_name: str) -> float:
71
71
  def get_required_env_bool(var_name: str) -> bool:
72
72
  """
73
73
  Get required boolean environment variable - NO hardcoded defaults.
74
-
74
+
75
75
  Args:
76
76
  var_name: Environment variable name
77
-
77
+
78
78
  Returns:
79
79
  Environment variable value as boolean
80
-
80
+
81
81
  Raises:
82
82
  ValueError: If environment variable is not set
83
83
  """
84
84
  value = get_required_env(var_name).lower()
85
- if value in ('true', '1', 'yes', 'on'):
85
+ if value in ("true", "1", "yes", "on"):
86
86
  return True
87
- elif value in ('false', '0', 'no', 'off'):
87
+ elif value in ("false", "0", "no", "off"):
88
88
  return False
89
89
  else:
90
90
  raise ValueError(f"Environment variable {var_name} must be a valid boolean (true/false), got: {value}")
@@ -92,5 +92,5 @@ def get_required_env_bool(var_name: str) -> bool:
92
92
 
93
93
  # Legacy compatibility function names for existing code
94
94
  _get_required_env_float = get_required_env_float
95
- _get_required_env_int = get_required_env_int
96
- _get_required_env = get_required_env
95
+ _get_required_env_int = get_required_env_int
96
+ _get_required_env = get_required_env