freeleaps-service-hub/apps/metrics/webapi/routes/prometheus_metrics/metrics_query.py

84 lines
3.0 KiB
Python

from fastapi import APIRouter
from typing import Optional, List, Dict, Any
from pydantic import BaseModel, Field
from common.log.module_logger import ModuleLogger
from backend.services.prometheus_metrics_service import PrometheusMetricsService
class MetricDataPoint(BaseModel):
"""Single data point in a time series."""
date: str = Field(..., description="Timestamp in ISO format")
value: Optional[float] = Field(None, description="Metric value")
labels: Optional[Dict[str, str]] = Field(None, description="Metric labels")
class MetricTimeSeriesResponse(BaseModel):
"""Response model for metric time series data."""
metric_name: str = Field(..., description="Name of the queried metric")
data_points: List[MetricDataPoint] = Field(..., description="List of data points")
total_points: int = Field(..., description="Total number of data points")
time_range: Dict[str, str] = Field(..., description="Start and end time of the query")
step: str = Field("1h", description="Query resolution step")
class MetricQueryRequest(BaseModel):
"""Request model for metric query."""
product_id: str = Field(..., description="Product ID to identify which product's metrics to query")
metric_name: str = Field(..., description="Name of the metric to query")
start_time: str = Field(..., description="Start time in ISO format or RFC3339")
end_time: str = Field(..., description="End time in ISO format or RFC3339")
step: str = Field("1h", description="Query resolution step (e.g., 1m, 5m, 1h)")
router = APIRouter()
# Initialize service and logger
prometheus_service = PrometheusMetricsService()
module_logger = ModuleLogger(__file__)
@router.post("/prometheus/metrics_query", response_model=MetricTimeSeriesResponse)
async def metrics_query(
request: MetricQueryRequest
):
"""
Query metrics time series data.
Returns XY curve data (time series) for the specified metric within the given time range.
"""
await module_logger.log_info(
f"Querying metric '{request.metric_name}' from product '{request.product_id}' from {request.start_time} to {request.end_time}")
# Query the metric data
data_points = await prometheus_service.query_metric_by_time_range(
product_id=request.product_id,
metric_name=request.metric_name,
start_time=request.start_time,
end_time=request.end_time,
step=request.step
)
# Format response
response = MetricTimeSeriesResponse(
metric_name=request.metric_name,
data_points=[
MetricDataPoint(
date=point["date"],
value=point["value"],
labels=point["labels"]
)
for point in data_points
],
total_points=len(data_points),
time_range={
"start": request.start_time,
"end": request.end_time
},
step=request.step
)
await module_logger.log_info(
f"Successfully queried metric '{request.metric_name}' with {len(data_points)} data points")
return response