@@ -281,51 +281,55 @@ async def setup_async_loggers_lifespan(
281281 # Create queue handler for loggers
282282 queue_handler = logging .handlers .QueueHandler (log_queue )
283283
284- # Use root-only approach for better performance and simplicity
284+ # Comprehensive approach: ensure ALL logs go through async queue
285285 root_logger = logging .getLogger ()
286- original_root_handlers = root_logger .handlers .copy ()
287-
288- # Check for edge cases and warn if found
289286 all_loggers = _get_all_loggers ()
290- edge_case_loggers = []
291287
288+ # Store original state for restoration
289+ original_logger_state = [
290+ {
291+ "logger" : logger ,
292+ "handlers" : logger .handlers .copy (),
293+ "propagate" : logger .propagate ,
294+ }
295+ for logger in all_loggers
296+ ]
297+
298+ # Remove all handlers from all loggers and ensure propagation
299+ loggers_modified = []
292300 for logger in all_loggers :
293301 if logger is root_logger :
294302 continue
295303
296- # Check for loggers that might bypass root logging
297- has_handlers = bool (logger .handlers )
298- propagate_disabled = not logger .propagate
304+ # Track what we're modifying for logging purposes
305+ had_handlers = bool (logger .handlers )
306+ had_propagate_disabled = not logger .propagate
299307
300- # Filter out harmless cases: NullHandler with propagate=True is fine
301- has_meaningful_handlers = (
302- any (not isinstance (h , logging .NullHandler ) for h in logger .handlers )
303- if logger .handlers
304- else False
305- )
306-
307- if has_meaningful_handlers or propagate_disabled :
308- edge_case_loggers .append (
308+ if had_handlers or had_propagate_disabled :
309+ loggers_modified .append (
309310 {
310311 "name" : logger .name ,
311- "has_handlers " : has_handlers ,
312- "propagate " : logger . propagate ,
312+ "had_handlers " : had_handlers ,
313+ "had_propagate_disabled " : had_propagate_disabled ,
313314 "handlers" : [type (h ).__name__ for h in logger .handlers ],
314315 }
315316 )
316317
317- if edge_case_loggers :
318- _logger .warning (
319- "Found %d loggers that may bypass async logging: %s. "
320- "Consider reviewing logger configuration." ,
321- len (edge_case_loggers ),
318+ # Clear handlers and ensure propagation
319+ logger .handlers .clear ()
320+ logger .propagate = True
321+
322+ if loggers_modified :
323+ _logger .info (
324+ "Modified %d loggers for async logging: %s" ,
325+ len (loggers_modified ),
322326 [
323- f"{ logger_info ['name' ]} (handlers= { logger_info ['handlers' ]} , propagate= { logger_info [ 'propagate ' ]} )"
324- for logger_info in edge_case_loggers [:3 ]
327+ f"{ info ['name' ]} (removed_handlers= { info ['handlers' ]} , enabled_propagate= { info [ 'had_propagate_disabled ' ]} )"
328+ for info in loggers_modified [:3 ]
325329 ], # Show first 3 to avoid spam
326330 )
327331
328- # Replace only root logger handlers
332+ # Set up root logger with queue handler only
329333 root_logger .handlers .clear ()
330334 root_logger .addHandler (queue_handler )
331335
@@ -338,10 +342,13 @@ async def setup_async_loggers_lifespan(
338342 yield
339343
340344 finally :
341- # Cleanup: Restore original root logger handlers
345+ # Cleanup: Restore all loggers to their original state
342346 try :
343- root_logger .handlers .clear ()
344- root_logger .handlers .extend (original_root_handlers )
347+ for state in original_logger_state :
348+ logger = state ["logger" ]
349+ logger .handlers .clear ()
350+ logger .handlers .extend (state ["handlers" ])
351+ logger .propagate = state ["propagate" ]
345352
346353 # Stop the queue listener
347354 with log_context (
0 commit comments