<@ULVA73B9P> why sometimes simple prints does not ...
# marvin-ai
m
@Marvin why sometimes simple prints does not show up in the logs, while I set log_prints=Trye everywhere
m
thought for 250.1 seconds
Great question — and I think you meant
log_prints=True
(easy typo). Short answer: Prefect only captures
print()
when it’s executed inside an active flow/task run and only to stdout/stderr. If prints happen outside that context or in processes Prefect doesn’t control, they won’t show up. Here are the most common causes and how to fix them. Why prints may not show up even with log_prints=True - Printed outside a run context - Before/after the flow or task actually runs (e.g., module import time, top-level code, or after returning from a task). - Fix: Move prints inside the `@flow`/`@task` function bodies. - Prints happen in another process that Prefect didn’t start - Examples:
subprocess.run(...)
,
multiprocessing
you spawn yourself, or libraries that launch workers (Dask, Ray, Spark, shell commands). - Fix: Capture and log the output yourself:
Copy code
from prefect import flow, get_run_logger
    import subprocess

    @flow(log_prints=True)
    def my_flow():
        r = subprocess.run(["python", "-c", "print('hello')"], capture_output=True, text=True)
        logger = get_run_logger()
        if r.stdout:
            <http://logger.info|logger.info>(r.stdout.strip())
        if r.stderr:
            logger.warning(r.stderr.strip())
- Logging level filters out INFO -
print()
is logged at INFO. If your logging level/handler is WARNING or higher, the messages won’t appear. - Fix: ensure INFO level is enabled (e.g., set
PREFECT_LOGGING_LEVEL=INFO
). - Printing to a custom file handle - Only default
print(...)
(stdout) and
print(..., file=sys.stderr)
are captured. Anything like
print(..., file=open('x.txt','w'))
is not. - Fix: don’t override
file
unless it’s `sys.stdout`/`sys.stderr`. - log_prints not actually enabled in that scope - Resolution order is: explicit on the flow/task → inherit from parent flow context →
PREFECT_LOGGING_LOG_PRINTS
env var (default False). - A subflow or task can override the parent. If something is
log_prints=False
in the chain, prints in that scope won’t be captured. What does work - Any
print()
inside a flow or task run (in the same Python process) with
log_prints=True
will be captured and logged at INFO. - Tasks executed by Prefect (regardless of runner) will patch
print()
during the task’s run. If you spawn your own subprocesses inside that task, those subprocess prints won’t be captured unless you capture and log them manually (as above). Recommended ways to make it consistent - Turn it on at the flow level so tasks inherit it:
Copy code
from prefect import flow, task

  @task
  def do_thing():
      print("This will be logged")

  @flow(log_prints=True)
  def main():
      print("This will be logged")
      do_thing()
- Or set it globally:
Copy code
# shell
  export PREFECT_LOGGING_LOG_PRINTS=true
- If you rely on external commands/processes, always capture their output and send it to the run logger (see subprocess example above). Quick check-list - Are the missing prints inside the actual `@flow`/`@task` body? - Do you spawn subprocesses/multiprocessing inside your code? - Is
PREFECT_LOGGING_LEVEL
at least INFO? - Are you printing to stdout/stderr (not a custom file)? - Any subflow/task explicitly set
log_prints=False
? If you can share: - A minimal code snippet where prints go missing - Your task runner and whether you spawn subprocesses/multiprocessing - How you enabled
log_prints
(decorator vs env var) …I can pinpoint the exact cause and suggest the best fix.