Add marker_analysis/src/marker_analysis/core.py

This commit is contained in:
Mika 2026-01-18 17:11:11 +00:00
parent c54aa122ca
commit e210eaaf86

View 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