Skip to content

Add on_missing_context parameter to get_run_logger()#21028

Open
zionts wants to merge 6 commits intoPrefectHQ:mainfrom
zionts:fix/get-run-logger-thread-fallback
Open

Add on_missing_context parameter to get_run_logger()#21028
zionts wants to merge 6 commits intoPrefectHQ:mainfrom
zionts:fix/get-run-logger-thread-fallback

Conversation

@zionts
Copy link
Copy Markdown
Contributor

@zionts zionts commented Mar 9, 2026

Summary

Closes #21027get_run_logger() raises MissingContextError in threaded contexts with no fallback option.

When using ThreadPoolExecutor inside Prefect tasks for parallel processing, worker threads don't inherit the Prefect run context. Any code that calls get_run_logger() in these threads crashes with MissingContextError. The only workaround today is to monkey-patch prefect.get_run_logger globally.

Changes

New on_missing_context parameter on get_run_logger():

  • "raise" (default): current behavior, fully backward compatible
  • "warn": return a standard prefect logger and emit a debug message
  • "ignore": return a standard prefect logger silently
# Before: crashes in threads
logger = get_run_logger()  # MissingContextError in ThreadPoolExecutor workers

# After: works everywhere
logger = get_run_logger(on_missing_context="warn")
logger.info("Processing file")  # Prefect logger in context, fallback in threads

The fallback logger is a standard prefect.run_fallback logger created via the existing get_logger() function, so it inherits Prefect's logging configuration.

Testing

  • 7 new tests in tests/logging/test_on_missing_context.py
  • Verifies default "raise" behavior is unchanged (backward compat)
  • Verifies "warn" returns logger and emits debug message
  • Verifies "ignore" returns logger silently
  • Verifies fallback logger is functional

Checklist

get_run_logger() raises MissingContextError when called outside a
flow or task run context. This makes it unusable from threads
(e.g. ThreadPoolExecutor workers) where no Prefect context exists,
forcing users to monkey-patch the function or wrap every call in
try/except.

Add an on_missing_context parameter that controls this behavior:
- "raise" (default): current behavior, fully backward compatible
- "warn": return a standard prefect logger + emit debug message
- "ignore": return a standard prefect logger silently

This lets users write code that works both inside and outside
Prefect run contexts without monkey-patching.
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Mar 9, 2026

Merging this PR will not alter performance

✅ 2 untouched benchmarks


Comparing zionts:fix/get-run-logger-thread-fallback (00126f2) with main (316330b)

Open in CodSpeed

Get a Prefect logger for the current task run or flow run.

The logger will be named either `prefect.task_runs` or `prefect.flow_runs`.
The logger will be named either ``prefect.task_runs`` or ``prefect.flow_runs``.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The logger will be named either ``prefect.task_runs`` or ``prefect.flow_runs``.
The logger will be named either `prefect.task_runs` or `prefect.flow_runs`.

Contextual data about the run will be attached to the log records.

These loggers are connected to the `APILogHandler` by default to send log records to
These loggers are connected to the ``APILogHandler`` by default to send log records to
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
These loggers are connected to the ``APILogHandler`` by default to send log records to
These loggers are connected to the `APILogHandler` by default to send log records to

Comment on lines +117 to +122
on_missing_context: Controls behavior when no active flow or task run context
exists. ``"raise"`` (default) raises ``MissingContextError`` for backward
compatibility. ``"warn"`` returns a standard ``prefect`` logger and emits a
warning. ``"ignore"`` returns a standard ``prefect`` logger silently. Use
``"warn"`` or ``"ignore"`` when calling from threads or other contexts where
a Prefect run context may not be available.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
on_missing_context: Controls behavior when no active flow or task run context
exists. ``"raise"`` (default) raises ``MissingContextError`` for backward
compatibility. ``"warn"`` returns a standard ``prefect`` logger and emits a
warning. ``"ignore"`` returns a standard ``prefect`` logger silently. Use
``"warn"`` or ``"ignore"`` when calling from threads or other contexts where
a Prefect run context may not be available.
on_missing_context: Controls behavior when no active flow or task run context
exists. `"raise"` (default) raises `MissingContextError` for backward
compatibility. `"warn"` returns a standard `prefect` logger and emits a
warning. `"ignore"` returns a standard `prefect` logger silently. Use
`"warn"` or `"ignore"` when calling from threads or other contexts where
a Prefect run context may not be available.

Comment on lines +127 to +128
MissingContextError: If no context can be found and ``on_missing_context`` is
``"raise"``
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
MissingContextError: If no context can be found and ``on_missing_context`` is
``"raise"``
MissingContextError: If no context can be found and `on_missing_context` is
`"raise"`

Comment thread src/prefect/logging/loggers.py Outdated
logger = logging.getLogger("null")
logger.disabled = True
elif on_missing_context == "warn":
logger = get_logger("prefect.run_fallback")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd feel better about adding this if users had the option to customize this logger name.

Comment thread src/prefect/logging/loggers.py Outdated
elif on_missing_context == "ignore":
logger = get_logger("prefect.run_fallback")
else:
raise MissingContextError("There is no active flow or task run context.")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be good to mention the new on_missing_context kwarg in this exception message.

zionts and others added 2 commits March 18, 2026 00:13
Apply docstring suggestions, add fallback_logger_name parameter for
customizing the logger returned in warn/ignore modes, and mention
on_missing_context in the MissingContextError message.
@zionts
Copy link
Copy Markdown
Contributor Author

zionts commented Mar 26, 2026

Friendly bump @desertaxle — all review feedback has been addressed and CI is green. Let me know if there's anything else needed!

Comment thread src/prefect/logging/loggers.py Outdated
@desertaxle
Copy link
Copy Markdown
Member

@zionts it looks like there are some test failures on this PR. Those need to be addressed before we can merge.

@github-actions
Copy link
Copy Markdown
Contributor

This pull request is stale because it has been open 14 days with no activity. To keep this pull request open remove stale label or comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

get_run_logger() raises MissingContextError in threaded contexts with no fallback option

2 participants