49 lines
1.5 KiB
Python
49 lines
1.5 KiB
Python
from dataclasses import dataclass, field
|
|
from datetime import datetime
|
|
import logging
|
|
from typing import List
|
|
|
|
logger = logging.getLogger("metrics")
|
|
|
|
@dataclass
|
|
class MessageMetrics:
|
|
topic: str
|
|
processing_time_ms: float
|
|
error: bool = False
|
|
error_msg: str = ""
|
|
timestamp: datetime = field(default_factory=datetime.now)
|
|
|
|
message_metrics: List[MessageMetrics] = []
|
|
|
|
def record_metric(topic: str, processing_time_ms: float, error: bool = False, error_msg: str = ""):
|
|
metric = MessageMetrics(
|
|
topic=topic,
|
|
processing_time_ms=processing_time_ms,
|
|
error=error,
|
|
error_msg=error_msg
|
|
)
|
|
message_metrics.append(metric)
|
|
if len(message_metrics) > 1000:
|
|
message_metrics.pop(0)
|
|
|
|
if error:
|
|
logger.error(f"[METRIC ERROR] {topic}: {error_msg} ({processing_time_ms:.1f}ms)")
|
|
elif processing_time_ms > 100:
|
|
logger.warning(f"[METRIC SLOW] {topic}: {processing_time_ms:.1f}ms (>100ms)")
|
|
|
|
def get_metrics_summary() -> dict:
|
|
if not message_metrics:
|
|
return {"message": "No metrics recorded yet"}
|
|
|
|
total_count = len(message_metrics)
|
|
error_count = sum(1 for m in message_metrics if m.error)
|
|
avg_time = sum(m.processing_time_ms for m in message_metrics) / total_count
|
|
|
|
return {
|
|
"total_messages": total_count,
|
|
"error_count": error_count,
|
|
"error_rate": error_count / total_count if total_count > 0 else 0.0,
|
|
"avg_processing_time_ms": round(avg_time, 2),
|
|
"last_update": message_metrics[-1].timestamp.isoformat()
|
|
}
|