Project: Prefect (Orchestration & Management / Scheduling & Orchestration)
File: logs.md

description: Prefect logging captures information about flows and tasks for monitoring, troubleshooting, and auditing. tags: UI dashboard Prefect Cloud flows tasks logging log formatters configuration debug search: boost: 2 Prefect enables you to log a variety of useful information about your flow and task runs, capturing information about your workflows for purposes such as monitoring, troubleshooting, and auditing. Prefect captures logs for your flow and task runs by default, even if you have not started a Prefect server with `prefect server start`. View and filter logs in the or access log records through the API. Prefect enables fine-grained customization of log levels for flows and tasks, including configuration for default levels and log message formatting. Whenever you run a flow, Prefect automatically logs events for flow runs and task runs, along with any custom log handlers you have configured. No configuration is needed to enable Prefect logging. For example, if you created a simple flow in `flow.py` and create a local flow run with `python flow.py`, you'll see an example of the log messages created automatically by Prefect: <div class='terminal'> ```bash 16:45:44.534 | INFO | prefect.engine - Created flow run 'gray-dingo' for flow 'hello-flow' 16:45:44.534 | INFO | Flow run 'gray-dingo' - Using task runner 'SequentialTaskRunner' 16:45:44.598 | INFO | Flow run 'gray-dingo' - Created task run 'hello-task-54135dc1-0' for task 'hello-task' Hello world! 16:45:44.650 | INFO | Task run 'hello-task-54135dc1-0' - Finished in state Completed(None) 16:45:44.672 | INFO | Flow run 'gray-dingo' - Finished in state Completed('All states completed.') ``` </div> See logs for a flow run in the UI by navigating to the page and selecting a specific flow run to inspect. These log messages reflect the logging configuration for log levels and message formatters. Customize the log levels captured and the default message format through configuration, and capture custom logging events by explicitly emitting log messages during flow and task runs. Prefect supports the standard Python logging levels `CRITICAL`, `ERROR`, `WARNING`, `INFO`, and `DEBUG`. By default, Prefect displays `INFO`-level and above events. Configure the root logging level as well as specific logging levels for flow and task runs. Prefect provides several settings to configure . By default, Prefect displays `INFO`-level and above logging records. Change this level to `DEBUG` and see `DEBUG`-level logs created by Prefect as well. You may need to change the log level used by loggers from other libraries to see their log records. Override any logging configuration by setting an environment variable or setting using the syntax `PREFECTLOGGING[PATH][TO][KEY]`, with `[PATH][TO][KEY]` corresponding to the nested address of any setting. For example, to change the default logging levels for Prefect to `DEBUG`, set the environment variable `PREFECTLOGGINGLEVEL="DEBUG"`. You may also configure the "root" Python logger. The root logger receives logs from all loggers unless they explicitly opt out by disabling propagation. By default, the root logger is configured to output `WARNING` level logs to the

As with other logging settings, you can override this from the environment or in the logging configuration file. For example, you can change the level with the variable `PREFECTLOGGINGROOT_LEVEL`. You may adjust the log level used by specific handlers. For example, set `PREFECTLOGGINGHANDLERSAPILEVEL=ERROR` to have only `ERROR` logs reported to the Prefect API. The console handlers will still default to level `INFO`. There is a file packaged with Prefect that defines the default logging configuration. Customize logging configuration by creating your own version of `logging.yml` with custom settings, by either creating the file at the default location (`/.prefect/logging.yml`) or by specifying the path to the file with `PREFECTLOGGINGSETTINGS_PATH`. (If the file does not exist at the specified location, Prefect ignores the setting and uses the default configuration.) See the Python documentation for more information about the configuration options and syntax used by `logging.yml`. To access the Prefect logger, import `from prefect import getrunlogger`. You can send messages to the logger in both flows and tasks. To log from a flow, retrieve a logger instance with `getrunlogger()`, then call the standard Python . ```python from prefect import flow, getrunlogger @flow(name="log-example-flow") def logger_flow(): logger = getrunlogger() logger.info("INFO level log message.") ``` Prefect automatically uses the flow run logger based on the flow context. If you run the code above, Prefect captures the following as a log event: <div class='terminal'> ```bash 15:35:17.304 | INFO | Flow run 'mottled-marten' - INFO level log message. ``` </div> The default flow run log formatter uses the flow run name for log messages. !!! note Starting in 2.7.11, if you use a logger that sends logs to the API outside of a flow or task run, a warning is displayed instead of an error. Silence this warning by setting `PREFECTLOGGINGTOAPIWHENMISSINGFLOW=ignore` or have the logger raise an error by setting the value to `error`. Logging in tasks works much like logging in flows: retrieve a logger instance with `getrunlogger()`, then call the standard Python . ```python from prefect import flow, task, getrunlogger @task(name="log-example-task") def logger_task(): logger = getrunlogger() logger.info("INFO level log message from a task.") @flow(name="log-example-flow") def logger_flow(): logger_task() ``` Prefect automatically uses the task run logger based on the task context. The default task run log formatter uses the task run name for log messages. <div class='terminal'> ```bash 15:33:47.179 | INFO | Task run 'logger_task-80a1ffd1-0' - INFO level log message from a task. ``` </div> The underlying log model for task runs captures the task name, task run ID, and parent flow run ID, which are persisted to the database for reporting and may also be used in custom message formatting. Prefect provides the `logprints` option to enable the logging of `print` statements at the task or flow level. When `logprints=True` for a given task or flow, the Python built-in `print` is patched to redirect to the Prefect logger for the scope of that task or

