Volver a la wiki

Incidente: agent.log se quedaba mudo tras arrancar uvicorn (Local Agent, hasta v2.23.0)

Cuándo

Detectado y arreglado el 27-08-2026 (task #269, PR #444, commit a59375ab), publicado como Local Agent 2.23.1 (v1.85.7 del SaaS). El bug llevaba activo desde el rewrite del Agente a la versión 2.0 — es decir, meses de logs silenciosamente incompletos en toda la flota, no un caso aislado.

Síntomas visibles

El fichero agent.log que el Local Agent escribe en su carpeta de instalación solo contenía las dos líneas previas al arranque del servidor web interno (uvicorn) y nada más: ni los sondeos periódicos, ni la purga/VACUUM semanal de la base de datos SQLite local, ni los errores de la conexión WebSocket con el SaaS quedaban registrados en disco. Esa información solo vivía en el buffer de memoria de la Debug Console (los últimos 500 mensajes, ws://localhost:5050/ws/debug), que se perdía al cerrar la consola o reiniciar el Agente. Ningún dato de monitorización enviado al SaaS se vio afectado — el problema era puramente de trazabilidad para diagnóstico.

Explica retroactivamente por qué el “TimeoutError mudo” de la task #223 nunca dejó rastro en el log: el error ocurría después del arranque de uvicorn, momento en el que el fichero ya había dejado de escribir.

Causa raíz

terminal/agent/app_main.py arrancaba el servidor con uvicorn.run(app, host="127.0.0.1", port=PORT, log_level="error"). Sin log_config explícito, uvicorn aplica su LOGGING_CONFIG por defecto vía logging.config.dictConfig, que cierra todos los handlers del logger raíz existentes antes de reconfigurarlo. El Agente abre su FileHandler en modo "w" (sobrescribir en cada arranque); una vez que dictConfig lo cierra, Python no lo vuelve a abrir — es un comportamiento documentado de la librería estándar (CPython issue #42378), no un fallo de uvicorn. A partir de ahí, cada logger.info(...) posterior al uvicorn.run(...) se descartaba en silencio: sin excepción, sin warning.

Fix aplicado

Commit a59375ab (PR #444, task #269): una línea en terminal/agent/app_main.py — uvicorn.run(app, host="127.0.0.1", port=PORT, log_level="error", log_config=None). Con log_config=None, uvicorn no toca la configuración global de logging; el FileHandler del Agente sigue vivo, y log_level="error" se sigue aplicando igual a los loggers propios de uvicorn (uvicorn.error, uvicorn.access).

Cambios acompañantes:

Lecciones

Preventivos futuros

Véase también

Subir