Skip to content

Commit 1387fbd

Browse files
authored
Change_log_level (temporalio#187)
added a sample showing how change workflow task failure log levels to error
1 parent dc1ad01 commit 1387fbd

File tree

4 files changed

+112
-0
lines changed

4 files changed

+112
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ Some examples require extra dependencies. See each sample's directory for specif
4141
* [hello_async_activity_completion](hello/hello_async_activity_completion.py) - Complete an activity outside of the
4242
function that was called.
4343
* [hello_cancellation](hello/hello_cancellation.py) - Manually react to cancellation inside workflows and activities.
44+
* [hello_change_log_level](hello/hello_change_log_level.py) - Change the level of workflow task failure from WARN to ERROR.
4445
* [hello_child_workflow](hello/hello_child_workflow.py) - Execute a child workflow from a workflow.
4546
* [hello_continue_as_new](hello/hello_continue_as_new.py) - Use continue as new to restart a workflow.
4647
* [hello_cron](hello/hello_cron.py) - Execute a workflow once a minute.

hello/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Replace `hello_activity.py` in the command with any other example filename to ru
2828
* [hello_async_activity_completion](hello_async_activity_completion.py) - Complete an activity outside of the function
2929
that was called.
3030
* [hello_cancellation](hello_cancellation.py) - Manually react to cancellation inside workflows and activities.
31+
* [hello_change_log_level](hello_change_log_level.py) - Change the level of workflow task failure from WARN to ERROR.
3132
* [hello_child_workflow](hello_child_workflow.py) - Execute a child workflow from a workflow.
3233
* [hello_continue_as_new](hello_continue_as_new.py) - Use continue as new to restart a workflow.
3334
* [hello_cron](hello_cron.py) - Execute a workflow once a minute.

hello/hello_change_log_level.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
"""
2+
Changes the log level of workflow task failures from WARN to ERROR.
3+
4+
Note that the __temporal_error_identifier attribute was added in
5+
version 1.13.0 of the Python SDK.
6+
"""
7+
8+
import asyncio
9+
import logging
10+
import sys
11+
12+
from temporalio import workflow
13+
from temporalio.client import Client
14+
from temporalio.worker import Worker
15+
16+
# --- Begin logging set‑up ----------------------------------------------------------
17+
logging.basicConfig(
18+
stream=sys.stdout,
19+
level=logging.INFO,
20+
format="%(asctime)s %(levelname)-8s %(name)s %(message)s",
21+
)
22+
23+
24+
class CustomLogFilter(logging.Filter):
25+
def filter(self, record: logging.LogRecord) -> bool:
26+
# Note that the __temporal_error_identifier attribute was added in
27+
# version 1.13.0 of the Python SDK.
28+
if (
29+
hasattr(record, "__temporal_error_identifier")
30+
and getattr(record, "__temporal_error_identifier") == "WorkflowTaskFailure"
31+
):
32+
record.levelno = logging.ERROR
33+
record.levelname = logging.getLevelName(logging.ERROR)
34+
return True
35+
36+
37+
for h in logging.getLogger().handlers:
38+
h.addFilter(CustomLogFilter())
39+
# --- End logging set‑up ----------------------------------------------------------
40+
41+
42+
LOG_MESSAGE = "This error is an experiment to check the log level"
43+
44+
45+
@workflow.defn
46+
class GreetingWorkflow:
47+
@workflow.run
48+
async def run(self):
49+
raise RuntimeError(LOG_MESSAGE)
50+
51+
52+
async def main():
53+
client = await Client.connect("localhost:7233")
54+
async with Worker(
55+
client,
56+
task_queue="hello-change-log-level-task-queue",
57+
workflows=[GreetingWorkflow],
58+
):
59+
await client.execute_workflow(
60+
GreetingWorkflow.run,
61+
id="hello-change-log-level-workflow-id",
62+
task_queue="hello-change-log-level-task-queue",
63+
)
64+
65+
66+
if __name__ == "__main__":
67+
asyncio.run(main())
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import asyncio
2+
import io
3+
import logging
4+
import uuid
5+
6+
from temporalio.client import Client
7+
from temporalio.worker import Worker
8+
9+
from hello.hello_change_log_level import LOG_MESSAGE, GreetingWorkflow
10+
11+
12+
async def test_workflow_with_log_capture(client: Client):
13+
14+
log_stream = io.StringIO()
15+
handler = logging.StreamHandler(log_stream)
16+
handler.setLevel(logging.ERROR)
17+
18+
logger = logging.getLogger()
19+
logger.addHandler(handler)
20+
logger.setLevel(logging.DEBUG)
21+
22+
task_queue = f"tq-{uuid.uuid4()}"
23+
24+
async with Worker(
25+
client,
26+
task_queue=task_queue,
27+
workflows=[GreetingWorkflow],
28+
):
29+
handle = await client.start_workflow(
30+
GreetingWorkflow.run,
31+
id=f"wf-{uuid.uuid4()}",
32+
task_queue=task_queue,
33+
)
34+
await asyncio.sleep(
35+
0.2
36+
) # small wait to ensure the workflow has started, failed, and logged
37+
await handle.terminate()
38+
39+
logger.removeHandler(handler)
40+
handler.flush()
41+
42+
logs = log_stream.getvalue()
43+
assert LOG_MESSAGE in logs

0 commit comments

Comments
 (0)