By default, tasks and subflows inherit the `logprints` setting from their parent flow, unless opted out with their own explicit `logprints` setting. ```python from prefect import task, flow @task def my_task(): print("we're logging print statements from a task") @flow(log_prints=True) def my_flow(): print("we're logging print statements from a flow") my_task() ``` Will output: <div class='terminal'> ```bash 15:52:11.244 | INFO | prefect.engine - Created flow run 'emerald-gharial' for flow 'my-flow' 15:52:11.812 | INFO | Flow run 'emerald-gharial' - we're logging print statements from a flow 15:52:11.926 | INFO | Flow run 'emerald-gharial' - Created task run 'mytask-20c6ece6-0' for task 'mytask' 15:52:11.927 | INFO | Flow run 'emerald-gharial' - Executing 'my_task-20c6ece6-0' immediately... 15:52:12.217 | INFO | Task run 'my_task-20c6ece6-0' - we're logging print statements from a task ``` </div> ```python from prefect import task, flow @task def mytask(logprints=False): print("not logging print statements in this task") @flow(log_prints=True) def my_flow(): print("we're logging print statements from a flow") my_task() ``` Using `log_prints=False` at the task level will output: <div class='terminal'> ```bash 15:52:11.244 | INFO | prefect.engine - Created flow run 'emerald-gharial' for flow 'my-flow' 15:52:11.812 | INFO | Flow run 'emerald-gharial' - we're logging print statements from a flow 15:52:11.926 | INFO | Flow run 'emerald-gharial' - Created task run 'mytask-20c6ece6-0' for task 'mytask' 15:52:11.927 | INFO | Flow run 'emerald-gharial' - Executing 'my_task-20c6ece6-0' immediately... not logging print statements in this task ``` </div> Configure this behavior globally for all Prefect flows, tasks, and subflows. <div class='terminal'> ```bash prefect config set PREFECTLOGGINGLOG_PRINTS=True ``` </div> Prefect log formatters specify the format of log messages. See details of message formatting for different loggers in . For example, the default formatting for task run log records is: ```python "%(asctime)s.%(msecs)03d | %(levelname)-7s | Task run %(taskrunname)r - %(message)s" ``` The variables available to interpolate in log messages varies by logger. In addition to the run context, message string, and any keyword arguments, flow and task run loggers have access to additional variables. The flow run logger has the following: `flowrunname` `flowrunid` `flow_name` The task run logger has the following: `taskrunid` `flowrunid` `taskrunname` `task_name` `flowrunname` `flow_name` Specify custom formatting by setting an environment variable or by modifying the formatter in a `logging.yml` file as described earlier. For example, to change the formatting for the flow runs formatter: <div class='terminal'> ```bash PREFECTLOGGINGFORMATTERSSTANDARDFLOWRUNFMT="%(asctime)s.%(msecs)03d | %(levelname)-7s | %(flowrunid)s - %(message)s" ``` </div> The resulting messages, using the flow run ID instead of name, look like this: <div class='terminal'> ```bash 10:40:01.211 | INFO | e43a5a80-417a-41c4-a39e-2ef7421ee1fc - Created task run 'othertask-1c085beb-3' for task 'othertask' ``` </div> By default, Prefect highlights specific keywords in the console logs with a variety of colors. Toggle highlighting on/off with the `PREFECTLOGGINGCOLORS` setting: <div class='terminal'> ```bash PREFECTLOGGINGCOLORS=False ``` </div> Change what gets highlighted and adjust the colors by updating the styles in a `logging.yml` file. List the specific keys built-in to the `PrefectConsoleHighlighter` as shown below. URLs: `log.web_url` `log.local_url` Log levels: `log.info_level` `log.warning_level` `log.error_level` `log.critical_level` State types: `log.pending_state` `log.running_state` `log.scheduled_state` `log.completed_state` `log.cancelled_state` `log.failed_state` `log.crashed_state` Flow (run) names: `log.flowrunname` `log.flow_name` Task (run) names: `log.taskrunname`

