Оценка разделения больше не роняет задачу, журнал доступен через API

Полный трейс показал настоящую причину сбоя: падало не распознавание,
а метрика separation_quality из 0.5.0 - она скармливала модели отпечатков
реплики целиком, и на 190-секундной та не выдержала. Теперь берётся кусок
из середины реплики, а сбой оценки лишь обнуляет её, не трогая расшифровку.

Добавлен /v1/logs: последние записи журнала с фильтром по уровню, чтобы
разбирать сбои без копирования консоли вручную.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Vladimir Bryzgalov
2026-08-15 23:44:09 +05:00
co-authored by Claude Opus 5
parent f2f266ba1c
commit 710fc8b90b
6 changed files with 174 additions and 7 deletions
+19
View File
@@ -16,6 +16,8 @@ from fastapi.responses import JSONResponse
from fastapi.security import HTTPBearer
from app.config import Settings, load_settings
from app.logbuffer import get as log_buffer
from app.logbuffer import install as install_log_buffer
from app.pipeline import ModelsMissing, Pipeline, to_wav16k
from app.security import check_token, ip_allowed, parse_allowlist
from app.store import JobStatus, JobStore
@@ -211,6 +213,22 @@ def openapi_schema(request: Request) -> JSONResponse:
return JSONResponse(schema)
@app.get("/v1/logs", dependencies=[Depends(guard)], summary="Журнал сервиса",
description="Последние записи журнала: удобно посмотреть причину сбоя, "
"не заходя на машину. Уровень можно отфильтровать параметром level.")
def logs(limit: int = Query(100, ge=1, le=500),
level: str | None = Query(None, description="INFO, WARNING или ERROR")) -> dict:
rows = log_buffer().tail(limit=limit, level=level)
return {
"count": len(rows),
"records": [
{"time": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(r["time"])),
"level": r["level"], "logger": r["logger"], "message": r["message"]}
for r in rows
],
}
@app.get("/health", summary="Состояние сервиса",
description="Единственный метод без токена - годится для мониторинга. "
"Показывает версию, очередь, число потоков и то, каким сервис "
@@ -342,6 +360,7 @@ def run() -> None:
import uvicorn
_setup_console()
install_log_buffer()
logging.basicConfig(level=logging.INFO,
format="%(asctime)s %(levelname)s %(name)s: %(message)s")