File tree Expand file tree Collapse file tree 2 files changed +19
-3
lines changed
src/uipath/runtime/logging Expand file tree Collapse file tree 2 files changed +19
-3
lines changed Original file line number Diff line number Diff line change @@ -209,7 +209,14 @@ def _redirect_stdout_stderr(self) -> None:
209209 )
210210
211211 def teardown (self ) -> None :
212- """Restore original logging configuration."""
212+ """Restore original logging configuration.
213+
214+ IMPORTANT: The ordering below is critical. Flushing must happen before
215+ clearing the context variable and before removing handlers. Otherwise:
216+ - If context is cleared first, the execution filter won't match the
217+ flushed records and they'll be dropped.
218+ - If handlers are removed first, the flushed records have no destination.
219+ """
213220 # Step 1: Flush LoggerWriter buffers while context and handlers are still active.
214221 # Child mode: flush only this context's buffer from the shared LoggerWriter.
215222 # Master mode: flush ALL remaining buffers before restoring streams.
@@ -266,7 +273,9 @@ def teardown(self) -> None:
266273 if self ._owns_handler :
267274 self .log_handler .close ()
268275
269- # Step 5: Only master restores streams (children never replaced them)
276+ # Step 5: Only master restores streams. Children never replaced
277+ # sys.stdout/sys.stderr (they only registered handlers on the loggers),
278+ # so there is nothing for them to restore here.
270279 if not self .execution_id and self .original_stdout and self .original_stderr :
271280 sys .stdout = self .original_stdout
272281 sys .stderr = self .original_stderr
Original file line number Diff line number Diff line change @@ -24,6 +24,9 @@ def __init__(
2424 self .logger = logger
2525 self .level = level
2626 self .min_level = min_level
27+ # Keyed by current_execution_id (None for master context).
28+ # A single shared buffer would interleave partial lines from
29+ # concurrent async tasks writing to the same sys.stdout.
2730 self ._buffers : dict [str | None , str ] = {}
2831 self .sys_file = sys_file
2932 self ._in_logging = False # Recursion guard
@@ -75,7 +78,11 @@ def flush(self) -> None:
7578 self ._in_logging = False
7679
7780 def flush_all (self ) -> None :
78- """Flush all execution contexts' buffered messages. Called by master teardown."""
81+ """Flush all execution contexts' buffered messages. Called by master teardown.
82+
83+ Intentionally ignores current_execution_id — iterates all keys
84+ directly so that no context's partial lines are lost.
85+ """
7986 if self ._in_logging :
8087 return
8188
You can’t perform that action at this time.
0 commit comments