Uh oh!
There was an error while loading. Please reload this page.
Fix remote processor injection happening before dictConfig runs in configure_logging - #66633
Fix remote processor injection happening before dictConfig runs in configure_logging#66633korex-f wants to merge 3 commits into
Conversation
chris-stetter
commented
May 11, 2026
I can confirm that this works in our ECS environment. Thank you! |
korex-f
commented
May 11, 2026
You're very much welcome. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
korex-f
commented
May 13, 2026
Good point, I have added tests to test_cloudwatch_task_handler.py covering the self-healing handler property (verifies a new handler is created when shutting_down=True) and the dynamic self.handler access in the processors closure. |
o-nikolas
left a comment
There was a problem hiding this comment.
Looks reasonable to me now, but I still think @ashb or @amoghrajesh should have a look
potiuk
commented
May 18, 2026
@korex-f — There are 2 unresolved review threads on this PR from @o-nikolas. Could you either push a fix or reply in each thread explaining why the feedback doesn't apply? Once you believe the feedback is addressed, mark the thread as resolved so the reviewer isn't re-pinged needlessly. Thanks! Note: This comment was drafted by an AI-assisted triage tool and may contain mistakes. Once you have addressed the points above, an Apache Airflow maintainer — a real person — will take the next look at your PR. We use this two-stage triage process so that our maintainers' limited time is spent where it matters most: the conversation with you. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
seanghaeli
left a comment
There was a problem hiding this comment.
Verified end-to-end this fixes remote logging. Thanks @korex-f this issue has been floating around for a while.
904f1ea to
ff723d1Compare
1fanwang
left a comment
There was a problem hiding this comment.
Thanks for addressing the comments, lgtm!
ff723d1 to
93a67a7Comparepotiuk
commented
Jun 9, 2026
@korex-f — A reviewer (@ashb) has requested changes on this PR, so I've removed the Note: This comment was drafted by an AI-assisted triage tool and may contain mistakes. Once you have addressed the points above, an Apache Airflow maintainer — a real person — will take the next look at your PR. We use this two-stage triage process so that our maintainers' limited time is spent where it matters most: the conversation with you. |
korex-f
commented
Jun 10, 2026
Thanks for the review, @ashb. I have addressed the requested changes, pushed the fixes, and re-requested review. Please do take another look when you have the chance. |
sarvesh371
commented
Jun 11, 2026
Hey, running into this exact issue on Airflow 3.2.2 with KubernetesExecutor — task pods emit WatchtowerWarning: Received message after logging system shutdown and logs never make it to CloudWatch. Any idea on ETA for merge and which provider version will ship the fix? Also is there any interim workaround while we wait? Happy to test if there's a pre-release available. |
korex-f
commented
Jul 12, 2026
Addressed all outstanding review comments:
|
eladkal
commented
Jul 16, 2026
Can the provider related changes be split into a dedicated PR? |
korex-f
commented
Jul 17, 2026
Done! |
o-nikolas
commented
Jul 17, 2026
@jason810496 and @ferruzzi, does this look good to approve/merge for y'all? @ashb it looks like your feedback was addressed, but you "requested changes" which makes me think you saw something very serious, are you happy with this PR now? |
You may not have pushed that, there are still provider changes in the current diff: Edit to add: the whitespace change in supervisor.py that you said was done is also not there. |
921eb9d to
f6d0f20Comparekorex-f
commented
Jul 21, 2026
Sorry for the confusion, the revert was there but spread across multiple commits, making it look like provider changes were still present in the per-commit view. The net diff against upstream/main now only touches task-sdk/src/airflow/sdk/execution_time/supervisor.py and task-sdk/src/airflow/sdk/log.py. No provider files are modified. |
jason810496
left a comment
There was a problem hiding this comment.
Here're final nits that would appreciate be addressed before merge, thanks.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
kaxil
commented
Jul 21, 2026
Picking up on @o-nikolas's merge question -- I think this needs a second look at scope before it goes in, because a fair bit of it landed via other PRs while this was open:
Given that, the supervisor.py side here (explicit @korex-f -- is there a failure mode left that the three merged PRs don't cover? If the log.py reorder is the remaining value, it may be worth narrowing this to just that (with a test); otherwise it looks mostly superseded now. Not trying to discount the work here, just want to make sure we're not re-landing something. |
korex-f
commented
Jul 22, 2026
Thanks for the detailed audit @kaxil — really helpful context. You're right that #68779, #67935, and #68370 together cover the provider-layer symptom. Looking at what's left: log.py reorder (Bug 1): supervisor.py What would you prefer? |
jason810496
left a comment
There was a problem hiding this comment.
Thank you for the update.
is there a failure mode left that the three merged PRs don't cover?
Yes log.py reorder (Bug 1): getattr(remote, "processors") was called before dictConfig ran, which meant dictConfig's _clearExistingHandlers closed the just-built watchtower handler before any task log was emitted. statement is correct.
I'd like to keep the only the log.py changes as that is the key point to resolve the unexpected .close on logging handler. The supervisors.py change is more "nice to have" but it might introduce further regression. Let's keep the change minimal if possible, thanks.
korex-f
commented
Jul 27, 2026
Thanks for the clarity. Reverting all supervisor.py changes now, this PR will only contain the log.py reorder (Bug 1). supervisor.py can be revisited in a follow-up if needed. |
jason810496
left a comment
There was a problem hiding this comment.
Hi @korex-f,
Thanks for follow-up on this.
We need to do the following items before merge.
- Add unit test to exercise the patch itself
- Fix the CI failure
- Rephrase the PR title and the description
Thanks.
Added a regression test in test_log.py that verifies load_remote_log_handler() is called only after the inner configure_logging() (dictConfig) returns. The CI failure in test_inject_parent_job_info_with_resume_on_retry is unrelated, it's a Glue operator test making a real network call that times out, last touched in #64513. Happy to re-trigger CI to confirm it's a flake. |
608b35f to
ec31091Compare
jason810496
left a comment
There was a problem hiding this comment.
#70938 - fix the OpenAI provider CI failure. Rebasing on top of the latest main should fix. Thanks.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…nfigure_logging In configure_logging(), getattr(remote, 'processors') was called before dictConfig() ran. dictConfig() calls _clearExistingHandlers() which closes every handler in logging._handlerList — including the remote handler built moments earlier. This caused CloudWatch/Watchtower logs to be silently dropped when using the Task SDK with remote logging on ECS/Kubernetes workers. Fix: move the remote processor injection to after dictConfig() has run via a second structlog.configure() call. Also gate on not sending_to_supervisor to avoid unmasked events from the task subprocess, and add a None default to getattr() to handle third-party RemoteLogIO objects. Provider-side fix: apache#68779Closesapache#66475
…nfigure_logging In configure_logging(), getattr(remote, 'processors') was called before dictConfig() ran. dictConfig() calls _clearExistingHandlers() which closes every handler in logging._handlerList — including the remote handler built moments earlier. This caused CloudWatch/Watchtower logs to be silently dropped when using the Task SDK with remote logging on ECS/Kubernetes workers. Fix: move the remote processor injection to after dictConfig() has run via a second structlog.configure() call. Also gate on not sending_to_supervisor to avoid unmasked events from the task subprocess, and add a None default to getattr() to handle third-party RemoteLogIO objects. Closesapache#66475
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…nfigure_logging In configure_logging(), getattr(remote, 'processors') was called before dictConfig() ran. dictConfig() calls _clearExistingHandlers() which closes every handler in logging._handlerList — including the remote handler built moments earlier. This caused CloudWatch/Watchtower logs to be silently dropped when using the Task SDK with remote logging on ECS/Kubernetes workers. Fix: move the remote processor injection to after dictConfig() has run via a second structlog.configure() call. Also gate on not sending_to_supervisor to avoid unmasked events from the task subprocess, and add a None default to getattr() to handle third-party RemoteLogIO objects. Closesapache#66475
3217a41 to
2667be1Compare@kaxil
|
korex-f
commented
Aug 5, 2026
Thanks for the guidance. |
Problem
In
configure_logging(),getattr(remote, "processors")was called beforedictConfig()ran.dictConfig()calls_clearExistingHandlers()which closes every handler registered inlogging._handlerList, including the watchtower handler built moments earlier. This caused CloudWatch/Watchtower logs to be silently dropped when using the Task SDK with remote logging.Fix
Move the remote processor injection to after
dictConfig()has run. The handler is now built into a clean logging state and cannot be killed prematurely.Also gate the injection on
not sending_to_supervisorto avoid unmasked events from the task subprocess, and add aNonedefault togetattrto handle third-partyRemoteLogIOobjects missing theprocessorsattribute.Related
Provider-side fix: #68779
closes: #66475
Important
🛠️ Maintainer triage note for @korex-f · by
@potiuk· 2026-07-02 17:46 UTCSome review feedback from
@jason810496is waiting on you:@jason810496need a reply or a fix.The ball is in your court — you've been assigned to this PR. Reply or push a fix in each thread, then mark them resolved.
Automated triage — may be imperfect; a maintainer takes the next look.