feat(p3.1-t2): Tier-2 三服務感知強化 — Sentry 簽章 + DiagnosisAggregator + Solver actions test
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
Wave 8 P3.1-T2 三項感知強化(多 engineer 補完):
Sentry Webhook 簽章驗證:
- sentry_webhook.py: 接入 SentryWebhookService.verify_sentry_signature()
- 拒絕無效 sentry-hook-signature → 401 → 防偽造攻擊
DiagnosisAggregator Pod 深診斷整合:
- pre_decision_investigator.py: 新增 _collect_diagnosis_aggregator()
- ENABLE_DIAGNOSIS_AGGREGATOR feature flag 守衛(default=False)
- evidence_snapshot.py: extra_diagnosis 欄位 + build_summary 顯示
- timeout=3.0s + try/except 隔離(fail-soft)
- Conservative 策略:待重疊分析確認 vs PreDecisionInvestigator 不重複
config.py:
- 新增 ENABLE_DIAGNOSIS_AGGREGATOR Field(default=False,K8s ConfigMap 動態啟用)
Solver B1 補測(commit 7c726ebc 對應):
- test_solver_recommended_actions.py — 20 tests + 3 skipped
- 驗證結構化 recommended_actions(北極星 §1.1 修復多樣性 ≥ 40%)
- LLM 失敗 graceful degraded(candidates=[], degraded=True)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Multiple Engineers (Wave 8 P3.1-T2) <noreply@anthropic.com>
This commit is contained in:
@@ -92,6 +92,8 @@ class EvidenceSnapshot:
|
||||
# Phase 4 ADR-084: 動態異常感官(DynamicBaseline + LogAnomaly + TrendPredictor)
|
||||
# 2026-04-15 ogt + Claude Sonnet 4.6(亞太): Phase 4 8D 升級
|
||||
anomaly_context: dict[str, Any] | None = None # Phase 4 動態異常上下文
|
||||
# 2026-04-27 P3.1-T2 by Claude — DiagnosisAggregator Pod 深診斷補充(in-memory only,不持久化)
|
||||
extra_diagnosis: str | None = None
|
||||
|
||||
# 感官品質
|
||||
mcp_health: dict[str, bool] = field(default_factory=dict)
|
||||
@@ -162,6 +164,9 @@ class EvidenceSnapshot:
|
||||
parts.append(f"[依賴拓撲] {self.dependency_topology}")
|
||||
if self.anomaly_context:
|
||||
parts.append(f"[動態異常偵測]\n{self.anomaly_context}")
|
||||
# 2026-04-27 P3.1-T2 by Claude — DiagnosisAggregator Pod 深診斷(ENABLE_DIAGNOSIS_AGGREGATOR=true 時填入)
|
||||
if self.extra_diagnosis:
|
||||
parts.append(f"[Pod深診斷]\n{self.extra_diagnosis}")
|
||||
|
||||
# 感官品質報告
|
||||
failed_tools = [t for t, ok in self.mcp_health.items() if not ok]
|
||||
|
||||
@@ -149,6 +149,21 @@ class PreDecisionInvestigator:
|
||||
except Exception:
|
||||
logger.exception("phase4_anomaly_collect_error", incident_id=incident_id)
|
||||
|
||||
# 4.6 P3.1-T2 by Claude 2026-04-27 — DiagnosisAggregator Pod 深診斷(守門:ENABLE_DIAGNOSIS_AGGREGATOR)
|
||||
# Conservative 策略:預設關閉,避免與 MCP sensor 重複收集 K8s+SignOz 資料。
|
||||
# 待重疊分析完成確認互補性後,由統帥設定 ENABLE_DIAGNOSIS_AGGREGATOR=true 啟用。
|
||||
try:
|
||||
from src.core.config import settings as _settings
|
||||
if _settings.ENABLE_DIAGNOSIS_AGGREGATOR:
|
||||
await asyncio.wait_for(
|
||||
self._collect_diagnosis_aggregator(snapshot, incident),
|
||||
timeout=3.0,
|
||||
)
|
||||
except asyncio.TimeoutError:
|
||||
logger.warning("diagnosis_aggregator_collect_timeout", incident_id=incident_id)
|
||||
except Exception:
|
||||
logger.warning("diagnosis_aggregator_collect_failed", incident_id=incident_id)
|
||||
|
||||
# 5. 組裝 summary
|
||||
snapshot.evidence_summary = snapshot.build_summary()
|
||||
|
||||
@@ -171,6 +186,48 @@ class PreDecisionInvestigator:
|
||||
)
|
||||
return snapshot
|
||||
|
||||
async def _collect_diagnosis_aggregator(
|
||||
self,
|
||||
snapshot: EvidenceSnapshot,
|
||||
incident: "Incident",
|
||||
) -> None:
|
||||
"""
|
||||
P3.1-T2 by Claude 2026-04-27 — DiagnosisAggregator Pod 深診斷整合
|
||||
|
||||
僅在 ENABLE_DIAGNOSIS_AGGREGATOR=true 時呼叫(外層已守門)。
|
||||
從 incident labels 取 pod_name + namespace,呼叫 DiagnosisAggregator
|
||||
收集 K8s events + SignOz metrics,結果存入 snapshot.extra_diagnosis。
|
||||
|
||||
Conservative 策略說明:
|
||||
DiagnosisAggregator 與 MCP sensors(D1_K8S_STATE / D3_METRICS)存在資料重疊,
|
||||
本方法透過 feature flag 隔離,不影響主路徑。資料僅作補充,不覆蓋 MCP 結果。
|
||||
"""
|
||||
from src.services.diagnosis_aggregator import get_diagnosis_aggregator
|
||||
|
||||
labels = _get_labels(incident)
|
||||
pod_name = labels.get("pod", labels.get("name", ""))
|
||||
namespace = labels.get("namespace", "awoooi-prod")
|
||||
|
||||
if not pod_name:
|
||||
logger.debug("diagnosis_aggregator_skip_no_pod", incident_id=snapshot.incident_id)
|
||||
return
|
||||
|
||||
aggregator = get_diagnosis_aggregator()
|
||||
ctx = await aggregator.collect_pod_diagnosis(
|
||||
pod_name=pod_name,
|
||||
namespace=namespace,
|
||||
)
|
||||
prompt_ctx = ctx.get_llm_prompt_context()
|
||||
if prompt_ctx:
|
||||
snapshot.extra_diagnosis = prompt_ctx[:4000] # 限 4K chars,不壓縮主 evidence_summary
|
||||
logger.debug(
|
||||
"diagnosis_aggregator_collected",
|
||||
incident_id=snapshot.incident_id,
|
||||
pod=pod_name,
|
||||
signals=len(ctx.signals),
|
||||
highest_severity=ctx.highest_severity.value,
|
||||
)
|
||||
|
||||
async def _collect_phase4_anomalies(self, snapshot: EvidenceSnapshot) -> None:
|
||||
"""
|
||||
Phase 4 8D 感官增強:從 ProactiveInspector 快取 + LogAnomalyDetector
|
||||
|
||||
Reference in New Issue
Block a user