Add marker_analysis/src/marker_analysis/core.py
This commit is contained in:
parent
c54aa122ca
commit
e210eaaf86
1 changed files with 63 additions and 0 deletions
63
marker_analysis/src/marker_analysis/core.py
Normal file
63
marker_analysis/src/marker_analysis/core.py
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
import logging
|
||||||
|
from typing import List, Dict
|
||||||
|
from pydantic import BaseModel, Field, ValidationError
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class MarkerData(BaseModel):
|
||||||
|
"""Repräsentiert ein einzelnes Marker-Ereignis aus der eBPF-Instrumentierung."""
|
||||||
|
|
||||||
|
marker_id: str = Field(..., description="Eindeutige ID des Marker-Ereignisses.")
|
||||||
|
timestamp: float = Field(..., description="Zeitstempel des Ereignisses in Sekunden.")
|
||||||
|
status: str = Field(..., description="Status, z. B. 'write_pre', 'write_post', 'read_between_steps'.")
|
||||||
|
|
||||||
|
|
||||||
|
class MarkerValidationError(Exception):
|
||||||
|
"""Wird ausgelöst, wenn Marker-Daten ungültig sind."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def validate_markers(marker_data: List[MarkerData]) -> Dict[str, int | float]:
|
||||||
|
"""Validiert Marker-Daten auf Konsistenz (write_pre/write_post Paare)."""
|
||||||
|
|
||||||
|
assert isinstance(marker_data, list), "marker_data muss eine Liste von MarkerData sein"
|
||||||
|
|
||||||
|
try:
|
||||||
|
validated_markers = [MarkerData(**m.dict()) if isinstance(m, MarkerData) else MarkerData(**m) for m in marker_data]
|
||||||
|
except ValidationError as e:
|
||||||
|
logger.error("Validierung der MarkerData fehlgeschlagen: %s", e)
|
||||||
|
raise MarkerValidationError(f"Ungültige Marker-Daten: {e}") from e
|
||||||
|
|
||||||
|
write_pre = {}
|
||||||
|
write_post = set()
|
||||||
|
retry_free_reads = 0
|
||||||
|
|
||||||
|
for m in validated_markers:
|
||||||
|
match m.status:
|
||||||
|
case 'write_pre':
|
||||||
|
write_pre[m.marker_id] = m.timestamp
|
||||||
|
case 'write_post':
|
||||||
|
write_post.add(m.marker_id)
|
||||||
|
case 'read_between_steps':
|
||||||
|
retry_free_reads += 1
|
||||||
|
case _:
|
||||||
|
logger.debug("Unbekannter Markerstatus ignoriert: %s", m.status)
|
||||||
|
|
||||||
|
valid_pairs = sum(1 for mid in write_pre if mid in write_post)
|
||||||
|
missing_post = sum(1 for mid in write_pre if mid not in write_post)
|
||||||
|
|
||||||
|
total_events = len(validated_markers)
|
||||||
|
ratio_complete = valid_pairs / max(len(write_pre), 1)
|
||||||
|
|
||||||
|
result = {
|
||||||
|
'total_events': total_events,
|
||||||
|
'valid_write_pairs': valid_pairs,
|
||||||
|
'missing_post_markers': missing_post,
|
||||||
|
'retry_free_reads': retry_free_reads,
|
||||||
|
'pair_completion_ratio': round(ratio_complete, 3),
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Marker-Validierung abgeschlossen: %s", result)
|
||||||
|
return result
|
||||||
Loading…
Reference in a new issue