98 Zeilen
3.5 KiB
Python
98 Zeilen
3.5 KiB
Python
"""
|
|
Error Summary Value Object - Zusammenfassung von Fehlerinformationen
|
|
"""
|
|
|
|
from dataclasses import dataclass
|
|
from datetime import datetime
|
|
from typing import List, Dict, Any
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ErrorSummary:
|
|
"""
|
|
Zusammenfassung von Fehlerinformationen für Berichte und Analysen.
|
|
Frozen dataclass macht es unveränderlich (Value Object).
|
|
"""
|
|
|
|
error_type: str
|
|
error_count: int
|
|
first_occurrence: datetime
|
|
last_occurrence: datetime
|
|
affected_sessions: List[str]
|
|
affected_accounts: List[str]
|
|
|
|
# Statistiken
|
|
avg_recovery_time: float # in Sekunden
|
|
recovery_success_rate: float # 0.0 - 1.0
|
|
|
|
# Häufigste Kontexte
|
|
most_common_urls: List[str]
|
|
most_common_actions: List[str]
|
|
most_common_steps: List[str]
|
|
|
|
# Impact
|
|
total_user_impact: int
|
|
total_system_impact: int
|
|
data_loss_incidents: int
|
|
|
|
def __post_init__(self):
|
|
"""Validierung der Summary-Daten"""
|
|
if self.error_count < 0:
|
|
raise ValueError("Error count kann nicht negativ sein")
|
|
if not 0.0 <= self.recovery_success_rate <= 1.0:
|
|
raise ValueError("Recovery success rate muss zwischen 0.0 und 1.0 liegen")
|
|
if self.first_occurrence > self.last_occurrence:
|
|
raise ValueError("First occurrence kann nicht nach last occurrence liegen")
|
|
|
|
@property
|
|
def duration(self) -> float:
|
|
"""Zeitspanne zwischen erstem und letztem Auftreten in Stunden"""
|
|
delta = self.last_occurrence - self.first_occurrence
|
|
return delta.total_seconds() / 3600
|
|
|
|
@property
|
|
def frequency(self) -> float:
|
|
"""Fehler pro Stunde"""
|
|
if self.duration > 0:
|
|
return self.error_count / self.duration
|
|
return self.error_count
|
|
|
|
@property
|
|
def severity_score(self) -> float:
|
|
"""
|
|
Berechnet einen Schweregrad-Score basierend auf:
|
|
- Häufigkeit
|
|
- Impact
|
|
- Wiederherstellungsrate
|
|
"""
|
|
frequency_factor = min(self.frequency / 10, 1.0) # Normalisiert auf 0-1
|
|
impact_factor = min((self.total_user_impact + self.total_system_impact) / 100, 1.0)
|
|
recovery_factor = 1.0 - self.recovery_success_rate
|
|
data_loss_factor = min(self.data_loss_incidents / 10, 1.0)
|
|
|
|
return (frequency_factor * 0.3 +
|
|
impact_factor * 0.3 +
|
|
recovery_factor * 0.2 +
|
|
data_loss_factor * 0.2)
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""Konvertiert zu Dictionary für Serialisierung"""
|
|
return {
|
|
'error_type': self.error_type,
|
|
'error_count': self.error_count,
|
|
'first_occurrence': self.first_occurrence.isoformat(),
|
|
'last_occurrence': self.last_occurrence.isoformat(),
|
|
'duration_hours': self.duration,
|
|
'frequency_per_hour': self.frequency,
|
|
'affected_sessions': self.affected_sessions,
|
|
'affected_accounts': self.affected_accounts,
|
|
'avg_recovery_time': self.avg_recovery_time,
|
|
'recovery_success_rate': self.recovery_success_rate,
|
|
'most_common_urls': self.most_common_urls[:5],
|
|
'most_common_actions': self.most_common_actions[:5],
|
|
'most_common_steps': self.most_common_steps[:5],
|
|
'total_user_impact': self.total_user_impact,
|
|
'total_system_impact': self.total_system_impact,
|
|
'data_loss_incidents': self.data_loss_incidents,
|
|
'severity_score': self.severity_score
|
|
} |