Initial commit
Dieser Commit ist enthalten in:
98
domain/value_objects/error_summary.py
Normale Datei
98
domain/value_objects/error_summary.py
Normale Datei
@ -0,0 +1,98 @@
|
||||
"""
|
||||
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
|
||||
}
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren