@@ -171,20 +171,6 @@ def _setup_format_string(
171171 return _DEFAULT_FORMATTING
172172
173173
174- def _set_logging_handler (
175- logger : logging .Logger ,
176- * ,
177- fmt : str ,
178- log_format_local_dev_enabled : bool ,
179- ) -> None :
180- for handler in logger .handlers :
181- handler .setFormatter (
182- CustomFormatter (
183- fmt , log_format_local_dev_enabled = log_format_local_dev_enabled
184- )
185- )
186-
187-
188174def _get_all_loggers () -> list [logging .Logger ]:
189175 manager = logging .Logger .manager
190176 root_logger = logging .getLogger ()
@@ -215,7 +201,12 @@ def setup_loggers(
215201 tracing_settings : TracingSettings | None ,
216202) -> None :
217203 """
218- Applies common configuration to ALL registered loggers.
204+ Applies comprehensive configuration to ALL registered loggers.
205+
206+ This function uses a comprehensive approach:
207+ - Removes all handlers from all loggers
208+ - Ensures all loggers propagate to root
209+ - Sets up root logger with properly formatted handler
219210
220211 Args:
221212 log_format_local_dev_enabled: Enable local development formatting
@@ -227,13 +218,17 @@ def setup_loggers(
227218 log_format_local_dev_enabled = log_format_local_dev_enabled ,
228219 )
229220
221+ # Create a properly formatted handler for the root logger
222+ root_handler = logging .StreamHandler ()
223+ root_handler .setFormatter (
224+ CustomFormatter (fmt , log_format_local_dev_enabled = log_format_local_dev_enabled )
225+ )
226+
230227 all_loggers = _get_all_loggers ()
231- for logger in all_loggers :
232- _set_logging_handler (
233- logger ,
234- fmt = fmt ,
235- log_format_local_dev_enabled = log_format_local_dev_enabled ,
236- )
228+
229+ # Apply comprehensive logging setup
230+ # Note: We don't store the original state here since this is a permanent setup
231+ _apply_comprehensive_logging_setup (all_loggers , root_handler )
237232
238233 # Apply filters
239234 _apply_logger_filters (logger_filter_mapping )
@@ -281,57 +276,11 @@ async def setup_async_loggers_lifespan(
281276 # Create queue handler for loggers
282277 queue_handler = logging .handlers .QueueHandler (log_queue )
283278
284- # Comprehensive approach: ensure ALL logs go through async queue
285- root_logger = logging .getLogger ()
279+ # Apply comprehensive logging setup and store original state for restoration
286280 all_loggers = _get_all_loggers ()
287-
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 = []
300- for logger in all_loggers :
301- if logger is root_logger :
302- continue
303-
304- # Track what we're modifying for logging purposes
305- had_handlers = bool (logger .handlers )
306- had_propagate_disabled = not logger .propagate
307-
308- if had_handlers or had_propagate_disabled :
309- loggers_modified .append (
310- {
311- "name" : logger .name ,
312- "had_handlers" : had_handlers ,
313- "had_propagate_disabled" : had_propagate_disabled ,
314- "handlers" : [type (h ).__name__ for h in logger .handlers ],
315- }
316- )
317-
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 ),
326- [
327- f"{ info ['name' ]} (removed_handlers={ info ['handlers' ]} , enabled_propagate={ info ['had_propagate_disabled' ]} )"
328- for info in loggers_modified [:3 ]
329- ], # Show first 3 to avoid spam
330- )
331-
332- # Set up root logger with queue handler only
333- root_logger .handlers .clear ()
334- root_logger .addHandler (queue_handler )
281+ original_logger_state = _apply_comprehensive_logging_setup (
282+ all_loggers , queue_handler
283+ )
335284
336285 try :
337286 # Apply filters if provided
@@ -344,11 +293,7 @@ async def setup_async_loggers_lifespan(
344293 finally :
345294 # Cleanup: Restore all loggers to their original state
346295 try :
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" ]
296+ _restore_logger_state (original_logger_state )
352297
353298 # Stop the queue listener
354299 with log_context (
@@ -606,3 +551,80 @@ def set_parent_module_log_level(
606551) -> None :
607552 parent_module = "." .join (current_module .split ("." )[:- 1 ])
608553 logging .getLogger (parent_module ).setLevel (desired_log_level )
554+
555+
556+ def _store_logger_state (loggers : list [logging .Logger ]) -> list [dict [str , Any ]]:
557+ """Store the original state of loggers for later restoration."""
558+ return [
559+ {
560+ "logger" : logger ,
561+ "handlers" : logger .handlers .copy (),
562+ "propagate" : logger .propagate ,
563+ }
564+ for logger in loggers
565+ ]
566+
567+
568+ def _restore_logger_state (original_state : list [dict [str , Any ]]) -> None :
569+ """Restore loggers to their original state."""
570+ for state in original_state :
571+ logger = state ["logger" ]
572+ logger .handlers .clear ()
573+ logger .handlers .extend (state ["handlers" ])
574+ logger .propagate = state ["propagate" ]
575+
576+
577+ def _apply_comprehensive_logging_setup (
578+ all_loggers : list [logging .Logger ],
579+ root_handler : logging .Handler ,
580+ ) -> list [dict [str , Any ]]:
581+ """
582+ Apply comprehensive logging setup: clear all handlers, ensure propagation,
583+ and set up root logger with the provided handler.
584+
585+ Returns the original logger state for restoration.
586+ """
587+ root_logger = logging .getLogger ()
588+
589+ # Store original state for restoration
590+ original_logger_state = _store_logger_state (all_loggers )
591+
592+ # Remove all handlers from all loggers and ensure propagation
593+ loggers_modified = []
594+ for logger in all_loggers :
595+ if logger is root_logger :
596+ continue
597+
598+ # Track what we're modifying for logging purposes
599+ had_handlers = bool (logger .handlers )
600+ had_propagate_disabled = not logger .propagate
601+
602+ if had_handlers or had_propagate_disabled :
603+ loggers_modified .append (
604+ {
605+ "name" : logger .name ,
606+ "had_handlers" : had_handlers ,
607+ "had_propagate_disabled" : had_propagate_disabled ,
608+ "handlers" : [type (h ).__name__ for h in logger .handlers ],
609+ }
610+ )
611+
612+ # Clear handlers and ensure propagation
613+ logger .handlers .clear ()
614+ logger .propagate = True
615+
616+ if loggers_modified :
617+ _logger .info (
618+ "Modified %d loggers for comprehensive logging: %s" ,
619+ len (loggers_modified ),
620+ [
621+ f"{ info ['name' ]} (removed_handlers={ info ['handlers' ]} , enabled_propagate={ info ['had_propagate_disabled' ]} )"
622+ for info in loggers_modified [:3 ]
623+ ], # Show first 3 to avoid spam
624+ )
625+
626+ # Set up root logger with the provided handler only
627+ root_logger .handlers .clear ()
628+ root_logger .addHandler (root_handler )
629+
630+ return original_logger_state
0 commit comments