Merge pull request '1d and 1m' (#68) from feature/wc into dev
Reviewed-on: freeleaps/freeleaps-service-hub#68
This commit is contained in:
commit
bae09037a3
@ -92,6 +92,7 @@ class StarRocksMetricsService:
|
|||||||
self,
|
self,
|
||||||
product_id: str,
|
product_id: str,
|
||||||
metric_name: str,
|
metric_name: str,
|
||||||
|
step: str,
|
||||||
start_date: Union[str, date],
|
start_date: Union[str, date],
|
||||||
end_date: Union[str, date]
|
end_date: Union[str, date]
|
||||||
) -> List[Dict[str, Any]]:
|
) -> List[Dict[str, Any]]:
|
||||||
@ -162,6 +163,14 @@ class StarRocksMetricsService:
|
|||||||
else:
|
else:
|
||||||
end_dt = end_date
|
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
|
# Validate date range
|
||||||
if start_dt >= end_dt:
|
if start_dt >= end_dt:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
@ -191,7 +200,14 @@ class StarRocksMetricsService:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Parse the result and format it
|
# 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(
|
await self.module_logger.log_info(
|
||||||
f"Successfully queried metric '{metric_name}' with {len(formatted_data)} data points")
|
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}")
|
await self.module_logger.log_error(f"Failed to query metric '{metric_name}': {e}")
|
||||||
raise
|
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.
|
Format StarRocks query result into the required format and fill missing dates with 0 values.
|
||||||
|
|
||||||
@ -219,25 +235,42 @@ class StarRocksMetricsService:
|
|||||||
result_dict = {}
|
result_dict = {}
|
||||||
|
|
||||||
for row in starrocks_result:
|
for row in starrocks_result:
|
||||||
# Format the date
|
# Normalize the date according to step granularity
|
||||||
date_value = row.get("date")
|
date_value = row.get("date")
|
||||||
if date_value:
|
if not 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:
|
|
||||||
continue
|
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
|
# Get the value
|
||||||
value = row.get("value", 0)
|
value = row.get("value", 0)
|
||||||
if value is None:
|
if value is None:
|
||||||
@ -256,32 +289,54 @@ class StarRocksMetricsService:
|
|||||||
"labels": labels
|
"labels": labels
|
||||||
}
|
}
|
||||||
|
|
||||||
# Generate complete date range and fill missing dates with 0
|
# Generate complete range and fill missing points with 0
|
||||||
formatted_data = []
|
formatted_data = []
|
||||||
current_date = start_date.date()
|
if step == '1d':
|
||||||
end_date_only = end_date.date()
|
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_date < end_date_only:
|
while current_dt < end_dt_exclusive:
|
||||||
date_str = current_date.strftime('%Y-%m-%d') + ' 00:00:00'
|
date_str = current_dt.strftime('%Y-%m-%d') + ' 00:00:00'
|
||||||
|
if date_str in result_dict:
|
||||||
if date_str in result_dict:
|
formatted_data.append(result_dict[date_str])
|
||||||
# Use existing data
|
else:
|
||||||
formatted_data.append(result_dict[date_str])
|
labels = {
|
||||||
else:
|
"product_id": product_id,
|
||||||
# Fill missing date with 0 value
|
"metric_type": metric_name
|
||||||
labels = {
|
}
|
||||||
"product_id": product_id,
|
formatted_data.append({
|
||||||
"metric_type": metric_name
|
"date": date_str,
|
||||||
}
|
"value": 0,
|
||||||
|
"metric": metric_name,
|
||||||
formatted_data.append({
|
"labels": labels
|
||||||
"date": date_str,
|
})
|
||||||
"value": 0,
|
current_dt += timedelta(days=1)
|
||||||
"metric": metric_name,
|
elif step == '1m':
|
||||||
"labels": labels
|
def month_start(d: datetime) -> datetime:
|
||||||
})
|
return datetime(d.year, d.month, 1)
|
||||||
|
|
||||||
current_date += timedelta(days=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
|
return formatted_data
|
||||||
|
|
||||||
|
|||||||
@ -26,6 +26,7 @@ class MetricQueryRequest(BaseModel):
|
|||||||
"""Request model for metric query."""
|
"""Request model for metric query."""
|
||||||
product_id: str = Field(..., description="Product ID to identify which product's data to 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")
|
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")
|
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")
|
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(
|
data_points = await starrocks_service.query_metric_by_time_range(
|
||||||
product_id=request.product_id,
|
product_id=request.product_id,
|
||||||
metric_name=request.metric_name,
|
metric_name=request.metric_name,
|
||||||
|
step=request.step,
|
||||||
start_date=request.start_date,
|
start_date=request.start_date,
|
||||||
end_date=request.end_date
|
end_date=request.end_date
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user