korex-f commented on code in PR #66633:
URL: https://github.com/apache/airflow/pull/66633#discussion_r3237163268


##########
providers/amazon/src/airflow/providers/amazon/aws/log/cloudwatch_task_handler.py:
##########
@@ -118,16 +119,29 @@ def handler(self) -> watchtower.CloudWatchLogHandler:
             json_serialize_default=_json_serialize or json_serialize_legacy,
         )
 
+    @property
+    def handler(self) -> watchtower.CloudWatchLogHandler:
+        # Defensive self-healing: if the handler was killed by 
logging.shutdown()
+        # (shutting_down=True), recreate it. This can happen if dictConfig() 
is called
+        # after the handler was first created, since dictConfig calls
+        # _clearExistingHandlers() -> logging.shutdown() on all existing 
handlers.
+        if self._handler is None or self._handler.shutting_down:
+            self._handler = self._create_handler()
+        return self._handler
+
     @cached_property
     def processors(self) -> tuple[structlog.typing.Processor, ...]:
         from logging import getLogRecordFactory
 
         import structlog.stdlib
 
         logRecordFactory = getLogRecordFactory()
-        # The handler MUST be initted here, before the processor is actually 
used to log anything.
-        # Otherwise, logging that occurs during the creation of the handler 
can create infinite loops.
-        _handler = self.handler
+        # Eagerly init the handler to avoid infinite loops from logging during 
handler creation.
+        # We do NOT capture it in a closure variable — instead we access 
self.handler each time
+        # so that if the handler is killed by logging.shutdown() and 
recreated, the processor
+        # always uses the live instance rather than a dead one.#
+        _ = self.handler

Review Comment:
   The assignment itself doesn't matter, i think what matters is the access. 
Calling `self.handler` eagerly triggers the property which initializes the 
boto3 client and creates the watchtower handler before the processor closure is 
returned. Without this eager initialization, the first log emission would 
trigger handler creation, which itself logs internally, which triggers handler 
creation again, infinite loop.
   I've changed `_ = self.handler` to a bare `self.handler` with a comment 
making this clearer.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to