Skip to content

Commit c681f09

Browse files
Pijukatelvdusek
andauthored
docs: Add log redirection guide (#504)
### Description Add log redirection guide ### Issues - Relates to: [#632](apify/apify-client-js#632) --------- Co-authored-by: Vlada Dusek <v.dusek96@gmail.com>
1 parent f836526 commit c681f09

File tree

4 files changed

+69
-0
lines changed

4 files changed

+69
-0
lines changed

docs/03_concepts/10_logging.mdx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import CodeBlock from '@theme/CodeBlock';
77

88
import LogConfigExample from '!!raw-loader!./code/10_log_config.py';
99
import LoggerUsageExample from '!!raw-loader!./code/10_logger_usage.py';
10+
import RedirectLog from '!!raw-loader!./code/10_redirect_log.py';
11+
import RedirectLogExistingRun from '!!raw-loader!./code/10_redirect_log_existing_run.py';
1012

1113
The Apify SDK is logging useful information through the [`logging`](https://docs.python.org/3/library/logging.html) module from Python's standard library, into the logger with the name `apify`.
1214

@@ -82,3 +84,31 @@ Result:
8284
</pre>
8385

8486
<!-- markdownlint-enable no-inline-html -->
87+
88+
## Redirect logs from other Actor runs
89+
90+
In some situations, one Actor is going to start one or more other Actors and wait for them to finish and produce some results. In such cases, you might want to redirect the logs and status messages of the started Actors runs back to the parent Actor run, so that you can see the progress of the started Actors' runs in the parent Actor's logs. This guide will show possibilities on how to do it.
91+
92+
### Redirecting logs from Actor.call
93+
94+
Typical use case for log redirection is to call another Actor using the [`Actor.call`](../../reference/class/Actor#call) method. This method has an optional `logger` argument, which is by default set to the `default` literal. This means that the logs of the called Actor will be automatically redirected to the parent Actor's logs with default formatting and filtering. If you set the `logger` argument to `None`, then no log redirection happens. The third option is to pass your own `Logger` instance with the possibility to define your own formatter, filter, and handler. Below you can see those three possible ways of log redirection when starting another Actor run through [`Actor.call`](../../reference/class/Actor#call).
95+
96+
<CodeBlock className="language-python">
97+
{RedirectLog}
98+
</CodeBlock>
99+
100+
Each default redirect logger log entry will have a specific format. After the timestamp, it will contain cyan colored text that will contain the redirect information - the other actor's name and the run ID. The rest of the log message will be printed in the same manner as the parent Actor's logger is configured.
101+
102+
The log redirection can be deep, meaning that if the other actor also starts another actor and is redirecting logs from it, then in the top-level Actor, you can see it as well. See the following example screenshot of the Apify log console when one actor recursively starts itself (there are 2 levels of recursion in the example).
103+
104+
![Console with redirected logs](/img/guides/redirected_logs_example.webp 'Example of console with redirected logs from recursively started actor.')
105+
106+
### Redirecting logs from already running Actor run
107+
108+
In some cases, you might want to connect to an already running Actor run and redirect its logs to your current Actor run. This can be done using the [ApifyClient](../../reference/class/Actor#apify_client) and getting the streamed log from a specific Actor run. You can then use it as a context manager, and the log redirection will be active in the context, or you can control the log redirection manually by explicitly calling `start` and `stop` methods.
109+
110+
You can further decide whether you want to redirect just new logs of the ongoing Actor run, or if you also want to redirect historical logs from that Actor's run, so all logs it has produced since it was started. Both options are shown in the example code below.
111+
112+
<CodeBlock className="language-python">
113+
{RedirectLogExistingRun}
114+
</CodeBlock>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import logging
2+
3+
from apify import Actor
4+
5+
6+
async def main() -> None:
7+
async with Actor:
8+
# Default redirect logger
9+
await Actor.call(actor_id='some_actor_id')
10+
# No redirect logger
11+
await Actor.call(actor_id='some_actor_id', logger=None)
12+
# Custom redirect logger
13+
await Actor.call(
14+
actor_id='some_actor_id', logger=logging.getLogger('custom_logger')
15+
)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import asyncio
2+
3+
from apify import Actor
4+
5+
6+
async def main() -> None:
7+
async with Actor:
8+
# Lifecycle of redirected logs is handled by the context manager.
9+
async with await Actor.apify_client.run('some_actor_id').get_streamed_log(
10+
# Redirect all logs from the start of that run, even the logs from past.
11+
from_start=True
12+
):
13+
await asyncio.sleep(5)
14+
# Logging will stop out of context
15+
16+
# Lifecycle of redirected logs can be handled manually.
17+
streamed_log = await Actor.apify_client.run('some_id').get_streamed_log(
18+
# Do not redirect historical logs from this actor run.
19+
# Redirect only new logs from now on.
20+
from_start=False
21+
)
22+
streamed_log.start()
23+
await asyncio.sleep(5)
24+
await streamed_log.stop()
Binary file not shown.

0 commit comments

Comments
 (0)