Los errores en producción difieren de los fallos locales: la forma del tráfico, el volumen de datos y la configuración del entorno ocultan problemas que tu portátil nunca ve. Los logs estructurados, las trazas distribuidas y el perfilado seguro en vivo cierran esa brecha sin reinicios arriesgados.
# Muestra de pila en vivo (sin reinicio, necesita ptrace o CAP_SYS_PTRACE)py-spy top --pid $(pgrep -f "gunicorn.*api:app")py-spy dump --pid <pid> --lines 50
Cuándo recurrir a esto:
Picos en la tasa de errores sin una correlación obvia con un despliegue
La latencia aumenta pero la CPU parece inactiva (GIL o espera de I/O)
El problema aparece solo para un inquilino o región
La reproducción local falla después de igualar la versión de Python y las variables de entorno
# Habilita faulthandler al inicio para cuelgues nativosimport faulthandlerfaulthandler.enable()# Depuración temporal en un solo pod (nunca cometer)import logginglogging.getLogger("sqlalchemy.engine").setLevel(logging.INFO)
Reiniciar pods antes de capturar logs - Pierdes el estado en memoria y la evidencia de la pila. Solución: Captura logs, py-spy dump y métricas de heap primero.
IDs de correlación faltantes - Miles de errores idénticos no se pueden buscar. Solución: Requiere request_id/trace_id en el middleware antes de que se ejecuten los manejadores.
Depurar con nivel DEBUG globalmente - El volumen de logs explota y se filtran PII. Solución: Sube el nivel en un pod o usa muestreo dinámico.
Asumir que local == prod - Diferentes PYTHONHASHSEED, locale o pines de dependencias cambian el comportamiento. Solución: Coincide con el digest de la imagen y el entorno en un entorno de preparación.
Bloquear el bucle de eventos en aplicaciones asíncronas - Las llamadas síncronas a ORM detienen todas las solicitudes; la CPU parece baja. Solución: Comprueba las líneas de tiempo de las trazas en busca de segmentos síncronos largos; mueve las I/O fuera del bucle.
Usa plataformas de logs, APM y kubectl exec/ecs exec solo en un único pod canario. Prefiere scripts de py-spy y env-print registrados en el repositorio sobre ediciones ad hoc.
¿Debo habilitar Python -X dev en producción?
No. El modo de desarrollo añade comprobaciones y advertencias costosas. Usa staging con -X dev y mantén producción con logging ajustado y sondas de salud.
¿Cuál es la primera consulta en un incidente?
Filtra errores por servicio y git_sha de las últimas dos horas, luego pivota en trace_id de la solicitud exitosa más lenta para contrastar.
¿Cómo rastreo una tarea Celery?
Pasa trace_id en los kwargs de la tarea y vincula structlog contextvars en la clase base de la tarea. Vincula los logs del worker a los logs de la API a través del mismo ID.
¿Cuándo no es suficiente py-spy?
Cuando el proceso está bloqueado en código nativo sin marcos de Python, o durante el inicio antes de que los workers se vinculen. Empareja con eBPF o perfilado nativo de APM.
¿Puedo usar pprint en producción?
Solo detrás de un feature flag y un límite de tasa. Prefiere campos estructurados para que los dashboards puedan agregar.
¿Cómo comparo las configuraciones de staging y producción?
Exporta claves de entorno redactadas (solo nombres) y diferencia tamaños de pool, valores de tiempo de espera y feature flags. Nunca pegues secretos en tickets.
¿Qué pasa con el Python 3.14 con hilos libres (free-threaded)?
Los bloqueos relacionados con GIL disminuyen, pero la I/O y la contención de bloqueos permanecen. py-spy todavía ayuda; observa los puntos críticos de threading.Lock en las métricas.
¿Cuánto tiempo debo mantener el logging de depuración activado?
Minutos para un pod. Revierte inmediatamente después de la captura; documenta los hallazgos en el canal de incidentes.
¿Quién debe ser el responsable de la depuración en producción?
El ingeniero de guardia impulsa la evidencia; el propietario del servicio interpreta la lógica del dominio. No depures en solitario un SEV1 sin un comandante de incidentes.