perf: build debug log messages lazily so disabled debug logs cost nothing (#27834)
GLOBAL_LOG_LEVEL defaults to INFO, so every log.debug(...) in the backend is discarded, but the message is built first: 187 call sites interpolate their payload into an f-string before the logging call runs, so the work happens on every request and the result is thrown away. The worst one sits in process_chat_payload and stringifies the whole request body, full conversation history included, once per chat completion.
That one line with DEBUG disabled, CPython 3.12:
| conversation | payload | before | after |
| ------------ | ------- | -------- | ------- |
| 4 messages | 1.2 kB | 3.4 us | 0.07 us |
| 20 messages | 17 kB | 24.8 us | 0.07 us |
| 60 messages | 123 kB | 216.6 us | 0.07 us |
The lazy form log.debug('form_data: %s', form_data) hands the payload to record.getMessage(), which the InterceptHandler only reaches once a record has passed the level check. With DEBUG enabled the emitted lines are byte-identical, f'{x=}' sites included: those map to %r. MistralLoader._debug_log callers get the same treatment, since that wrapper already forwards *args.
This commit is contained in:
1 parent
b67804f2b6
commit
52cfb02c72
40 files changed
+198
-190
No files matched your search
@@ -878,7 +878,7 @@ async def get_models(request: Request, refresh: bool = False, user=Depends(get_v
|
||||
tags = list(set(model_tags + tags))
|
||||
model['tags'] = [{'name': tag} for tag in tags]
|
||||
except Exception as e:
|
||||
log.debug(f'Error processing model tags: {e}')
|
||||
log.debug('Error processing model tags: %s', e)
|
||||
model['tags'] = []
|
||||
|
||||
model_order_list = await Config.get('ui.model_order_list')
|
||||
@@ -1377,7 +1377,7 @@ async def chat_completion(
|
||||
user.id,
|
||||
)
|
||||
except Exception as e:
|
||||
log.debug(f'Error inserting chat files: {e}')
|
||||
log.debug('Error inserting chat files: %s', e)
|
||||
pass
|
||||
|
||||
if initial_title_generation is not None and all_assistant_ids:
|
||||
@@ -1399,7 +1399,7 @@ async def chat_completion(
|
||||
try:
|
||||
await background_tasks_handler(title_ctx)
|
||||
except Exception as e:
|
||||
log.debug(f'Error generating initial chat title: {e}')
|
||||
log.debug('Error generating initial chat title: %s', e)
|
||||
|
||||
asyncio.create_task(run_initial_title_generation())
|
||||
else:
|
||||
@@ -1487,7 +1487,7 @@ async def chat_completion(
|
||||
user.id,
|
||||
)
|
||||
except Exception as e:
|
||||
log.debug(f'Error inserting chat files: {e}')
|
||||
log.debug('Error inserting chat files: %s', e)
|
||||
pass
|
||||
|
||||
# Save ALL assistant placeholders
|
||||
@@ -1653,9 +1653,9 @@ async def chat_completion(
|
||||
try:
|
||||
await client.disconnect()
|
||||
except BaseException as e:
|
||||
log.debug(f'Error disconnecting MCP client: {e}')
|
||||
log.debug('Error disconnecting MCP client: %s', e)
|
||||
except BaseException as e:
|
||||
log.debug(f'Error cleaning up MCP clients: {e}')
|
||||
log.debug('Error cleaning up MCP clients: %s', e)
|
||||
|
||||
# Deregister this task, then emit chat:active=false if no others remain
|
||||
try:
|
||||
@@ -2051,7 +2051,7 @@ async def list_tasks_by_chat_id_endpoint(request: Request, chat_id: str, user=De
|
||||
|
||||
task_ids = await list_task_ids_by_item_id(request.app.state.redis, chat_id)
|
||||
|
||||
log.debug(f'Task IDs for chat {chat_id}: {task_ids}')
|
||||
log.debug('Task IDs for chat %s: %s', chat_id, task_ids)
|
||||
return {'task_ids': task_ids}
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user