2222)
2323from temporalio .worker import Worker
2424from tests .helpers import (
25+ LogHandler ,
2526 assert_eq_eventually ,
2627 assert_eventually ,
2728 find_free_port ,
@@ -80,8 +81,8 @@ async def test_runtime_log_forwarding():
8081 # Create logger with record capture
8182 log_queue : queue .Queue [logging .LogRecord ] = queue .Queue ()
8283 log_queue_list = cast (list [logging .LogRecord ], log_queue .queue )
84+ handler = logging .handlers .QueueHandler (log_queue )
8385 logger = logging .getLogger (f"log-{ uuid .uuid4 ()} " )
84- logger .addHandler (logging .handlers .QueueHandler (log_queue ))
8586
8687 async def log_queue_len () -> int :
8788 return len (log_queue_list )
@@ -96,49 +97,50 @@ async def log_queue_len() -> int:
9697 )
9798 )
9899
99- # Set capture only info logs
100- logger .setLevel (logging .INFO )
101- # Write some logs
102- runtime ._core_runtime .write_test_info_log ("info1" , "extra1" )
103- runtime ._core_runtime .write_test_debug_log ("debug2" , "extra2" )
104- runtime ._core_runtime .write_test_info_log ("info3" , "extra3" )
105-
106- # Check the expected records
107- await assert_eq_eventually (2 , log_queue_len )
108- assert log_queue_list [0 ].levelno == logging .INFO
109- assert log_queue_list [0 ].message .startswith (
110- "[sdk_core::temporal_sdk_bridge::runtime] info1"
111- )
112- assert (
113- log_queue_list [0 ].name
114- == f"{ logger .name } -sdk_core::temporal_sdk_bridge::runtime"
115- )
116- assert log_queue_list [0 ].created == log_queue_list [0 ].temporal_log .time # type: ignore
117- assert log_queue_list [0 ].temporal_log .fields == {"extra_data" : "extra1" } # type: ignore
118- assert log_queue_list [1 ].levelno == logging .INFO
119- assert log_queue_list [1 ].message .startswith (
120- "[sdk_core::temporal_sdk_bridge::runtime] info3"
121- )
100+ with LogHandler .apply (logger , handler ):
101+ # Set capture only info logs
102+ logger .setLevel (logging .INFO )
103+ # Write some logs
104+ runtime ._core_runtime .write_test_info_log ("info1" , "extra1" )
105+ runtime ._core_runtime .write_test_debug_log ("debug2" , "extra2" )
106+ runtime ._core_runtime .write_test_info_log ("info3" , "extra3" )
107+
108+ # Check the expected records
109+ await assert_eq_eventually (2 , log_queue_len )
110+ assert log_queue_list [0 ].levelno == logging .INFO
111+ assert log_queue_list [0 ].message .startswith (
112+ "[sdk_core::temporal_sdk_bridge::runtime] info1"
113+ )
114+ assert (
115+ log_queue_list [0 ].name
116+ == f"{ logger .name } -sdk_core::temporal_sdk_bridge::runtime"
117+ )
118+ assert log_queue_list [0 ].created == log_queue_list [0 ].temporal_log .time # type: ignore
119+ assert log_queue_list [0 ].temporal_log .fields == {"extra_data" : "extra1" } # type: ignore
120+ assert log_queue_list [1 ].levelno == logging .INFO
121+ assert log_queue_list [1 ].message .startswith (
122+ "[sdk_core::temporal_sdk_bridge::runtime] info3"
123+ )
122124
123- # Clear logs and enable debug and try again
124- log_queue_list .clear ()
125- logger .setLevel (logging .DEBUG )
126- runtime ._core_runtime .write_test_info_log ("info4" , "extra4" )
127- runtime ._core_runtime .write_test_debug_log ("debug5" , "extra5" )
128- runtime ._core_runtime .write_test_info_log ("info6" , "extra6" )
129- await assert_eq_eventually (3 , log_queue_len )
130- assert log_queue_list [0 ].levelno == logging .INFO
131- assert log_queue_list [0 ].message .startswith (
132- "[sdk_core::temporal_sdk_bridge::runtime] info4"
133- )
134- assert log_queue_list [1 ].levelno == logging .DEBUG
135- assert log_queue_list [1 ].message .startswith (
136- "[sdk_core::temporal_sdk_bridge::runtime] debug5"
137- )
138- assert log_queue_list [2 ].levelno == logging .INFO
139- assert log_queue_list [2 ].message .startswith (
140- "[sdk_core::temporal_sdk_bridge::runtime] info6"
141- )
125+ # Clear logs and enable debug and try again
126+ log_queue_list .clear ()
127+ logger .setLevel (logging .DEBUG )
128+ runtime ._core_runtime .write_test_info_log ("info4" , "extra4" )
129+ runtime ._core_runtime .write_test_debug_log ("debug5" , "extra5" )
130+ runtime ._core_runtime .write_test_info_log ("info6" , "extra6" )
131+ await assert_eq_eventually (3 , log_queue_len )
132+ assert log_queue_list [0 ].levelno == logging .INFO
133+ assert log_queue_list [0 ].message .startswith (
134+ "[sdk_core::temporal_sdk_bridge::runtime] info4"
135+ )
136+ assert log_queue_list [1 ].levelno == logging .DEBUG
137+ assert log_queue_list [1 ].message .startswith (
138+ "[sdk_core::temporal_sdk_bridge::runtime] debug5"
139+ )
140+ assert log_queue_list [2 ].levelno == logging .INFO
141+ assert log_queue_list [2 ].message .startswith (
142+ "[sdk_core::temporal_sdk_bridge::runtime] info6"
143+ )
142144
143145
144146@workflow .defn
@@ -152,8 +154,8 @@ async def test_runtime_task_fail_log_forwarding(client: Client):
152154 # Client with lo capturing runtime
153155 log_queue : queue .Queue [logging .LogRecord ] = queue .Queue ()
154156 log_queue_list = cast (list [logging .LogRecord ], log_queue .queue )
157+ handler = logging .handlers .QueueHandler (log_queue )
155158 logger = logging .getLogger (f"log-{ uuid .uuid4 ()} " )
156- logger .addHandler (logging .handlers .QueueHandler (log_queue ))
157159 logger .setLevel (logging .WARN )
158160 client = await Client .connect (
159161 client .service_client .config .target_host ,
@@ -168,30 +170,32 @@ async def test_runtime_task_fail_log_forwarding(client: Client):
168170 ),
169171 )
170172
171- # Start workflow
172- task_queue = f"task-queue-{ uuid .uuid4 ()} "
173- async with Worker (client , task_queue = task_queue , workflows = [TaskFailWorkflow ]):
174- handle = await client .start_workflow (
175- TaskFailWorkflow .run ,
176- id = f"workflow-{ uuid .uuid4 ()} " ,
177- task_queue = task_queue ,
178- )
179-
180- # Wait for log to appear
181- async def has_log () -> bool :
182- return any (
183- l for l in log_queue_list if "Failing workflow task" in l .message
173+ with LogHandler .apply (logger , handler ):
174+ # Start workflow
175+ task_queue = f"task-queue-{ uuid .uuid4 ()} "
176+ async with Worker (client , task_queue = task_queue , workflows = [TaskFailWorkflow ]):
177+ handle = await client .start_workflow (
178+ TaskFailWorkflow .run ,
179+ id = f"workflow-{ uuid .uuid4 ()} " ,
180+ task_queue = task_queue ,
184181 )
185182
186- await assert_eq_eventually (True , has_log )
183+ # Wait for log to appear
184+ async def has_log () -> bool :
185+ return any (
186+ l for l in log_queue_list if "Failing workflow task" in l .message
187+ )
187188
188- # Check record
189- record = next (l for l in log_queue_list if "Failing workflow task" in l .message )
190- assert record .levelno == logging .WARNING
191- assert (
192- record .name == f"{ logger .name } -sdk_core::temporalio_sdk_core::worker::workflow"
193- )
194- assert record .temporal_log .fields ["run_id" ] == handle .result_run_id # type: ignore
189+ await assert_eq_eventually (True , has_log )
190+
191+ # Check record
192+ record = next (l for l in log_queue_list if "Failing workflow task" in l .message )
193+ assert record .levelno == logging .WARNING
194+ assert (
195+ record .name
196+ == f"{ logger .name } -sdk_core::temporalio_sdk_core::worker::workflow"
197+ )
198+ assert record .temporal_log .fields ["run_id" ] == handle .result_run_id # type: ignore
195199
196200
197201async def test_prometheus_histogram_bucket_overrides (client : Client ):
0 commit comments