add logging

This commit is contained in:
awe
2026-01-29 17:05:47 +03:00
parent 23cff76dd2
commit 508c835368

View File

@ -222,10 +222,11 @@ class SerialLineSource:
class SerialChunkReader:
"""Быстрое неблокирующее чтение чанков из serial/raw TTY для максимального дренажа буфера."""
def __init__(self, src: SerialLineSource):
def __init__(self, src: SerialLineSource, error_counter: Optional[list] = None):
self._src = src
self._ser = src._pyserial
self._fd: Optional[int] = None
self._error_counter = error_counter # Список с 1 элементом для передачи по ссылке
if self._ser is not None:
# Неблокирующий режим для быстрой откачки
try:
@ -248,11 +249,15 @@ class SerialChunkReader:
try:
n = int(getattr(self._ser, "in_waiting", 0))
except Exception:
if self._error_counter:
self._error_counter[0] += 1
n = 0
if n > 0:
try:
return self._ser.read(n)
except Exception:
if self._error_counter:
self._error_counter[0] += 1
return b""
return b""
if self._fd is None:
@ -269,6 +274,8 @@ class SerialChunkReader:
except BlockingIOError:
break
except Exception:
if self._error_counter:
self._error_counter[0] += 1
break
return bytes(out)
@ -297,6 +304,12 @@ class SweepReader(threading.Thread):
self._n_valid_hist = deque()
# Счетчик потерь данных (выброшенных свипов из-за переполнения очереди)
self._dropped_sweeps: int = 0
# Диагностика потери точек внутри свипа
self._total_lines_received: int = 0 # Всего принято строк с данными
self._total_parse_errors: int = 0 # Ошибок парсинга строк
self._total_empty_lines: int = 0 # Пустых строк
self._max_buf_size: int = 0 # Максимальный размер буфера парсинга
self._read_errors: int = 0 # Ошибок чтения из порта
def _finalize_current(self, xs, ys):
if not xs:
@ -381,6 +394,10 @@ class SweepReader(threading.Thread):
"std": std,
"dt_ms": dt_ms,
"dropped": self._dropped_sweeps,
"lines": self._total_lines_received,
"parse_err": self._total_parse_errors,
"read_err": self._read_errors,
"max_buf": self._max_buf_size,
}
# Кладём готовый свип (если очередь полна — выбрасываем самый старый)
@ -412,12 +429,19 @@ class SweepReader(threading.Thread):
try:
# Быстрый неблокирующий дренаж порта с разбором по байтам
chunk_reader = SerialChunkReader(self._src)
# Передаем счетчик ошибок чтения как список для изменения по ссылке
error_counter = [0]
chunk_reader = SerialChunkReader(self._src, error_counter)
buf = bytearray()
while not self._stop.is_set():
data = chunk_reader.read_available()
# Обновляем счетчик ошибок чтения
self._read_errors = error_counter[0]
if data:
buf += data
# Отслеживаем максимальный размер буфера парсинга
if len(buf) > self._max_buf_size:
self._max_buf_size = len(buf)
else:
# Короткая уступка CPU, если нет новых данных (уменьшена до 0.1ms)
time.sleep(0.0001)
@ -433,6 +457,7 @@ class SweepReader(threading.Thread):
if line.endswith(b"\r"):
line = line[:-1]
if not line:
self._total_empty_lines += 1
continue
if line.startswith(b"Sweep_start"):
@ -449,9 +474,17 @@ class SweepReader(threading.Thread):
x = int(parts[1], 10)
y = int(parts[2], 10) # поддержка знака: "+…" и "-…"
except Exception:
self._total_parse_errors += 1
continue
xs.append(x)
ys.append(y)
self._total_lines_received += 1
else:
# Строка не в формате "s X Y"
self._total_parse_errors += 1
else:
# Строка слишком короткая
self._total_parse_errors += 1
# Защита от переполнения буфера при отсутствии переводов строки (снижен порог)
if len(buf) > 262144: