diff --git a/docs/02_concepts/06_logging.mdx b/docs/02_concepts/06_logging.mdx index ace9ee4d..5acf3f8e 100644 --- a/docs/02_concepts/06_logging.mdx +++ b/docs/02_concepts/06_logging.mdx @@ -1,7 +1,7 @@ --- id: logging title: Logging -description: Configure debug logging to inspect API requests and responses. +description: Configure debug logging for API requests and redirect Actor run logs to Python loggers. --- import Tabs from '@theme/Tabs'; @@ -10,6 +10,12 @@ import CodeBlock from '@theme/CodeBlock'; import LoggingConfigExample from '!!raw-loader!./code/06_logging_config.py'; import LoggingFormatterExample from '!!raw-loader!./code/06_logging_formatter.py'; +import RedirectCallAsyncExample from '!!raw-loader!./code/06_redirect_call_async.py'; +import RedirectCallSyncExample from '!!raw-loader!./code/06_redirect_call_sync.py'; +import RedirectRunAsyncExample from '!!raw-loader!./code/06_redirect_run_async.py'; +import RedirectRunSyncExample from '!!raw-loader!./code/06_redirect_run_sync.py'; + +import ApiLink from '@theme/ApiLink'; The library logs useful debug information to the `apify_client` logger whenever it sends requests to the Apify API. You can configure this logger to print debug information to the standard output by adding a handler: @@ -32,3 +38,39 @@ To display these additional properties in the log output, you need to use a cust For more information on creating and using custom log formatters, refer to the official Python [logging documentation](https://docs.python.org/3/howto/logging.html#formatters). + +## Redirecting Actor run logs + +When you start an Actor with `ActorClient.call`, the client redirects the run's log to a Python logger while it waits for the run to finish. The same logger also receives the run's status and status message whenever they change. The `logger` argument controls where the lines go: + +- `'default'` (the default) - A built-in redirect logger named after the Actor and the run ID. +- A `logging.Logger` - Your own logger receives the lines, so give it a handler and a level that let them through. +- `None` - Redirection is turned off. + + + + + {RedirectCallAsyncExample} + + + + + {RedirectCallSyncExample} + + + + +For a run started with `ActorClient.start`, or any other run you have a client for, use `RunClient.get_streamed_log` to redirect its log and `RunClient.get_status_message_watcher` to redirect its status messages. Both accept an optional `to_logger` and work as context managers, or you can call `start()` and `stop()` yourself: + + + + + {RedirectRunAsyncExample} + + + + + {RedirectRunSyncExample} + + + diff --git a/docs/02_concepts/code/06_redirect_call_async.py b/docs/02_concepts/code/06_redirect_call_async.py new file mode 100644 index 00000000..6b268516 --- /dev/null +++ b/docs/02_concepts/code/06_redirect_call_async.py @@ -0,0 +1,21 @@ +import logging + +from apify_client import ApifyClientAsync + +TOKEN = 'MY-APIFY-TOKEN' + + +async def main() -> None: + apify_client = ApifyClientAsync(TOKEN) + actor_client = apify_client.actor('username/actor-name') + + # By default, the run's log and status messages go to a built-in redirect logger. + await actor_client.call() + + # Send the run's log and status messages to your own logger. + logging.basicConfig(level=logging.INFO) + my_logger = logging.getLogger('my_actor_run') + await actor_client.call(logger=my_logger) + + # Turn the redirection off. + await actor_client.call(logger=None) diff --git a/docs/02_concepts/code/06_redirect_call_sync.py b/docs/02_concepts/code/06_redirect_call_sync.py new file mode 100644 index 00000000..acf3da6d --- /dev/null +++ b/docs/02_concepts/code/06_redirect_call_sync.py @@ -0,0 +1,21 @@ +import logging + +from apify_client import ApifyClient + +TOKEN = 'MY-APIFY-TOKEN' + + +def main() -> None: + apify_client = ApifyClient(TOKEN) + actor_client = apify_client.actor('username/actor-name') + + # By default, the run's log and status messages go to a built-in redirect logger. + actor_client.call() + + # Send the run's log and status messages to your own logger. + logging.basicConfig(level=logging.INFO) + my_logger = logging.getLogger('my_actor_run') + actor_client.call(logger=my_logger) + + # Turn the redirection off. + actor_client.call(logger=None) diff --git a/docs/02_concepts/code/06_redirect_run_async.py b/docs/02_concepts/code/06_redirect_run_async.py new file mode 100644 index 00000000..333f733e --- /dev/null +++ b/docs/02_concepts/code/06_redirect_run_async.py @@ -0,0 +1,27 @@ +from apify_client import ApifyClientAsync + +TOKEN = 'MY-APIFY-TOKEN' + + +async def main() -> None: + apify_client = ApifyClientAsync(TOKEN) + actor_client = apify_client.actor('username/actor-name') + + actor_run = await actor_client.start() + run_client = apify_client.run(actor_run.id) + + # Use the helpers as context managers to redirect while the run is in progress. + streamed_log = await run_client.get_streamed_log() + status_message_watcher = await run_client.get_status_message_watcher() + async with streamed_log, status_message_watcher: + await run_client.wait_for_finish() + + # Or start and stop them yourself. + actor_run = await actor_client.start() + run_client = apify_client.run(actor_run.id) + + # With `from_start=False`, only log lines written from now on are redirected. + streamed_log = await run_client.get_streamed_log(from_start=False) + streamed_log.start() + # Do other work while the run's log is redirected. + await streamed_log.stop() diff --git a/docs/02_concepts/code/06_redirect_run_sync.py b/docs/02_concepts/code/06_redirect_run_sync.py new file mode 100644 index 00000000..4281c5fe --- /dev/null +++ b/docs/02_concepts/code/06_redirect_run_sync.py @@ -0,0 +1,27 @@ +from apify_client import ApifyClient + +TOKEN = 'MY-APIFY-TOKEN' + + +def main() -> None: + apify_client = ApifyClient(TOKEN) + actor_client = apify_client.actor('username/actor-name') + + actor_run = actor_client.start() + run_client = apify_client.run(actor_run.id) + + # Use the helpers as context managers to redirect while the run is in progress. + streamed_log = run_client.get_streamed_log() + status_message_watcher = run_client.get_status_message_watcher() + with streamed_log, status_message_watcher: + run_client.wait_for_finish() + + # Or start and stop them yourself. + actor_run = actor_client.start() + run_client = apify_client.run(actor_run.id) + + # With `from_start=False`, only log lines written from now on are redirected. + streamed_log = run_client.get_streamed_log(from_start=False) + streamed_log.start() + # Do other work while the run's log is redirected. + streamed_log.stop()