1d and 1m
This commit is contained in:
parent
6fc505ebb2
commit
5b521c4ec4
@ -92,6 +92,7 @@ class StarRocksMetricsService:
|
||||
self,
|
||||
product_id: str,
|
||||
metric_name: str,
|
||||
step: str,
|
||||
start_date: Union[str, date],
|
||||
end_date: Union[str, date]
|
||||
) -> List[Dict[str, Any]]:
|
||||
@ -162,6 +163,14 @@ class StarRocksMetricsService:
|
||||
else:
|
||||
end_dt = end_date
|
||||
|
||||
# Normalize and validate step (default '1d')
|
||||
step = step or '1d'
|
||||
if step not in {"1d", "1m"}:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Invalid step. Supported values are '1d' and '1m'"
|
||||
)
|
||||
|
||||
# Validate date range
|
||||
if start_dt >= end_dt:
|
||||
raise HTTPException(
|
||||
@ -191,7 +200,14 @@ class StarRocksMetricsService:
|
||||
)
|
||||
|
||||
# Parse the result and format it
|
||||
formatted_data = self._format_query_result(result, metric_name, product_id, start_dt, end_dt)
|
||||
formatted_data = self._format_query_result(
|
||||
starrocks_result=result,
|
||||
metric_name=metric_name,
|
||||
product_id=product_id,
|
||||
step=step,
|
||||
start_date=start_dt,
|
||||
end_date=end_dt
|
||||
)
|
||||
|
||||
await self.module_logger.log_info(
|
||||
f"Successfully queried metric '{metric_name}' with {len(formatted_data)} data points")
|
||||
@ -201,7 +217,7 @@ class StarRocksMetricsService:
|
||||
await self.module_logger.log_error(f"Failed to query metric '{metric_name}': {e}")
|
||||
raise
|
||||
|
||||
def _format_query_result(self, starrocks_result: List[Dict[str, Any]], metric_name: str, product_id: str, start_date: datetime, end_date: datetime) -> List[Dict[str, Any]]:
|
||||
def _format_query_result(self, starrocks_result: List[Dict[str, Any]], metric_name: str, product_id: str, step: str, start_date: datetime, end_date: datetime) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
Format StarRocks query result into the required format and fill missing dates with 0 values.
|
||||
|
||||
@ -219,25 +235,42 @@ class StarRocksMetricsService:
|
||||
result_dict = {}
|
||||
|
||||
for row in starrocks_result:
|
||||
# Format the date
|
||||
# Normalize the date according to step granularity
|
||||
date_value = row.get("date")
|
||||
if date_value:
|
||||
if isinstance(date_value, str):
|
||||
date_str = date_value
|
||||
else:
|
||||
# If it's a datetime object, format it as a string
|
||||
if hasattr(date_value, 'strftime'):
|
||||
# Convert to date first, then format consistently
|
||||
if hasattr(date_value, 'date'):
|
||||
date_obj = date_value.date() if hasattr(date_value, 'date') else date_value
|
||||
else:
|
||||
date_obj = date_value
|
||||
date_str = date_obj.strftime('%Y-%m-%d') + ' 00:00:00'
|
||||
else:
|
||||
date_str = str(date_value)
|
||||
else:
|
||||
if not date_value:
|
||||
continue
|
||||
|
||||
def month_start(d: datetime) -> datetime:
|
||||
return datetime(d.year, d.month, 1)
|
||||
|
||||
# Parse and normalize
|
||||
if isinstance(date_value, str):
|
||||
parsed_dt = None
|
||||
for fmt in ('%Y-%m-%d %H:%M:%S', '%Y-%m-%d'):
|
||||
try:
|
||||
parsed_dt = datetime.strptime(date_value, fmt)
|
||||
break
|
||||
except ValueError:
|
||||
continue
|
||||
if parsed_dt is None:
|
||||
date_str = str(date_value)
|
||||
else:
|
||||
if step == '1m':
|
||||
date_str = month_start(parsed_dt).strftime('%Y-%m-01 00:00:00')
|
||||
else:
|
||||
date_str = parsed_dt.strftime('%Y-%m-%d') + ' 00:00:00'
|
||||
else:
|
||||
if hasattr(date_value, 'strftime'):
|
||||
dt_obj = date_value
|
||||
if step == '1m':
|
||||
date_str = month_start(dt_obj).strftime('%Y-%m-01 00:00:00')
|
||||
else:
|
||||
if hasattr(dt_obj, 'date'):
|
||||
dt_obj = dt_obj.date()
|
||||
date_str = dt_obj.strftime('%Y-%m-%d') + ' 00:00:00'
|
||||
else:
|
||||
date_str = str(date_value)
|
||||
|
||||
# Get the value
|
||||
value = row.get("value", 0)
|
||||
if value is None:
|
||||
@ -256,32 +289,54 @@ class StarRocksMetricsService:
|
||||
"labels": labels
|
||||
}
|
||||
|
||||
# Generate complete date range and fill missing dates with 0
|
||||
# Generate complete range and fill missing points with 0
|
||||
formatted_data = []
|
||||
current_date = start_date.date()
|
||||
end_date_only = end_date.date()
|
||||
|
||||
while current_date < end_date_only:
|
||||
date_str = current_date.strftime('%Y-%m-%d') + ' 00:00:00'
|
||||
|
||||
if date_str in result_dict:
|
||||
# Use existing data
|
||||
formatted_data.append(result_dict[date_str])
|
||||
else:
|
||||
# Fill missing date with 0 value
|
||||
labels = {
|
||||
"product_id": product_id,
|
||||
"metric_type": metric_name
|
||||
}
|
||||
|
||||
formatted_data.append({
|
||||
"date": date_str,
|
||||
"value": 0,
|
||||
"metric": metric_name,
|
||||
"labels": labels
|
||||
})
|
||||
|
||||
current_date += timedelta(days=1)
|
||||
if step == '1d':
|
||||
current_dt = datetime(start_date.year, start_date.month, start_date.day)
|
||||
end_dt_exclusive = datetime(end_date.year, end_date.month, end_date.day)
|
||||
while current_dt < end_dt_exclusive:
|
||||
date_str = current_dt.strftime('%Y-%m-%d') + ' 00:00:00'
|
||||
if date_str in result_dict:
|
||||
formatted_data.append(result_dict[date_str])
|
||||
else:
|
||||
labels = {
|
||||
"product_id": product_id,
|
||||
"metric_type": metric_name
|
||||
}
|
||||
formatted_data.append({
|
||||
"date": date_str,
|
||||
"value": 0,
|
||||
"metric": metric_name,
|
||||
"labels": labels
|
||||
})
|
||||
current_dt += timedelta(days=1)
|
||||
elif step == '1m':
|
||||
def month_start(d: datetime) -> datetime:
|
||||
return datetime(d.year, d.month, 1)
|
||||
|
||||
def add_one_month(d: datetime) -> datetime:
|
||||
year = d.year + (1 if d.month == 12 else 0)
|
||||
month = 1 if d.month == 12 else d.month + 1
|
||||
return datetime(year, month, 1)
|
||||
|
||||
current_dt = month_start(start_date)
|
||||
end_month_exclusive = month_start(end_date)
|
||||
while current_dt < end_month_exclusive:
|
||||
date_str = current_dt.strftime('%Y-%m-01 00:00:00')
|
||||
if date_str in result_dict:
|
||||
formatted_data.append(result_dict[date_str])
|
||||
else:
|
||||
labels = {
|
||||
"product_id": product_id,
|
||||
"metric_type": metric_name
|
||||
}
|
||||
formatted_data.append({
|
||||
"date": date_str,
|
||||
"value": 0,
|
||||
"metric": metric_name,
|
||||
"labels": labels
|
||||
})
|
||||
current_dt = add_one_month(current_dt)
|
||||
|
||||
return formatted_data
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@ class MetricQueryRequest(BaseModel):
|
||||
"""Request model for metric query."""
|
||||
product_id: str = Field(..., description="Product ID to identify which product's data to query")
|
||||
metric_name: str = Field(..., description="Name of the metric to query")
|
||||
step: str = Field(..., description="Aggregation step, e.g., 1d or 1m")
|
||||
start_date: str = Field(..., description="Start date in YYYY-MM-DD HH:MM:SS format")
|
||||
end_date: str = Field(..., description="End date in YYYY-MM-DD HH:MM:SS format")
|
||||
|
||||
@ -53,6 +54,7 @@ async def metrics_query(
|
||||
data_points = await starrocks_service.query_metric_by_time_range(
|
||||
product_id=request.product_id,
|
||||
metric_name=request.metric_name,
|
||||
step=request.step,
|
||||
start_date=request.start_date,
|
||||
end_date=request.end_date
|
||||
)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user