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:
Classic298 authored and GitHub committed 2026-07-31 19:09:01 -05:00
1 parent b67804f2b6
commit 52cfb02c72
40 files changed
+198 -190

No files matched your search

+4 -4
View File
@@ -448,7 +448,7 @@ def _process_chat_for_export(chat) -> ChatStatsExport | None:
history_models[model] = 0
history_models[model] += 1
except Exception as e:
log.debug(f'Error processing message {key}: {e}')
log.debug('Error processing message %s: %s', key, e)
continue
# Calculate Averages
@@ -614,7 +614,7 @@ async def export_chat_stats(
return ChatStatsExportList(items=chat_stats_export_list, total=total, page=page)
except Exception as e:
log.debug(f'Error exporting chat stats: {e}')
log.debug('Error exporting chat stats: %s', e)
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT())
@@ -671,7 +671,7 @@ async def export_single_chat_stats(
except HTTPException:
raise
except Exception as e:
log.debug(f'Error exporting single chat stats: {e}')
log.debug('Error exporting single chat stats: %s', e)
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT())
@@ -877,7 +877,7 @@ async def search_user_chats(
tag_id = words[0].replace('tag:', '')
if len(chat_list) == 0:
if await Tags.get_tag_by_name_and_user_id(tag_id, user.id, db=db):
log.debug(f'deleting tag: {tag_id}')
log.debug('deleting tag: %s', tag_id)
await Tags.delete_tag_by_name_and_user_id(tag_id, user.id, db=db)
return await add_active_state_to_chat_list(request, chat_list)