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:
@@ -182,7 +182,7 @@ class ChromaClient(VectorDBBase):
|
||||
collection.delete(where=filter)
|
||||
except Exception as e:
|
||||
# If collection doesn't exist, that's fine - nothing to delete
|
||||
log.debug(f'Attempted to delete from non-existent collection {collection_name}. Ignoring.')
|
||||
log.debug('Attempted to delete from non-existent collection %s. Ignoring.', collection_name)
|
||||
pass
|
||||
|
||||
def reset(self):
|
||||
|
||||
@@ -242,7 +242,7 @@ class MilvusClient(VectorDBBase):
|
||||
break
|
||||
all_results.extend(batch)
|
||||
|
||||
log.debug(f'Total results from query: {len(all_results)}')
|
||||
log.debug('Total results from query: %s', len(all_results))
|
||||
return self._result_to_get_result([all_results] if all_results else [[]])
|
||||
|
||||
except Exception as e:
|
||||
|
||||
@@ -274,7 +274,7 @@ class PineconeClient(VectorDBBase):
|
||||
log.error(f'Error inserting batch: {e}')
|
||||
raise
|
||||
elapsed = time.time() - start_time
|
||||
log.debug(f'Insert of {len(points)} vectors took {elapsed:.2f} seconds')
|
||||
log.debug('Insert of %s vectors took %.2f seconds', len(points), elapsed)
|
||||
log.info(
|
||||
f"Successfully inserted {len(points)} vectors in parallel batches into '{collection_name_with_prefix}'"
|
||||
)
|
||||
@@ -303,7 +303,7 @@ class PineconeClient(VectorDBBase):
|
||||
log.error(f'Error upserting batch: {e}')
|
||||
raise
|
||||
elapsed = time.time() - start_time
|
||||
log.debug(f'Upsert of {len(points)} vectors took {elapsed:.2f} seconds')
|
||||
log.debug('Upsert of %s vectors took %.2f seconds', len(points), elapsed)
|
||||
log.info(
|
||||
f"Successfully upserted {len(points)} vectors in parallel batches into '{collection_name_with_prefix}'"
|
||||
)
|
||||
@@ -474,7 +474,9 @@ class PineconeClient(VectorDBBase):
|
||||
# Note: When deleting by ID, we can't filter by collection_name
|
||||
# This is a limitation of Pinecone - be careful with ID uniqueness
|
||||
self.index.delete(ids=batch_ids)
|
||||
log.debug(f"Deleted batch of {len(batch_ids)} vectors by ID from '{collection_name_with_prefix}'")
|
||||
log.debug(
|
||||
"Deleted batch of %s vectors by ID from '%s'", len(batch_ids), collection_name_with_prefix
|
||||
)
|
||||
log.info(f"Successfully deleted {len(ids)} vectors by ID from '{collection_name_with_prefix}'")
|
||||
|
||||
elif filter:
|
||||
|
||||
@@ -224,7 +224,7 @@ class QdrantClient(VectorDBBase):
|
||||
|
||||
mt_collection, tenant_id = self._get_collection_and_tenant_id(collection_name)
|
||||
if not self.client.collection_exists(collection_name=mt_collection):
|
||||
log.debug(f"Collection {mt_collection} doesn't exist, nothing to delete")
|
||||
log.debug("Collection %s doesn't exist, nothing to delete", mt_collection)
|
||||
return None
|
||||
|
||||
must_conditions = [_tenant_filter(tenant_id)]
|
||||
@@ -255,7 +255,7 @@ class QdrantClient(VectorDBBase):
|
||||
return None
|
||||
mt_collection, tenant_id = self._get_collection_and_tenant_id(collection_name)
|
||||
if not self.client.collection_exists(collection_name=mt_collection):
|
||||
log.debug(f"Collection {mt_collection} doesn't exist, search returns None")
|
||||
log.debug("Collection %s doesn't exist, search returns None", mt_collection)
|
||||
return None
|
||||
|
||||
tenant_filter = _tenant_filter(tenant_id)
|
||||
@@ -281,7 +281,7 @@ class QdrantClient(VectorDBBase):
|
||||
return None
|
||||
mt_collection, tenant_id = self._get_collection_and_tenant_id(collection_name)
|
||||
if not self.client.collection_exists(collection_name=mt_collection):
|
||||
log.debug(f"Collection {mt_collection} doesn't exist, query returns None")
|
||||
log.debug("Collection %s doesn't exist, query returns None", mt_collection)
|
||||
return None
|
||||
if limit is None:
|
||||
limit = NO_LIMIT
|
||||
@@ -303,7 +303,7 @@ class QdrantClient(VectorDBBase):
|
||||
return None
|
||||
mt_collection, tenant_id = self._get_collection_and_tenant_id(collection_name)
|
||||
if not self.client.collection_exists(collection_name=mt_collection):
|
||||
log.debug(f"Collection {mt_collection} doesn't exist, get returns None")
|
||||
log.debug("Collection %s doesn't exist, get returns None", mt_collection)
|
||||
return None
|
||||
tenant_filter = _tenant_filter(tenant_id)
|
||||
points = self.client.scroll(
|
||||
@@ -350,7 +350,7 @@ class QdrantClient(VectorDBBase):
|
||||
return None
|
||||
mt_collection, tenant_id = self._get_collection_and_tenant_id(collection_name)
|
||||
if not self.client.collection_exists(collection_name=mt_collection):
|
||||
log.debug(f"Collection {mt_collection} doesn't exist, nothing to delete")
|
||||
log.debug("Collection %s doesn't exist, nothing to delete", mt_collection)
|
||||
return None
|
||||
self.client.delete(
|
||||
collection_name=mt_collection,
|
||||
|
||||
@@ -54,7 +54,7 @@ class S3VectorClient(VectorDBBase):
|
||||
Create a new index in the S3 vector bucket for the given collection if it does not exist.
|
||||
"""
|
||||
if self.has_collection(index_name):
|
||||
log.debug(f"Index '{index_name}' already exists, skipping creation")
|
||||
log.debug("Index '%s' already exists, skipping creation", index_name)
|
||||
return
|
||||
|
||||
try:
|
||||
@@ -310,7 +310,7 @@ class S3VectorClient(VectorDBBase):
|
||||
|
||||
# Process each query vector
|
||||
for i, query_vector in enumerate(vectors):
|
||||
log.debug(f'Processing query vector {i + 1}/{len(vectors)}')
|
||||
log.debug('Processing query vector %s/%s', i + 1, len(vectors))
|
||||
|
||||
# Prepare the query vector in S3 Vector format
|
||||
query_vector_dict = {'float32': [float(x) for x in query_vector]}
|
||||
@@ -521,7 +521,7 @@ class S3VectorClient(VectorDBBase):
|
||||
)
|
||||
|
||||
# Log the actual content for debugging
|
||||
log.debug(f'Document text preview (first 200 chars): {str(document_text)[:200]}')
|
||||
log.debug('Document text preview (first 200 chars): %s', str(document_text)[:200])
|
||||
else:
|
||||
document_text = vector_id
|
||||
|
||||
|
||||
@@ -390,7 +390,7 @@ class ValkeyClient(VectorDBBase):
|
||||
)
|
||||
except g['RequestError'] as e:
|
||||
if 'already exists' in str(e).lower():
|
||||
log.debug(f'Index {index_name} already exists, skipping creation.')
|
||||
log.debug('Index %s already exists, skipping creation.', index_name)
|
||||
else:
|
||||
raise
|
||||
|
||||
@@ -458,7 +458,7 @@ class ValkeyClient(VectorDBBase):
|
||||
self._g['glide_ft'].dropindex(self.client, index_name)
|
||||
log.info(f'Dropped index {index_name}')
|
||||
except self._g['RequestError'] as e:
|
||||
log.debug(f'Could not drop index {index_name}: {e}')
|
||||
log.debug('Could not drop index %s: %s', index_name, e)
|
||||
|
||||
self._delete_keys_by_prefix(self._key_prefix(collection_name))
|
||||
|
||||
@@ -492,7 +492,7 @@ class ValkeyClient(VectorDBBase):
|
||||
}
|
||||
self.batch_client.hset(self._item_key(collection_name, item['id']), mapping)
|
||||
|
||||
log.debug(f'Inserted {len(items)} items into collection {collection_name}')
|
||||
log.debug('Inserted %s items into collection %s', len(items), collection_name)
|
||||
|
||||
def upsert(self, collection_name: str, items: list[VectorItem]):
|
||||
self.insert(collection_name, items)
|
||||
|
||||
Reference in New Issue
Block a user