Skip to content

Commit d329c66

Browse files
committed
Throttle hardware-trigger wait logs
Reduce log flooding when waiting for hardware triggers by adding throttled logging. Changes in dlclivegui/services/multi_camera_controller.py: - Import time. - Add a new _log_interval_while_waiting_for_trigger_s attribute to SingleCameraWorker. - Replace the direct LOGGER.debug call for expected trigger wait timeouts with a call to _log_trigger_wait_throttled. - Implement _log_trigger_wait_throttled to suppress repeated timeout messages, emit a consolidated debug message, and report how many repeated logs were suppressed. This prevents high-frequency expected poll-timeout logs (common in trigger-waiting modes) from overwhelming the logs.
1 parent 17211a8 commit d329c66

1 file changed

Lines changed: 33 additions & 5 deletions

File tree

dlclivegui/services/multi_camera_controller.py

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import copy
66
import logging
7+
import time
78
from dataclasses import dataclass
89
from functools import partial
910
from threading import Event, Lock
@@ -55,6 +56,7 @@ def __init__(self, camera_id: str, settings: CameraSettings):
5556
self._max_consecutive_errors = 5
5657
self._retry_delay = 0.1
5758
self._trigger_timeout_delay = 0.05
59+
self._log_interval_while_waiting_for_trigger_s = 2.0
5860

5961
# Performance logs
6062
self._timing = WorkerTimingStats(
@@ -126,11 +128,7 @@ def run(self) -> None:
126128
# "no trigger pulse arrived during this poll interval".
127129
# This is expected and should not count as a camera failure.
128130
if bool(getattr(self._backend, "waits_for_hardware_trigger", False)):
129-
LOGGER.debug(
130-
"[Worker %s] waiting for hardware trigger: %s",
131-
self._camera_id,
132-
exc,
133-
)
131+
self._log_trigger_wait_throttled(exc)
134132
consecutive_errors = 0
135133

136134
if self._stop_event.wait(self._trigger_timeout_delay):
@@ -285,6 +283,36 @@ def _timing_for_camera(self, camera_id: str) -> WorkerTimingStats:
285283
self._timing_per_cam[camera_id] = timing
286284
return timing
287285

286+
def _log_trigger_wait_throttled(self, exc: BaseException) -> None:
287+
"""Log hardware-trigger wait timeouts at a controlled rate.
288+
289+
In trigger-waiting modes, read timeouts are expected polling misses.
290+
Without throttling, the log can be flooded at ~10-20 messages/sec/camera.
291+
"""
292+
now = time.monotonic()
293+
294+
if now - self._last_trigger_wait_log < self._trigger_wait_log_interval:
295+
self._trigger_wait_suppressed_count += 1
296+
return
297+
298+
suppressed = self._trigger_wait_suppressed_count
299+
self._trigger_wait_suppressed_count = 0
300+
self._last_trigger_wait_log = now
301+
302+
if suppressed:
303+
LOGGER.debug(
304+
"[Worker %s] waiting for hardware trigger: %s (suppressed %d repeated timeout logs)",
305+
self._camera_id,
306+
exc,
307+
suppressed,
308+
)
309+
else:
310+
LOGGER.debug(
311+
"[Worker %s] waiting for hardware trigger: %s",
312+
self._camera_id,
313+
exc,
314+
)
315+
288316
def start(self, camera_settings: list[CameraSettings]) -> None:
289317
"""Start multiple cameras."""
290318
if self._running:

0 commit comments

Comments
 (0)