Skip to content

Commit 0663ef2

Browse files
committed
feat: Locust multi-process
1 parent 730c8b8 commit 0663ef2

27 files changed

+1700
-860
lines changed

backend/service/analysis_service.py

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ async def analyze_tasks_svc(
6767
try:
6868
ai_config = await get_ai_service_config_internal_svc(request)
6969
except HTTPException as e:
70-
error_msg = f"Failed to get AI service configuration. {str(e)}"
70+
error_msg = "Failed to get AI service configuration. %s" % str(e)
7171
logger.error(error_msg, exc_info=True)
7272
return AnalysisResponse(
7373
task_ids=task_ids,
@@ -201,8 +201,9 @@ async def analyze_tasks_svc(
201201

202202
except Exception as e:
203203
# Handle other exceptions - only log error, don't update database
204-
error_message = (
205-
f"Analysis failed for tasks {analysis_request.task_ids}: {str(e)}"
204+
error_message = "Analysis failed for tasks %s: %s" % (
205+
analysis_request.task_ids,
206+
str(e),
206207
)
207208
logger.error(error_message, exc_info=True)
208209
return AnalysisResponse(
@@ -268,7 +269,7 @@ async def get_analysis_svc(request: Request, task_id: str) -> GetAnalysisRespons
268269
)
269270

270271
except Exception as e:
271-
error_msg = f"Failed to retrieve analysis for task {task_id}: {str(e)}"
272+
error_msg = "Failed to retrieve analysis for task %s: %s" % (task_id, str(e))
272273
logger.error(error_msg, exc_info=True)
273274
return GetAnalysisResponse(
274275
data=None,
@@ -322,18 +323,18 @@ async def _call_ai_service(
322323
model_info_str = json.dumps(model_info, ensure_ascii=False, indent=2)
323324
prompt = prompt_template.format(model_info=model_info_str)
324325
except (TypeError, ValueError) as e:
325-
error_msg = f"Failed to serialize model_info: {str(e)}"
326+
error_msg = "Failed to serialize model_info: %s" % str(e)
326327
logger.error(error_msg)
327328
# Try fallback serialization
328329
try:
329330
model_info_str = str(model_info)
330331
prompt = prompt_template.format(model_info=model_info_str)
331332
except Exception as fallback_error:
332-
logger.error(f"Fallback serialization failed: {str(fallback_error)}")
333-
raise Exception(f"Failed to serialize model_info: {str(e)}")
333+
logger.error("Fallback serialization failed: %s" % str(fallback_error))
334+
raise Exception("Failed to serialize model_info: %s" % str(e))
334335
except Exception as format_error:
335-
error_msg = f"Failed to format prompt: {str(format_error)}"
336-
logger.error(f"Prompt formatting error: {error_msg}")
336+
error_msg = "Failed to format prompt: %s" % str(format_error)
337+
logger.error("Prompt formatting error: %s" % error_msg)
337338
raise Exception(error_msg)
338339
else:
339340
error_msg = "model_info is required for task analysis"
@@ -372,22 +373,22 @@ async def _call_ai_service(
372373
raise Exception(error_msg)
373374

374375
except httpx.TimeoutException as e:
375-
error_msg = f"AI service request timeout: {str(e)}"
376-
logger.error(f"AI service timeout error: {error_msg}")
376+
error_msg = "AI service request timeout: %s" % str(e)
377+
logger.error("AI service timeout error: %s" % error_msg)
377378
raise Exception(error_msg)
378379
except httpx.ConnectError as e:
379-
error_msg = f"AI service connection error: {str(e)}"
380-
logger.error(f"AI service connection error: {error_msg}")
380+
error_msg = "AI service connection error: %s" % str(e)
381+
logger.error("AI service connection error: %s" % error_msg)
381382
raise Exception(error_msg)
382383
except httpx.HTTPStatusError as e:
383-
error_msg = f"AI service HTTP error: {e.response.status_code} - {str(e)}"
384-
logger.error(f"AI service HTTP error: {error_msg}")
384+
error_msg = "AI service HTTP error: %s - %s" % (e.response.status_code, str(e))
385+
logger.error("AI service HTTP error: %s" % error_msg)
385386
raise Exception(error_msg)
386387
except httpx.RequestError as e:
387-
error_msg = f"AI service request failed: {str(e)}"
388-
logger.error(f"AI service request error: {error_msg}")
388+
error_msg = "AI service request failed: %s" % str(e)
389+
logger.error("AI service request error: %s" % error_msg)
389390
raise Exception(error_msg)
390391
except Exception as e:
391-
error_msg = f"AI service call failed: {str(e)}"
392-
logger.error(f"AI service general error: {error_msg}")
392+
error_msg = "AI service call failed: %s" % str(e)
393+
logger.error("AI service general error: %s" % error_msg)
393394
raise Exception(error_msg)

backend/service/log_service.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def get_last_n_lines(file_path: str, n: int = 100) -> str:
9898
return result
9999

100100
except Exception as e:
101-
logger.error(f"Failed to read log file: {str(e)}")
101+
logger.error("Failed to read log file: %s" % str(e))
102102
return ""
103103

104104

@@ -155,7 +155,7 @@ async def get_service_log_svc(service_name: str, offset: int, tail: int):
155155
file_size = os.path.getsize(log_file_path)
156156
return LogContentResponse(content=content, file_size=file_size)
157157
except Exception as e:
158-
logger.error(f"Failed to read log file {log_file_path}: {str(e)}")
158+
logger.error("Failed to read log file %s: %s" % (log_file_path, str(e)))
159159
return ErrorResponse.internal_server_error(ErrorMessages.LOG_FILE_READ_FAILED)
160160

161161

@@ -182,5 +182,5 @@ async def get_task_log_svc(task_id: str, offset: int, tail: int):
182182
file_size = os.path.getsize(log_file_path)
183183
return LogContentResponse(content=content, file_size=file_size)
184184
except Exception as e:
185-
logger.error(f"Failed to read log file {log_file_path}: {str(e)}")
185+
logger.error("Failed to read log file %s: %s" % (log_file_path, str(e)))
186186
return ErrorResponse.internal_server_error(ErrorMessages.LOG_FILE_READ_FAILED)

backend/service/system_service.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ async def get_system_configs_svc(request: Request) -> SystemConfigListResponse:
7777
)
7878

7979
except Exception as e:
80-
logger.warning(f"Failed to get system configs: {str(e)}")
80+
logger.warning("Failed to get system configs: %s" % str(e))
8181
return SystemConfigListResponse(
8282
data=[],
8383
status="success",
@@ -135,7 +135,7 @@ async def get_system_configs_internal_svc(request: Request) -> SystemConfigListR
135135
)
136136

137137
except Exception as e:
138-
logger.error(f"Failed to get system configs: {str(e)}")
138+
logger.error("Failed to get system configs: %s" % str(e))
139139
return SystemConfigListResponse(
140140
data=[],
141141
status="error",
@@ -207,7 +207,7 @@ async def create_system_config_svc(
207207
except HTTPException:
208208
raise
209209
except Exception as e:
210-
logger.error(f"Failed to create system config: {str(e)}")
210+
logger.error("Failed to create system config: %s" % str(e))
211211
raise HTTPException(status_code=500, detail=ErrorMessages.TASK_CREATION_FAILED)
212212

213213

@@ -269,7 +269,7 @@ async def update_system_config_svc(
269269
except HTTPException:
270270
raise
271271
except Exception as e:
272-
logger.error(f"Failed to update system config: {str(e)}")
272+
logger.error("Failed to update system config: %s" % str(e))
273273
raise HTTPException(status_code=500, detail=ErrorMessages.TASK_UPDATE_FAILED)
274274

275275

@@ -307,7 +307,7 @@ async def delete_system_config_svc(request: Request, config_key: str) -> Dict:
307307
except HTTPException:
308308
raise
309309
except Exception as e:
310-
logger.error(f"Failed to delete system config: {str(e)}")
310+
logger.error("Failed to delete system config: %s" % str(e))
311311
raise HTTPException(status_code=500, detail=ErrorMessages.TASK_DELETION_FAILED)
312312

313313

@@ -368,7 +368,7 @@ async def get_ai_service_config_svc(request: Request) -> AIServiceConfig:
368368
except HTTPException:
369369
raise
370370
except Exception as e:
371-
logger.error(f"Failed to get AI service config: {str(e)}")
371+
logger.error("Failed to get AI service config: %s" % str(e))
372372
raise HTTPException(status_code=500, detail=ErrorMessages.DATABASE_ERROR)
373373

374374

@@ -428,7 +428,7 @@ async def get_ai_service_config_internal_svc(request: Request) -> AIServiceConfi
428428
except HTTPException:
429429
raise
430430
except Exception as e:
431-
logger.error(f"Failed to get AI service config: {str(e)}")
431+
logger.error("Failed to get AI service config: %s" % str(e))
432432
raise HTTPException(status_code=500, detail=ErrorMessages.DATABASE_ERROR)
433433

434434

@@ -520,7 +520,7 @@ async def batch_upsert_system_configs_svc(
520520
)
521521

522522
except Exception as e:
523-
logger.error(f"Failed to batch upsert system configs: {str(e)}")
523+
logger.error("Failed to batch upsert system configs: %s" % str(e))
524524
return BatchSystemConfigResponse(
525525
data=[],
526526
status="error",

backend/service/task_service.py

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ async def stop_task_svc(request: Request, task_id: str):
288288
status="stopping", task_id=task_id, message="Task is being stopped."
289289
)
290290
except Exception as e:
291-
logger.error(f"Failed to stop task {task_id}: {str(e)}", exc_info=True)
291+
logger.error("Failed to stop task %s: %s" % (task_id, str(e)), exc_info=True)
292292
return TaskCreateRsp(
293293
status="error", task_id=task_id, message="Failed to stop task."
294294
)
@@ -306,7 +306,7 @@ async def create_task_svc(request: Request, body: TaskCreateReq):
306306
A `TaskCreateRsp` on success or a `JSONResponse` on failure.
307307
"""
308308
task_id = str(uuid.uuid4())
309-
logger.info(f"Creating task '{body.name}' with ID: {task_id}")
309+
logger.info("Creating task '%s' with ID: %s" % (body.name, task_id))
310310

311311
cert_file, key_file = _get_cert_config(body)
312312

@@ -363,7 +363,7 @@ async def create_task_svc(request: Request, body: TaskCreateReq):
363363
db.add(new_task)
364364
await db.flush()
365365
await db.commit()
366-
logger.info(f"Task created successfully: {new_task.id}")
366+
logger.info("Task created successfully: %s" % new_task.id)
367367

368368
return TaskCreateRsp(
369369
task_id=str(new_task.id),
@@ -372,7 +372,7 @@ async def create_task_svc(request: Request, body: TaskCreateReq):
372372
)
373373
except Exception as e:
374374
await db.rollback()
375-
error_msg = f"Failed to create task in database: {str(e)}"
375+
error_msg = "Failed to create task in database: %s" % str(e)
376376
logger.error(error_msg, exc_info=True)
377377
return ErrorResponse.internal_server_error(error_msg)
378378

@@ -431,7 +431,7 @@ async def is_task_exist(request: Request, task_id: str) -> bool:
431431
return result.scalar_one_or_none() is not None
432432
except Exception as e:
433433
logger.error(
434-
f"Failed to query for task existence (id={task_id}): {str(e)}",
434+
"Failed to query for task existence (id=%s): %s" % (task_id, str(e)),
435435
exc_info=True,
436436
)
437437
return False
@@ -516,7 +516,9 @@ async def get_task_svc(request: Request, task_id: str):
516516
# Re-raise HTTPException to let FastAPI handle it.
517517
raise
518518
except Exception as e:
519-
logger.error(f"Failed to retrieve task {task_id}: {str(e)}", exc_info=True)
519+
logger.error(
520+
"Failed to retrieve task %s: %s" % (task_id, str(e)), exc_info=True
521+
)
520522
raise HTTPException(
521523
status_code=500,
522524
detail="An internal error occurred while retrieving the task.",
@@ -563,7 +565,7 @@ async def get_task_status_svc(request: Request, task_id: str):
563565
raise
564566
except Exception as e:
565567
logger.error(
566-
f"Failed to retrieve task status {task_id}: {str(e)}", exc_info=True
568+
"Failed to retrieve task status %s: %s" % (task_id, str(e)), exc_info=True
567569
)
568570
raise HTTPException(
569571
status_code=500,
@@ -624,7 +626,7 @@ async def get_model_tasks_for_comparison_svc(request: Request):
624626

625627
except Exception as e:
626628
logger.error(
627-
f"Failed to get model tasks for comparison: {str(e)}", exc_info=True
629+
"Failed to get model tasks for comparison: %s" % str(e), exc_info=True
628630
)
629631
return ModelTasksResponse(
630632
data=[],
@@ -697,7 +699,8 @@ async def compare_performance_svc(
697699

698700
# Log metrics extraction results for debugging
699701
logger.info(
700-
f"Extracted metrics for {len(metrics_data_list)} out of {len(task_ids)} tasks"
702+
"Extracted metrics for %s out of %s tasks"
703+
% (len(metrics_data_list), len(task_ids))
701704
)
702705

703706
# Check if we have any valid metrics
@@ -736,7 +739,8 @@ async def compare_performance_svc(
736739
comparison_metrics.append(metrics)
737740
except Exception as e:
738741
logger.error(
739-
f"Failed to create ComparisonMetrics for task {metrics_data.get('task_id', 'unknown')}: {str(e)}"
742+
"Failed to create ComparisonMetrics for task %s: %s"
743+
% (metrics_data.get("task_id", "unknown"), str(e))
740744
)
741745
continue
742746

@@ -750,7 +754,7 @@ async def compare_performance_svc(
750754
return ComparisonResponse(data=comparison_metrics, status="success", error=None)
751755

752756
except Exception as e:
753-
logger.error(f"Failed to compare performance: {str(e)}", exc_info=True)
757+
logger.error("Failed to compare performance: %s" % str(e), exc_info=True)
754758
return ComparisonResponse(
755759
data=[], status="error", error="Failed to perform performance comparison"
756760
)
@@ -812,7 +816,7 @@ def _prepare_request_payload(body: TaskCreateReq) -> Dict:
812816
try:
813817
return json.loads(body.request_payload)
814818
except json.JSONDecodeError as e:
815-
raise ValueError(f"Invalid JSON in request payload: {str(e)}")
819+
raise ValueError("Invalid JSON in request payload: %s" % str(e))
816820
else:
817821
raise ValueError("Request payload is required for custom API endpoints")
818822

@@ -885,7 +889,7 @@ def _read(path: str) -> str:
885889

886890
return True, ""
887891
except Exception as e:
888-
return False, f"Certificate validation error: {str(e)}"
892+
return False, "Certificate validation error: %s" % str(e)
889893

890894

891895
def _prepare_client_cert(body: TaskCreateReq):
@@ -900,7 +904,7 @@ def _prepare_client_cert(body: TaskCreateReq):
900904
try:
901905
is_valid, err_msg = _validate_certificate_files(cert_file, key_file or None)
902906
if not is_valid:
903-
logger.error(f"Invalid client certificate configuration: {err_msg}")
907+
logger.error("Invalid client certificate configuration: %s" % err_msg)
904908
return None
905909

906910
if cert_file and key_file:
@@ -910,7 +914,7 @@ def _prepare_client_cert(body: TaskCreateReq):
910914
# Only cert file provided (combined cert+key file)
911915
client_cert = cert_file
912916
except Exception as e:
913-
logger.error(f"Error preparing certificate configuration: {e}")
917+
logger.error("Error preparing certificate configuration: %s" % str(e))
914918
return None
915919

916920
return client_cert
@@ -1029,14 +1033,14 @@ async def test_api_endpoint_svc(request: Request, body: TaskCreateReq):
10291033
logger.error("Request timeout when testing API endpoint.")
10301034
return {
10311035
"status": "error",
1032-
"error": f"Request timeout: {str(e)}",
1036+
"error": "Request timeout: %s" % str(e),
10331037
"response": None,
10341038
}
10351039
except httpx.ConnectError as e:
10361040
logger.error("Connection error when testing API endpoint.")
10371041
return {
10381042
"status": "error",
1039-
"error": f"Connection error: {str(e)}",
1043+
"error": "Connection error: %s" % str(e),
10401044
"response": None,
10411045
}
10421046
except asyncio.TimeoutError:
@@ -1047,10 +1051,10 @@ async def test_api_endpoint_svc(request: Request, body: TaskCreateReq):
10471051
"response": None,
10481052
}
10491053
except Exception as e:
1050-
logger.error(f"Error testing API endpoint: {e}", exc_info=True)
1054+
logger.error("Error testing API endpoint: %s" % str(e), exc_info=True)
10511055
return {
10521056
"status": "error",
1053-
"error": f"Unexpected error: {str(e)}",
1057+
"error": "Unexpected error: %s" % str(e),
10541058
"response": None,
10551059
}
10561060

@@ -1149,11 +1153,11 @@ async def _handle_streaming_response(response, full_url: str) -> Dict:
11491153
}
11501154
except Exception as stream_error:
11511155
logger.error(
1152-
f"Error processing stream: {stream_error}. stream data: {stream_data}"
1156+
"Error processing stream: %s. stream data: %s" % (stream_error, stream_data)
11531157
)
11541158
return {
11551159
"status": "error",
1156-
"error": f"Streaming data processing error: {str(stream_error)}",
1160+
"error": "Streaming data processing error: %s" % str(stream_error),
11571161
"response": {
11581162
"status_code": (
11591163
response.status_code if hasattr(response, "status_code") else None

backend/utils/tools.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def mask_sensitive_data(data: Union[dict, list]) -> Union[dict, list]:
4444
else:
4545
safe_dict[key] = mask_sensitive_data(value)
4646
except Exception as e:
47-
logger.warning(f"Error masking sensitive data: {str(e)}")
47+
logger.warning("Error masking sensitive data: %s" % str(e))
4848
return data
4949
return safe_dict
5050
elif isinstance(data, list):
@@ -259,7 +259,8 @@ async def extract_task_metrics(
259259

260260
except Exception as e:
261261
logger.error(
262-
f"Failed to extract metrics for task {task_id}: {str(e)}", exc_info=True
262+
"Failed to extract metrics for task %s: %s" % (task_id, str(e)),
263+
exc_info=True,
263264
)
264265
return None
265266

0 commit comments

Comments
 (0)