Build your own handler with a . For example, to additionally highlight emails: Copy and paste the following code into `mypackageor_module.py` (rename as needed) in the same directory as the flow run script, or ideally as part of a Python package so it's available in `site-packages` and accessible anywhere within your environment. ```python import logging from typing import Dict, Union from rich.highlighter import Highlighter from prefect.logging.handlers import PrefectConsoleHandler from prefect.logging.highlighters import PrefectConsoleHighlighter class CustomConsoleHighlighter(PrefectConsoleHighlighter): base_style = "log." highlights = PrefectConsoleHighlighter.highlights + [ r"(?P<email>[\w-]+@([\w-]+\.)+[\w-]+)", ] class CustomConsoleHandler(PrefectConsoleHandler): def init( self, highlighter: Highlighter = CustomConsoleHighlighter, styles: Dict[str, str] = None, level: Union[int, str] = logging.NOTSET, ): super().init(highlighter=highlighter, styles=styles, level=level) ``` Update `/.prefect/logging.yml` to use `mypackageormodule.CustomConsoleHandler` and additionally reference the basestyle and named expression: `log.email`. ```yaml consoleflowruns: level: 0 class: mypackageor_module.CustomConsoleHandler formatter: flow_runs styles: log.email: magenta ``` On your next flow run, text that looks like an email will be highlighted. For example, `my@email.com` is colored in magenta below: ```python from prefect import flow, getrunlogger @flow def logemailflow(): logger = getrunlogger() logger.info("my@email.com") logemailflow() ``` To use in Prefect logs, first configure `PREFECTLOGGINGMARKUP`: <div class='terminal'> ```bash PREFECTLOGGINGMARKUP=True ``` </div> The following will highlight "fancy" in red: ```python from prefect import flow, getrunlogger @flow def my_flow(): logger = getrunlogger() logger.info("This is [bold red]fancy[/]") my_flow() ``` !!! warning "Inaccurate logs could result" Although this can be convenient, the downside is, if enabled, strings that contain square brackets may be inaccurately interpreted and lead to incomplete output. For example, `DROP TABLE [dbo].[SomeTable];"` outputs `DROP TABLE .[SomeTable];`. Logged events are also persisted to the Prefect database. A log record includes the following data: | Column | Description | | -- | - | | id | Primary key ID of the log record. | | created | Timestamp specifying when the record was created. | | updated | Timestamp specifying when the record was updated. | | name | String specifying the name of the logger. | | level | Integer representation of the logging level. | | flowrunid | ID of the flow run associated with the log record. If the log record is for a task run, this is the parent flow of the task. | | taskrunid | ID of the task run associated with the log record. Null if logging a flow run event. | | message | Log message. | | timestamp | The client-side timestamp of this logged statement. | For more information, see in the API documentation. By default, Prefect won't capture log statements from libraries that your flows and tasks use. You can tell Prefect to include logs from these libraries with the `PREFECTLOGGINGEXTRA_LOGGERS` setting. To use this setting, specify one or more Python library names to include, separated by commas. For example, if you want to make sure Prefect captures Dask and SciPy logging statements with your flow and task run logs: PREFECTLOGGINGEXTRA_LOGGERS=dask,scipy You can configure this setting as an environment variable or in a profile. See for more details about how to use settings.