fix: auto-fix code issues (cron)
- 修复重复导入/字段 - 修复异常处理 - 修复PEP8格式问题 - 添加类型注解
This commit is contained in:
@@ -10,26 +10,27 @@ InsightFlow Operations & Monitoring Manager - Phase 8 Task 8
|
||||
作者: InsightFlow Team
|
||||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
import sqlite3
|
||||
import httpx
|
||||
import asyncio
|
||||
import hashlib
|
||||
import uuid
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
import sqlite3
|
||||
import statistics
|
||||
from typing import List, Dict, Optional, Tuple, Callable
|
||||
import time
|
||||
import uuid
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timedelta
|
||||
from enum import Enum
|
||||
from enum import StrEnum
|
||||
|
||||
import httpx
|
||||
|
||||
# Database path
|
||||
DB_PATH = os.path.join(os.path.dirname(__file__), "insightflow.db")
|
||||
|
||||
|
||||
class AlertSeverity(str, Enum):
|
||||
class AlertSeverity(StrEnum):
|
||||
"""告警严重级别 P0-P3"""
|
||||
|
||||
P0 = "p0" # 紧急 - 系统不可用,需要立即处理
|
||||
@@ -38,7 +39,7 @@ class AlertSeverity(str, Enum):
|
||||
P3 = "p3" # 轻微 - 非核心功能问题,24小时内处理
|
||||
|
||||
|
||||
class AlertStatus(str, Enum):
|
||||
class AlertStatus(StrEnum):
|
||||
"""告警状态"""
|
||||
|
||||
FIRING = "firing" # 正在告警
|
||||
@@ -47,7 +48,7 @@ class AlertStatus(str, Enum):
|
||||
SUPPRESSED = "suppressed" # 已抑制
|
||||
|
||||
|
||||
class AlertChannelType(str, Enum):
|
||||
class AlertChannelType(StrEnum):
|
||||
"""告警渠道类型"""
|
||||
|
||||
PAGERDUTY = "pagerduty"
|
||||
@@ -60,7 +61,7 @@ class AlertChannelType(str, Enum):
|
||||
WEBHOOK = "webhook"
|
||||
|
||||
|
||||
class AlertRuleType(str, Enum):
|
||||
class AlertRuleType(StrEnum):
|
||||
"""告警规则类型"""
|
||||
|
||||
THRESHOLD = "threshold" # 阈值告警
|
||||
@@ -69,7 +70,7 @@ class AlertRuleType(str, Enum):
|
||||
COMPOSITE = "composite" # 复合告警
|
||||
|
||||
|
||||
class ResourceType(str, Enum):
|
||||
class ResourceType(StrEnum):
|
||||
"""资源类型"""
|
||||
|
||||
CPU = "cpu"
|
||||
@@ -82,7 +83,7 @@ class ResourceType(str, Enum):
|
||||
QUEUE = "queue"
|
||||
|
||||
|
||||
class ScalingAction(str, Enum):
|
||||
class ScalingAction(StrEnum):
|
||||
"""扩缩容动作"""
|
||||
|
||||
SCALE_UP = "scale_up" # 扩容
|
||||
@@ -90,7 +91,7 @@ class ScalingAction(str, Enum):
|
||||
MAINTAIN = "maintain" # 保持
|
||||
|
||||
|
||||
class HealthStatus(str, Enum):
|
||||
class HealthStatus(StrEnum):
|
||||
"""健康状态"""
|
||||
|
||||
HEALTHY = "healthy"
|
||||
@@ -99,7 +100,7 @@ class HealthStatus(str, Enum):
|
||||
UNKNOWN = "unknown"
|
||||
|
||||
|
||||
class BackupStatus(str, Enum):
|
||||
class BackupStatus(StrEnum):
|
||||
"""备份状态"""
|
||||
|
||||
PENDING = "pending"
|
||||
@@ -124,9 +125,9 @@ class AlertRule:
|
||||
threshold: float
|
||||
duration: int # 持续时间(秒)
|
||||
evaluation_interval: int # 评估间隔(秒)
|
||||
channels: List[str] # 告警渠道ID列表
|
||||
labels: Dict[str, str] # 标签
|
||||
annotations: Dict[str, str] # 注释
|
||||
channels: list[str] # 告警渠道ID列表
|
||||
labels: dict[str, str] # 标签
|
||||
annotations: dict[str, str] # 注释
|
||||
is_enabled: bool
|
||||
created_at: str
|
||||
updated_at: str
|
||||
@@ -141,12 +142,12 @@ class AlertChannel:
|
||||
tenant_id: str
|
||||
name: str
|
||||
channel_type: AlertChannelType
|
||||
config: Dict # 渠道特定配置
|
||||
severity_filter: List[str] # 过滤的告警级别
|
||||
config: dict # 渠道特定配置
|
||||
severity_filter: list[str] # 过滤的告警级别
|
||||
is_enabled: bool
|
||||
success_count: int
|
||||
fail_count: int
|
||||
last_used_at: Optional[str]
|
||||
last_used_at: str | None
|
||||
created_at: str
|
||||
updated_at: str
|
||||
|
||||
@@ -165,13 +166,13 @@ class Alert:
|
||||
metric: str
|
||||
value: float
|
||||
threshold: float
|
||||
labels: Dict[str, str]
|
||||
annotations: Dict[str, str]
|
||||
labels: dict[str, str]
|
||||
annotations: dict[str, str]
|
||||
started_at: str
|
||||
resolved_at: Optional[str]
|
||||
acknowledged_by: Optional[str]
|
||||
acknowledged_at: Optional[str]
|
||||
notification_sent: Dict[str, bool] # 渠道发送状态
|
||||
resolved_at: str | None
|
||||
acknowledged_by: str | None
|
||||
acknowledged_at: str | None
|
||||
notification_sent: dict[str, bool] # 渠道发送状态
|
||||
suppression_count: int # 抑制计数
|
||||
|
||||
|
||||
@@ -182,11 +183,11 @@ class AlertSuppressionRule:
|
||||
id: str
|
||||
tenant_id: str
|
||||
name: str
|
||||
matchers: Dict[str, str] # 匹配条件
|
||||
matchers: dict[str, str] # 匹配条件
|
||||
duration: int # 抑制持续时间(秒)
|
||||
is_regex: bool # 是否使用正则匹配
|
||||
created_at: str
|
||||
expires_at: Optional[str]
|
||||
expires_at: str | None
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -196,7 +197,7 @@ class AlertGroup:
|
||||
id: str
|
||||
tenant_id: str
|
||||
group_key: str # 聚合键
|
||||
alerts: List[str] # 告警ID列表
|
||||
alerts: list[str] # 告警ID列表
|
||||
created_at: str
|
||||
updated_at: str
|
||||
|
||||
@@ -213,7 +214,7 @@ class ResourceMetric:
|
||||
metric_value: float
|
||||
unit: str
|
||||
timestamp: str
|
||||
metadata: Dict
|
||||
metadata: dict
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -267,8 +268,8 @@ class ScalingEvent:
|
||||
triggered_by: str # 触发来源: manual, auto, scheduled
|
||||
status: str # pending, in_progress, completed, failed
|
||||
started_at: str
|
||||
completed_at: Optional[str]
|
||||
error_message: Optional[str]
|
||||
completed_at: str | None
|
||||
error_message: str | None
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -281,7 +282,7 @@ class HealthCheck:
|
||||
target_type: str # service, database, api, etc.
|
||||
target_id: str
|
||||
check_type: str # http, tcp, ping, custom
|
||||
check_config: Dict # 检查配置
|
||||
check_config: dict # 检查配置
|
||||
interval: int # 检查间隔(秒)
|
||||
timeout: int # 超时时间(秒)
|
||||
retry_count: int
|
||||
@@ -302,7 +303,7 @@ class HealthCheckResult:
|
||||
status: HealthStatus
|
||||
response_time: float # 响应时间(毫秒)
|
||||
message: str
|
||||
details: Dict
|
||||
details: dict
|
||||
checked_at: str
|
||||
|
||||
|
||||
@@ -314,7 +315,7 @@ class FailoverConfig:
|
||||
tenant_id: str
|
||||
name: str
|
||||
primary_region: str
|
||||
secondary_regions: List[str] # 备用区域列表
|
||||
secondary_regions: list[str] # 备用区域列表
|
||||
failover_trigger: str # 触发条件
|
||||
auto_failover: bool
|
||||
failover_timeout: int # 故障转移超时(秒)
|
||||
@@ -336,8 +337,8 @@ class FailoverEvent:
|
||||
reason: str
|
||||
status: str # initiated, in_progress, completed, failed, rolled_back
|
||||
started_at: str
|
||||
completed_at: Optional[str]
|
||||
rolled_back_at: Optional[str]
|
||||
completed_at: str | None
|
||||
rolled_back_at: str | None
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -371,9 +372,9 @@ class BackupRecord:
|
||||
size_bytes: int
|
||||
checksum: str
|
||||
started_at: str
|
||||
completed_at: Optional[str]
|
||||
verified_at: Optional[str]
|
||||
error_message: Optional[str]
|
||||
completed_at: str | None
|
||||
verified_at: str | None
|
||||
error_message: str | None
|
||||
storage_path: str
|
||||
|
||||
|
||||
@@ -386,9 +387,9 @@ class CostReport:
|
||||
report_period: str # YYYY-MM
|
||||
total_cost: float
|
||||
currency: str
|
||||
breakdown: Dict[str, float] # 按资源类型分解
|
||||
trends: Dict # 趋势数据
|
||||
anomalies: List[Dict] # 异常检测
|
||||
breakdown: dict[str, float] # 按资源类型分解
|
||||
trends: dict # 趋势数据
|
||||
anomalies: list[dict] # 异常检测
|
||||
created_at: str
|
||||
|
||||
|
||||
@@ -405,7 +406,7 @@ class ResourceUtilization:
|
||||
avg_utilization: float
|
||||
idle_time_percent: float
|
||||
report_date: str
|
||||
recommendations: List[str]
|
||||
recommendations: list[str]
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -438,11 +439,11 @@ class CostOptimizationSuggestion:
|
||||
currency: str
|
||||
confidence: float
|
||||
difficulty: str # easy, medium, hard
|
||||
implementation_steps: List[str]
|
||||
implementation_steps: list[str]
|
||||
risk_level: str # low, medium, high
|
||||
is_applied: bool
|
||||
created_at: str
|
||||
applied_at: Optional[str]
|
||||
applied_at: str | None
|
||||
|
||||
|
||||
class OpsManager:
|
||||
@@ -450,7 +451,7 @@ class OpsManager:
|
||||
|
||||
def __init__(self, db_path: str = DB_PATH):
|
||||
self.db_path = db_path
|
||||
self._alert_evaluators: Dict[str, Callable] = {}
|
||||
self._alert_evaluators: dict[str, Callable] = {}
|
||||
self._running = False
|
||||
self._evaluator_thread = None
|
||||
self._register_default_evaluators()
|
||||
@@ -481,9 +482,9 @@ class OpsManager:
|
||||
threshold: float,
|
||||
duration: int,
|
||||
evaluation_interval: int,
|
||||
channels: List[str],
|
||||
labels: Dict,
|
||||
annotations: Dict,
|
||||
channels: list[str],
|
||||
labels: dict,
|
||||
annotations: dict,
|
||||
created_by: str,
|
||||
) -> AlertRule:
|
||||
"""创建告警规则"""
|
||||
@@ -545,7 +546,7 @@ class OpsManager:
|
||||
|
||||
return rule
|
||||
|
||||
def get_alert_rule(self, rule_id: str) -> Optional[AlertRule]:
|
||||
def get_alert_rule(self, rule_id: str) -> AlertRule | None:
|
||||
"""获取告警规则"""
|
||||
with self._get_db() as conn:
|
||||
row = conn.execute("SELECT * FROM alert_rules WHERE id = ?", (rule_id,)).fetchone()
|
||||
@@ -554,7 +555,7 @@ class OpsManager:
|
||||
return self._row_to_alert_rule(row)
|
||||
return None
|
||||
|
||||
def list_alert_rules(self, tenant_id: str, is_enabled: Optional[bool] = None) -> List[AlertRule]:
|
||||
def list_alert_rules(self, tenant_id: str, is_enabled: bool | None = None) -> list[AlertRule]:
|
||||
"""列出租户的所有告警规则"""
|
||||
query = "SELECT * FROM alert_rules WHERE tenant_id = ?"
|
||||
params = [tenant_id]
|
||||
@@ -569,7 +570,7 @@ class OpsManager:
|
||||
rows = conn.execute(query, params).fetchall()
|
||||
return [self._row_to_alert_rule(row) for row in rows]
|
||||
|
||||
def update_alert_rule(self, rule_id: str, **kwargs) -> Optional[AlertRule]:
|
||||
def update_alert_rule(self, rule_id: str, **kwargs) -> AlertRule | None:
|
||||
"""更新告警规则"""
|
||||
allowed_fields = [
|
||||
"name",
|
||||
@@ -619,7 +620,7 @@ class OpsManager:
|
||||
# ==================== 告警渠道管理 ====================
|
||||
|
||||
def create_alert_channel(
|
||||
self, tenant_id: str, name: str, channel_type: AlertChannelType, config: Dict, severity_filter: List[str] = None
|
||||
self, tenant_id: str, name: str, channel_type: AlertChannelType, config: dict, severity_filter: list[str] = None
|
||||
) -> AlertChannel:
|
||||
"""创建告警渠道"""
|
||||
channel_id = f"ac_{uuid.uuid4().hex[:16]}"
|
||||
@@ -667,7 +668,7 @@ class OpsManager:
|
||||
|
||||
return channel
|
||||
|
||||
def get_alert_channel(self, channel_id: str) -> Optional[AlertChannel]:
|
||||
def get_alert_channel(self, channel_id: str) -> AlertChannel | None:
|
||||
"""获取告警渠道"""
|
||||
with self._get_db() as conn:
|
||||
row = conn.execute("SELECT * FROM alert_channels WHERE id = ?", (channel_id,)).fetchone()
|
||||
@@ -676,7 +677,7 @@ class OpsManager:
|
||||
return self._row_to_alert_channel(row)
|
||||
return None
|
||||
|
||||
def list_alert_channels(self, tenant_id: str) -> List[AlertChannel]:
|
||||
def list_alert_channels(self, tenant_id: str) -> list[AlertChannel]:
|
||||
"""列出租户的所有告警渠道"""
|
||||
with self._get_db() as conn:
|
||||
rows = conn.execute(
|
||||
@@ -715,7 +716,7 @@ class OpsManager:
|
||||
|
||||
# ==================== 告警评估与触发 ====================
|
||||
|
||||
def _evaluate_threshold_rule(self, rule: AlertRule, metrics: List[ResourceMetric]) -> bool:
|
||||
def _evaluate_threshold_rule(self, rule: AlertRule, metrics: list[ResourceMetric]) -> bool:
|
||||
"""评估阈值告警规则"""
|
||||
if not metrics:
|
||||
return False
|
||||
@@ -746,7 +747,7 @@ class OpsManager:
|
||||
|
||||
return False
|
||||
|
||||
def _evaluate_anomaly_rule(self, rule: AlertRule, metrics: List[ResourceMetric]) -> bool:
|
||||
def _evaluate_anomaly_rule(self, rule: AlertRule, metrics: list[ResourceMetric]) -> bool:
|
||||
"""评估异常检测规则(基于标准差)"""
|
||||
if len(metrics) < 10:
|
||||
return False
|
||||
@@ -764,7 +765,7 @@ class OpsManager:
|
||||
|
||||
return z_score > 3.0
|
||||
|
||||
def _evaluate_predictive_rule(self, rule: AlertRule, metrics: List[ResourceMetric]) -> bool:
|
||||
def _evaluate_predictive_rule(self, rule: AlertRule, metrics: list[ResourceMetric]) -> bool:
|
||||
"""评估预测性告警规则(基于线性趋势)"""
|
||||
if len(metrics) < 5:
|
||||
return False
|
||||
@@ -814,7 +815,7 @@ class OpsManager:
|
||||
# 触发告警
|
||||
await self._trigger_alert(rule, metrics[-1] if metrics else None)
|
||||
|
||||
async def _trigger_alert(self, rule: AlertRule, metric: Optional[ResourceMetric]):
|
||||
async def _trigger_alert(self, rule: AlertRule, metric: ResourceMetric | None):
|
||||
"""触发告警"""
|
||||
# 检查是否已有相同告警在触发中
|
||||
existing = self.get_active_alert_by_rule(rule.id)
|
||||
@@ -1166,7 +1167,7 @@ class OpsManager:
|
||||
|
||||
# ==================== 告警查询与管理 ====================
|
||||
|
||||
def get_active_alert_by_rule(self, rule_id: str) -> Optional[Alert]:
|
||||
def get_active_alert_by_rule(self, rule_id: str) -> Alert | None:
|
||||
"""获取规则对应的活跃告警"""
|
||||
with self._get_db() as conn:
|
||||
row = conn.execute(
|
||||
@@ -1180,7 +1181,7 @@ class OpsManager:
|
||||
return self._row_to_alert(row)
|
||||
return None
|
||||
|
||||
def get_alert(self, alert_id: str) -> Optional[Alert]:
|
||||
def get_alert(self, alert_id: str) -> Alert | None:
|
||||
"""获取告警详情"""
|
||||
with self._get_db() as conn:
|
||||
row = conn.execute("SELECT * FROM alerts WHERE id = ?", (alert_id,)).fetchone()
|
||||
@@ -1192,10 +1193,10 @@ class OpsManager:
|
||||
def list_alerts(
|
||||
self,
|
||||
tenant_id: str,
|
||||
status: Optional[AlertStatus] = None,
|
||||
severity: Optional[AlertSeverity] = None,
|
||||
status: AlertStatus | None = None,
|
||||
severity: AlertSeverity | None = None,
|
||||
limit: int = 100,
|
||||
) -> List[Alert]:
|
||||
) -> list[Alert]:
|
||||
"""列出租户的告警"""
|
||||
query = "SELECT * FROM alerts WHERE tenant_id = ?"
|
||||
params = [tenant_id]
|
||||
@@ -1214,7 +1215,7 @@ class OpsManager:
|
||||
rows = conn.execute(query, params).fetchall()
|
||||
return [self._row_to_alert(row) for row in rows]
|
||||
|
||||
def acknowledge_alert(self, alert_id: str, user_id: str) -> Optional[Alert]:
|
||||
def acknowledge_alert(self, alert_id: str, user_id: str) -> Alert | None:
|
||||
"""确认告警"""
|
||||
now = datetime.now().isoformat()
|
||||
|
||||
@@ -1231,7 +1232,7 @@ class OpsManager:
|
||||
|
||||
return self.get_alert(alert_id)
|
||||
|
||||
def resolve_alert(self, alert_id: str) -> Optional[Alert]:
|
||||
def resolve_alert(self, alert_id: str) -> Alert | None:
|
||||
"""解决告警"""
|
||||
now = datetime.now().isoformat()
|
||||
|
||||
@@ -1306,10 +1307,10 @@ class OpsManager:
|
||||
self,
|
||||
tenant_id: str,
|
||||
name: str,
|
||||
matchers: Dict[str, str],
|
||||
matchers: dict[str, str],
|
||||
duration: int,
|
||||
is_regex: bool = False,
|
||||
expires_at: Optional[str] = None,
|
||||
expires_at: str | None = None,
|
||||
) -> AlertSuppressionRule:
|
||||
"""创建告警抑制规则"""
|
||||
rule_id = f"sr_{uuid.uuid4().hex[:16]}"
|
||||
@@ -1394,7 +1395,7 @@ class OpsManager:
|
||||
metric_name: str,
|
||||
metric_value: float,
|
||||
unit: str,
|
||||
metadata: Dict = None,
|
||||
metadata: dict = None,
|
||||
) -> ResourceMetric:
|
||||
"""记录资源指标"""
|
||||
metric_id = f"rm_{uuid.uuid4().hex[:16]}"
|
||||
@@ -1436,7 +1437,7 @@ class OpsManager:
|
||||
|
||||
return metric
|
||||
|
||||
def get_recent_metrics(self, tenant_id: str, metric_name: str, seconds: int = 3600) -> List[ResourceMetric]:
|
||||
def get_recent_metrics(self, tenant_id: str, metric_name: str, seconds: int = 3600) -> list[ResourceMetric]:
|
||||
"""获取最近的指标数据"""
|
||||
cutoff_time = (datetime.now() - timedelta(seconds=seconds)).isoformat()
|
||||
|
||||
@@ -1458,7 +1459,7 @@ class OpsManager:
|
||||
metric_name: str,
|
||||
start_time: str,
|
||||
end_time: str,
|
||||
) -> List[ResourceMetric]:
|
||||
) -> list[ResourceMetric]:
|
||||
"""获取指定资源的指标数据"""
|
||||
with self._get_db() as conn:
|
||||
rows = conn.execute(
|
||||
@@ -1549,7 +1550,7 @@ class OpsManager:
|
||||
|
||||
return plan
|
||||
|
||||
def _calculate_trend(self, values: List[float]) -> float:
|
||||
def _calculate_trend(self, values: list[float]) -> float:
|
||||
"""计算趋势(增长率)"""
|
||||
if len(values) < 2:
|
||||
return 0.0
|
||||
@@ -1576,7 +1577,7 @@ class OpsManager:
|
||||
return slope / mean_y
|
||||
return 0.0
|
||||
|
||||
def get_capacity_plans(self, tenant_id: str) -> List[CapacityPlan]:
|
||||
def get_capacity_plans(self, tenant_id: str) -> list[CapacityPlan]:
|
||||
"""获取容量规划列表"""
|
||||
with self._get_db() as conn:
|
||||
rows = conn.execute(
|
||||
@@ -1653,7 +1654,7 @@ class OpsManager:
|
||||
|
||||
return policy
|
||||
|
||||
def get_auto_scaling_policy(self, policy_id: str) -> Optional[AutoScalingPolicy]:
|
||||
def get_auto_scaling_policy(self, policy_id: str) -> AutoScalingPolicy | None:
|
||||
"""获取自动扩缩容策略"""
|
||||
with self._get_db() as conn:
|
||||
row = conn.execute("SELECT * FROM auto_scaling_policies WHERE id = ?", (policy_id,)).fetchone()
|
||||
@@ -1662,7 +1663,7 @@ class OpsManager:
|
||||
return self._row_to_auto_scaling_policy(row)
|
||||
return None
|
||||
|
||||
def list_auto_scaling_policies(self, tenant_id: str) -> List[AutoScalingPolicy]:
|
||||
def list_auto_scaling_policies(self, tenant_id: str) -> list[AutoScalingPolicy]:
|
||||
"""列出租户的自动扩缩容策略"""
|
||||
with self._get_db() as conn:
|
||||
rows = conn.execute(
|
||||
@@ -1672,7 +1673,7 @@ class OpsManager:
|
||||
|
||||
def evaluate_scaling_policy(
|
||||
self, policy_id: str, current_instances: int, current_utilization: float
|
||||
) -> Optional[ScalingEvent]:
|
||||
) -> ScalingEvent | None:
|
||||
"""评估扩缩容策略"""
|
||||
policy = self.get_auto_scaling_policy(policy_id)
|
||||
if not policy or not policy.is_enabled:
|
||||
@@ -1754,7 +1755,7 @@ class OpsManager:
|
||||
|
||||
return event
|
||||
|
||||
def get_last_scaling_event(self, policy_id: str) -> Optional[ScalingEvent]:
|
||||
def get_last_scaling_event(self, policy_id: str) -> ScalingEvent | None:
|
||||
"""获取最近的扩缩容事件"""
|
||||
with self._get_db() as conn:
|
||||
row = conn.execute(
|
||||
@@ -1770,7 +1771,7 @@ class OpsManager:
|
||||
|
||||
def update_scaling_event_status(
|
||||
self, event_id: str, status: str, error_message: str = None
|
||||
) -> Optional[ScalingEvent]:
|
||||
) -> ScalingEvent | None:
|
||||
"""更新扩缩容事件状态"""
|
||||
now = datetime.now().isoformat()
|
||||
|
||||
@@ -1797,7 +1798,7 @@ class OpsManager:
|
||||
|
||||
return self.get_scaling_event(event_id)
|
||||
|
||||
def get_scaling_event(self, event_id: str) -> Optional[ScalingEvent]:
|
||||
def get_scaling_event(self, event_id: str) -> ScalingEvent | None:
|
||||
"""获取扩缩容事件"""
|
||||
with self._get_db() as conn:
|
||||
row = conn.execute("SELECT * FROM scaling_events WHERE id = ?", (event_id,)).fetchone()
|
||||
@@ -1806,7 +1807,7 @@ class OpsManager:
|
||||
return self._row_to_scaling_event(row)
|
||||
return None
|
||||
|
||||
def list_scaling_events(self, tenant_id: str, policy_id: str = None, limit: int = 100) -> List[ScalingEvent]:
|
||||
def list_scaling_events(self, tenant_id: str, policy_id: str = None, limit: int = 100) -> list[ScalingEvent]:
|
||||
"""列出租户的扩缩容事件"""
|
||||
query = "SELECT * FROM scaling_events WHERE tenant_id = ?"
|
||||
params = [tenant_id]
|
||||
@@ -1831,7 +1832,7 @@ class OpsManager:
|
||||
target_type: str,
|
||||
target_id: str,
|
||||
check_type: str,
|
||||
check_config: Dict,
|
||||
check_config: dict,
|
||||
interval: int = 60,
|
||||
timeout: int = 10,
|
||||
retry_count: int = 3,
|
||||
@@ -1889,7 +1890,7 @@ class OpsManager:
|
||||
|
||||
return check
|
||||
|
||||
def get_health_check(self, check_id: str) -> Optional[HealthCheck]:
|
||||
def get_health_check(self, check_id: str) -> HealthCheck | None:
|
||||
"""获取健康检查配置"""
|
||||
with self._get_db() as conn:
|
||||
row = conn.execute("SELECT * FROM health_checks WHERE id = ?", (check_id,)).fetchone()
|
||||
@@ -1898,7 +1899,7 @@ class OpsManager:
|
||||
return self._row_to_health_check(row)
|
||||
return None
|
||||
|
||||
def list_health_checks(self, tenant_id: str) -> List[HealthCheck]:
|
||||
def list_health_checks(self, tenant_id: str) -> list[HealthCheck]:
|
||||
"""列出租户的健康检查"""
|
||||
with self._get_db() as conn:
|
||||
rows = conn.execute(
|
||||
@@ -1958,7 +1959,7 @@ class OpsManager:
|
||||
|
||||
return result
|
||||
|
||||
async def _check_http_health(self, check: HealthCheck) -> Tuple[HealthStatus, float, str]:
|
||||
async def _check_http_health(self, check: HealthCheck) -> tuple[HealthStatus, float, str]:
|
||||
"""HTTP 健康检查"""
|
||||
config = check.check_config
|
||||
url = config.get("url")
|
||||
@@ -1980,7 +1981,7 @@ class OpsManager:
|
||||
except Exception as e:
|
||||
return HealthStatus.UNHEALTHY, (time.time() - start_time) * 1000, str(e)
|
||||
|
||||
async def _check_tcp_health(self, check: HealthCheck) -> Tuple[HealthStatus, float, str]:
|
||||
async def _check_tcp_health(self, check: HealthCheck) -> tuple[HealthStatus, float, str]:
|
||||
"""TCP 健康检查"""
|
||||
config = check.check_config
|
||||
host = config.get("host")
|
||||
@@ -1996,12 +1997,12 @@ class OpsManager:
|
||||
writer.close()
|
||||
await writer.wait_closed()
|
||||
return HealthStatus.HEALTHY, response_time, "TCP connection successful"
|
||||
except asyncio.TimeoutError:
|
||||
except TimeoutError:
|
||||
return HealthStatus.UNHEALTHY, (time.time() - start_time) * 1000, "Connection timeout"
|
||||
except Exception as e:
|
||||
return HealthStatus.UNHEALTHY, (time.time() - start_time) * 1000, str(e)
|
||||
|
||||
async def _check_ping_health(self, check: HealthCheck) -> Tuple[HealthStatus, float, str]:
|
||||
async def _check_ping_health(self, check: HealthCheck) -> tuple[HealthStatus, float, str]:
|
||||
"""Ping 健康检查(模拟)"""
|
||||
config = check.check_config
|
||||
host = config.get("host")
|
||||
@@ -2013,7 +2014,7 @@ class OpsManager:
|
||||
# 这里模拟成功
|
||||
return HealthStatus.HEALTHY, 10.0, "Ping successful"
|
||||
|
||||
def get_health_check_results(self, check_id: str, limit: int = 100) -> List[HealthCheckResult]:
|
||||
def get_health_check_results(self, check_id: str, limit: int = 100) -> list[HealthCheckResult]:
|
||||
"""获取健康检查历史结果"""
|
||||
with self._get_db() as conn:
|
||||
rows = conn.execute(
|
||||
@@ -2031,7 +2032,7 @@ class OpsManager:
|
||||
tenant_id: str,
|
||||
name: str,
|
||||
primary_region: str,
|
||||
secondary_regions: List[str],
|
||||
secondary_regions: list[str],
|
||||
failover_trigger: str,
|
||||
auto_failover: bool = False,
|
||||
failover_timeout: int = 300,
|
||||
@@ -2083,7 +2084,7 @@ class OpsManager:
|
||||
|
||||
return config
|
||||
|
||||
def get_failover_config(self, config_id: str) -> Optional[FailoverConfig]:
|
||||
def get_failover_config(self, config_id: str) -> FailoverConfig | None:
|
||||
"""获取故障转移配置"""
|
||||
with self._get_db() as conn:
|
||||
row = conn.execute("SELECT * FROM failover_configs WHERE id = ?", (config_id,)).fetchone()
|
||||
@@ -2092,7 +2093,7 @@ class OpsManager:
|
||||
return self._row_to_failover_config(row)
|
||||
return None
|
||||
|
||||
def list_failover_configs(self, tenant_id: str) -> List[FailoverConfig]:
|
||||
def list_failover_configs(self, tenant_id: str) -> list[FailoverConfig]:
|
||||
"""列出租户的故障转移配置"""
|
||||
with self._get_db() as conn:
|
||||
rows = conn.execute(
|
||||
@@ -2100,7 +2101,7 @@ class OpsManager:
|
||||
).fetchall()
|
||||
return [self._row_to_failover_config(row) for row in rows]
|
||||
|
||||
def initiate_failover(self, config_id: str, reason: str) -> Optional[FailoverEvent]:
|
||||
def initiate_failover(self, config_id: str, reason: str) -> FailoverEvent | None:
|
||||
"""发起故障转移"""
|
||||
config = self.get_failover_config(config_id)
|
||||
if not config or not config.is_enabled:
|
||||
@@ -2150,7 +2151,7 @@ class OpsManager:
|
||||
|
||||
return event
|
||||
|
||||
def update_failover_status(self, event_id: str, status: str) -> Optional[FailoverEvent]:
|
||||
def update_failover_status(self, event_id: str, status: str) -> FailoverEvent | None:
|
||||
"""更新故障转移状态"""
|
||||
now = datetime.now().isoformat()
|
||||
|
||||
@@ -2186,7 +2187,7 @@ class OpsManager:
|
||||
|
||||
return self.get_failover_event(event_id)
|
||||
|
||||
def get_failover_event(self, event_id: str) -> Optional[FailoverEvent]:
|
||||
def get_failover_event(self, event_id: str) -> FailoverEvent | None:
|
||||
"""获取故障转移事件"""
|
||||
with self._get_db() as conn:
|
||||
row = conn.execute("SELECT * FROM failover_events WHERE id = ?", (event_id,)).fetchone()
|
||||
@@ -2195,7 +2196,7 @@ class OpsManager:
|
||||
return self._row_to_failover_event(row)
|
||||
return None
|
||||
|
||||
def list_failover_events(self, tenant_id: str, limit: int = 100) -> List[FailoverEvent]:
|
||||
def list_failover_events(self, tenant_id: str, limit: int = 100) -> list[FailoverEvent]:
|
||||
"""列出租户的故障转移事件"""
|
||||
with self._get_db() as conn:
|
||||
rows = conn.execute(
|
||||
@@ -2272,7 +2273,7 @@ class OpsManager:
|
||||
|
||||
return job
|
||||
|
||||
def get_backup_job(self, job_id: str) -> Optional[BackupJob]:
|
||||
def get_backup_job(self, job_id: str) -> BackupJob | None:
|
||||
"""获取备份任务"""
|
||||
with self._get_db() as conn:
|
||||
row = conn.execute("SELECT * FROM backup_jobs WHERE id = ?", (job_id,)).fetchone()
|
||||
@@ -2281,7 +2282,7 @@ class OpsManager:
|
||||
return self._row_to_backup_job(row)
|
||||
return None
|
||||
|
||||
def list_backup_jobs(self, tenant_id: str) -> List[BackupJob]:
|
||||
def list_backup_jobs(self, tenant_id: str) -> list[BackupJob]:
|
||||
"""列出租户的备份任务"""
|
||||
with self._get_db() as conn:
|
||||
rows = conn.execute(
|
||||
@@ -2289,7 +2290,7 @@ class OpsManager:
|
||||
).fetchall()
|
||||
return [self._row_to_backup_job(row) for row in rows]
|
||||
|
||||
def execute_backup(self, job_id: str) -> Optional[BackupRecord]:
|
||||
def execute_backup(self, job_id: str) -> BackupRecord | None:
|
||||
"""执行备份"""
|
||||
job = self.get_backup_job(job_id)
|
||||
if not job or not job.is_enabled:
|
||||
@@ -2354,7 +2355,7 @@ class OpsManager:
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
def get_backup_record(self, record_id: str) -> Optional[BackupRecord]:
|
||||
def get_backup_record(self, record_id: str) -> BackupRecord | None:
|
||||
"""获取备份记录"""
|
||||
with self._get_db() as conn:
|
||||
row = conn.execute("SELECT * FROM backup_records WHERE id = ?", (record_id,)).fetchone()
|
||||
@@ -2363,7 +2364,7 @@ class OpsManager:
|
||||
return self._row_to_backup_record(row)
|
||||
return None
|
||||
|
||||
def list_backup_records(self, tenant_id: str, job_id: str = None, limit: int = 100) -> List[BackupRecord]:
|
||||
def list_backup_records(self, tenant_id: str, job_id: str = None, limit: int = 100) -> list[BackupRecord]:
|
||||
"""列出租户的备份记录"""
|
||||
query = "SELECT * FROM backup_records WHERE tenant_id = ?"
|
||||
params = [tenant_id]
|
||||
@@ -2452,7 +2453,7 @@ class OpsManager:
|
||||
|
||||
return report
|
||||
|
||||
def _detect_cost_anomalies(self, utilizations: List[ResourceUtilization]) -> List[Dict]:
|
||||
def _detect_cost_anomalies(self, utilizations: list[ResourceUtilization]) -> list[dict]:
|
||||
"""检测成本异常"""
|
||||
anomalies = []
|
||||
|
||||
@@ -2483,7 +2484,7 @@ class OpsManager:
|
||||
|
||||
return anomalies
|
||||
|
||||
def _calculate_cost_trends(self, tenant_id: str, year: int, month: int) -> Dict:
|
||||
def _calculate_cost_trends(self, tenant_id: str, year: int, month: int) -> dict:
|
||||
"""计算成本趋势"""
|
||||
# 简化实现:返回模拟趋势
|
||||
return {"month_over_month": 0.05, "year_over_year": 0.15, "forecast_next_month": 1.05} # 5% 增长 # 15% 增长
|
||||
@@ -2498,7 +2499,7 @@ class OpsManager:
|
||||
avg_utilization: float,
|
||||
idle_time_percent: float,
|
||||
report_date: str,
|
||||
recommendations: List[str] = None,
|
||||
recommendations: list[str] = None,
|
||||
) -> ResourceUtilization:
|
||||
"""记录资源利用率"""
|
||||
util_id = f"ru_{uuid.uuid4().hex[:16]}"
|
||||
@@ -2541,7 +2542,7 @@ class OpsManager:
|
||||
|
||||
return util
|
||||
|
||||
def get_resource_utilizations(self, tenant_id: str, report_period: str) -> List[ResourceUtilization]:
|
||||
def get_resource_utilizations(self, tenant_id: str, report_period: str) -> list[ResourceUtilization]:
|
||||
"""获取资源利用率列表"""
|
||||
with self._get_db() as conn:
|
||||
rows = conn.execute(
|
||||
@@ -2552,7 +2553,7 @@ class OpsManager:
|
||||
).fetchall()
|
||||
return [self._row_to_resource_utilization(row) for row in rows]
|
||||
|
||||
def detect_idle_resources(self, tenant_id: str) -> List[IdleResource]:
|
||||
def detect_idle_resources(self, tenant_id: str) -> list[IdleResource]:
|
||||
"""检测闲置资源"""
|
||||
idle_resources = []
|
||||
|
||||
@@ -2615,7 +2616,7 @@ class OpsManager:
|
||||
|
||||
return idle_resources
|
||||
|
||||
def get_idle_resources(self, tenant_id: str) -> List[IdleResource]:
|
||||
def get_idle_resources(self, tenant_id: str) -> list[IdleResource]:
|
||||
"""获取闲置资源列表"""
|
||||
with self._get_db() as conn:
|
||||
rows = conn.execute(
|
||||
@@ -2623,7 +2624,7 @@ class OpsManager:
|
||||
).fetchall()
|
||||
return [self._row_to_idle_resource(row) for row in rows]
|
||||
|
||||
def generate_cost_optimization_suggestions(self, tenant_id: str) -> List[CostOptimizationSuggestion]:
|
||||
def generate_cost_optimization_suggestions(self, tenant_id: str) -> list[CostOptimizationSuggestion]:
|
||||
"""生成成本优化建议"""
|
||||
suggestions = []
|
||||
|
||||
@@ -2691,7 +2692,7 @@ class OpsManager:
|
||||
|
||||
def get_cost_optimization_suggestions(
|
||||
self, tenant_id: str, is_applied: bool = None
|
||||
) -> List[CostOptimizationSuggestion]:
|
||||
) -> list[CostOptimizationSuggestion]:
|
||||
"""获取成本优化建议"""
|
||||
query = "SELECT * FROM cost_optimization_suggestions WHERE tenant_id = ?"
|
||||
params = [tenant_id]
|
||||
@@ -2706,7 +2707,7 @@ class OpsManager:
|
||||
rows = conn.execute(query, params).fetchall()
|
||||
return [self._row_to_cost_optimization_suggestion(row) for row in rows]
|
||||
|
||||
def apply_cost_optimization_suggestion(self, suggestion_id: str) -> Optional[CostOptimizationSuggestion]:
|
||||
def apply_cost_optimization_suggestion(self, suggestion_id: str) -> CostOptimizationSuggestion | None:
|
||||
"""应用成本优化建议"""
|
||||
now = datetime.now().isoformat()
|
||||
|
||||
@@ -2723,7 +2724,7 @@ class OpsManager:
|
||||
|
||||
return self.get_cost_optimization_suggestion(suggestion_id)
|
||||
|
||||
def get_cost_optimization_suggestion(self, suggestion_id: str) -> Optional[CostOptimizationSuggestion]:
|
||||
def get_cost_optimization_suggestion(self, suggestion_id: str) -> CostOptimizationSuggestion | None:
|
||||
"""获取成本优化建议详情"""
|
||||
with self._get_db() as conn:
|
||||
row = conn.execute("SELECT * FROM cost_optimization_suggestions WHERE id = ?", (suggestion_id,)).fetchone()
|
||||
|
||||
Reference in New Issue
Block a user