From 9a98251162e0a580ab59edc5f500209fa502e68b Mon Sep 17 00:00:00 2001 From: dheerajitbhu <73860752+dheerajitbhu@users.noreply.github.com> Date: Thu, 5 Nov 2026 11:09:19 -0800 Subject: [PATCH 1/2] docs: document Actor run log redirection on the Logging page --- docs/02_concepts/06_logging.mdx | 42 +++++++++++++++++++ .../code/06_redirect_call_async.py | 20 +++++++++ .../02_concepts/code/06_redirect_call_sync.py | 20 +++++++++ .../02_concepts/code/06_redirect_run_async.py | 22 ++++++++++ docs/02_concepts/code/06_redirect_run_sync.py | 22 ++++++++++ 5 files changed, 126 insertions(+) create mode 100644 docs/02_concepts/code/06_redirect_call_async.py create mode 100644 docs/02_concepts/code/06_redirect_call_sync.py create mode 100644 docs/02_concepts/code/06_redirect_run_async.py create mode 100644 docs/02_concepts/code/06_redirect_run_sync.py diff --git a/docs/02_concepts/06_logging.mdx b/docs/02_concepts/06_logging.mdx index ace9ee4d..2479da8b 100644 --- a/docs/02_concepts/06_logging.mdx +++ b/docs/02_concepts/06_logging.mdx @@ -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. +- `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..9cb94f19 --- /dev/null +++ b/docs/02_concepts/code/06_redirect_call_async.py @@ -0,0 +1,20 @@ +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. + 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..b4595db4 --- /dev/null +++ b/docs/02_concepts/code/06_redirect_call_sync.py @@ -0,0 +1,20 @@ +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. + 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..b91eeb3f --- /dev/null +++ b/docs/02_concepts/code/06_redirect_run_async.py @@ -0,0 +1,22 @@ +from apify_client import ApifyClientAsync + +TOKEN = 'MY-APIFY-TOKEN' + + +async def main() -> None: + apify_client = ApifyClientAsync(TOKEN) + actor_run = await apify_client.actor('username/actor-name').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. + # 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..11d8ce18 --- /dev/null +++ b/docs/02_concepts/code/06_redirect_run_sync.py @@ -0,0 +1,22 @@ +from apify_client import ApifyClient + +TOKEN = 'MY-APIFY-TOKEN' + + +def main() -> None: + apify_client = ApifyClient(TOKEN) + actor_run = apify_client.actor('username/actor-name').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. + # 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() From 0d2025a96e2bb043d4a10a3433972d57c81d13ab Mon Sep 17 00:00:00 2001 From: Vlada Dusek Date: Fri, 6 Nov 2026 12:27:36 +0100 Subject: [PATCH 2/2] docs: fix run log redirection examples --- docs/02_concepts/06_logging.mdx | 4 ++-- docs/02_concepts/code/06_redirect_call_async.py | 1 + docs/02_concepts/code/06_redirect_call_sync.py | 1 + docs/02_concepts/code/06_redirect_run_async.py | 7 ++++++- docs/02_concepts/code/06_redirect_run_sync.py | 7 ++++++- 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/docs/02_concepts/06_logging.mdx b/docs/02_concepts/06_logging.mdx index 2479da8b..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'; @@ -44,7 +44,7 @@ For more information on creating and using custom log formatters, refer to the o 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. +- 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. diff --git a/docs/02_concepts/code/06_redirect_call_async.py b/docs/02_concepts/code/06_redirect_call_async.py index 9cb94f19..6b268516 100644 --- a/docs/02_concepts/code/06_redirect_call_async.py +++ b/docs/02_concepts/code/06_redirect_call_async.py @@ -13,6 +13,7 @@ async def main() -> None: 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) diff --git a/docs/02_concepts/code/06_redirect_call_sync.py b/docs/02_concepts/code/06_redirect_call_sync.py index b4595db4..acf3da6d 100644 --- a/docs/02_concepts/code/06_redirect_call_sync.py +++ b/docs/02_concepts/code/06_redirect_call_sync.py @@ -13,6 +13,7 @@ def main() -> None: 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) diff --git a/docs/02_concepts/code/06_redirect_run_async.py b/docs/02_concepts/code/06_redirect_run_async.py index b91eeb3f..333f733e 100644 --- a/docs/02_concepts/code/06_redirect_run_async.py +++ b/docs/02_concepts/code/06_redirect_run_async.py @@ -5,7 +5,9 @@ async def main() -> None: apify_client = ApifyClientAsync(TOKEN) - actor_run = await apify_client.actor('username/actor-name').start() + 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. @@ -15,6 +17,9 @@ async def main() -> None: 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() diff --git a/docs/02_concepts/code/06_redirect_run_sync.py b/docs/02_concepts/code/06_redirect_run_sync.py index 11d8ce18..4281c5fe 100644 --- a/docs/02_concepts/code/06_redirect_run_sync.py +++ b/docs/02_concepts/code/06_redirect_run_sync.py @@ -5,7 +5,9 @@ def main() -> None: apify_client = ApifyClient(TOKEN) - actor_run = apify_client.actor('username/actor-name').start() + 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. @@ -15,6 +17,9 @@ def main() -> None: 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()