5 minute read

Esta semana me he centrado en desarrollar e integrar un sistema de monitorización autónoma para el servidor central de Unibotics. El objetivo ha sido implementar un mecanismo que permita recopilar periódicamente información sobre el rendimiento del hardware del servidor y la actividad de los usuarios en la plataforma.

Para ello, se ha desarrollado un módulo encargado de obtener métricas de uso de CPU y memoria RAM, así como de contabilizar los usuarios que mantienen sesiones activas. Toda esta información se almacena de forma persistente en una base de datos PostgreSQL, permitiendo disponer de un registro histórico del estado del servidor.

Además, se ha automatizado el proceso de recopilación mediante un planificador de tareas en segundo plano, de manera que las métricas se actualizan automáticamente cada cinco minutos sin necesidad de intervención manual.

Archivos involucrados

  • Backend:
    • apps/academy/models/...
    • apps/academy/metrics.py
    • apps/academy/apps.py
  • Dependencias: utils/requirements.txt.
  • Migraciones de Django: academy.0008_servermonitorprobe.

Implementación del modelo de datos

El primer paso ha sido definir una estructura persistente para almacenar las métricas recopiladas por el sistema de monitorización.

Para ello, se ha creado el modelo ServerMonitorProbe, encargado de representar cada evento de sondeo realizado sobre el servidor. Este modelo permite almacenar los siguientes datos:

  • created_at: marca temporal que indica cuándo se ha realizado la recopilación de las métricas.
  • cpu_percent: porcentaje de utilización de la CPU.
  • ram_percent: porcentaje de memoria RAM utilizada.
  • ram_used_mb: cantidad de memoria RAM consumida, expresada en megabytes.
  • active_users: número de usuarios activos en la plataforma en el momento del sondeo.

La información se almacena en PostgreSQL, proporcionando un registro histórico que permite consultar y analizar la evolución del rendimiento del servidor y la actividad de los usuarios.

Una vez definido el modelo, se ha generado y aplicado la migración de Django academy.0008_servermonitorprobe, incorporando la nueva estructura a la base de datos.

Recolección de métricas del sistema

La lógica principal de recopilación se ha desarrollado en el fichero apps/academy/metrics.py, utilizando la librería psutil para obtener información sobre los recursos hardware del servidor.

Se ha implementado la función get_system_metrics(), encargada de consultar el estado de la CPU y la memoria RAM. Esta función incorpora un mecanismo de detección adaptativo de las rutas del sistema, permitiendo que la monitorización funcione correctamente tanto en producción como en desarrollo.

En particular, se contemplan dos escenarios:

  1. Entorno de producción: cuando la aplicación se ejecuta dentro de un contenedor, se utilizan las rutas disponibles a través de /host/proc, permitiendo consultar las métricas del sistema anfitrión.
  2. Entorno de desarrollo: cuando se ejecuta localmente, se utiliza por defecto la ruta /proc para acceder a la información del sistema.

Esta adaptación permite obtener métricas del servidor real en los despliegues basados en contenedores, evitando limitar la monitorización únicamente a los recursos visibles desde el entorno aislado de la aplicación.

De esta forma, se consigue una implementación compatible con los diferentes entornos de ejecución sin necesidad de modificar manualmente la configuración de las rutas.

Conteo de usuarios activos

Además de las métricas de hardware, se ha incorporado un mecanismo para conocer cuántos usuarios mantienen actividad reciente en la plataforma.

Para ello, se ha desarrollado la función get_active_users_count(), que utiliza el gestor nativo de sesiones de Django (Session) para consultar las sesiones almacenadas en la base de datos.

El criterio utilizado consiste en filtrar aquellas sesiones cuya fecha de expiración sea igual o posterior al momento actual, mediante la condición expire_date__gte=now.

De esta manera, únicamente se contabilizan las sesiones que todavía se encuentran vigentes, obteniendo una aproximación del número de usuarios únicos con actividad reciente en Unibotics.

Esta solución permite aprovechar el sistema de sesiones que ya proporciona Django, evitando implementar mecanismos adicionales de seguimiento de usuarios.

Automatización de la monitorización

Una vez implementada la lógica de recopilación, el siguiente paso ha sido automatizar su ejecución para que el servidor registre sus métricas de forma periódica.

Para ello, se ha integrado APScheduler, concretamente mediante la clase BackgroundScheduler, dentro del ciclo de inicialización de la aplicación Django.

La configuración se ha realizado en el fichero apps/academy/apps.py, dentro del método AcademyConfig.ready(), que se ejecuta durante el proceso de inicialización de la aplicación.

Se ha programado una tarea automática que ejecuta el proceso de monitorización cada cinco minutos. De esta forma, el sistema obtiene periódicamente los datos de CPU, memoria RAM y usuarios activos, sin necesidad de realizar consultas manuales.

Además, se ha incorporado una protección mediante la variable de entorno RUN_MAIN para evitar que se creen múltiples planificadores durante las recargas automáticas del servidor en el entorno de desarrollo.

Esta precaución resulta especialmente importante porque Django puede iniciar procesos adicionales durante la recarga del código. Sin esta comprobación, podrían generarse varios hilos de ejecución y, en consecuencia, duplicarse los eventos de monitorización.

Integración y almacenamiento de las métricas

Para centralizar el proceso completo se ha desarrollado la función dispatch_monitor_event(), que actúa como orquestador del sistema de monitorización.

Su responsabilidad consiste en coordinar la obtención de las métricas del hardware y el conteo de usuarios activos para posteriormente almacenar los resultados mediante el modelo ServerMonitorProbe.

De esta manera, el proceso queda organizado en diferentes responsabilidades:

  1. Obtención de métricas: get_system_metrics() consulta los porcentajes de utilización de CPU y RAM, así como la memoria consumida.
  2. Conteo de usuarios: get_active_users_count() obtiene el número de sesiones que continúan vigentes.
  3. Centralización del proceso: dispatch_monitor_event() reúne la información obtenida y prepara el registro correspondiente.
  4. Persistencia: se almacena un nuevo evento en PostgreSQL mediante el modelo ServerMonitorProbe.

Esta separación facilita el mantenimiento del código y permite modificar o ampliar las diferentes partes del sistema sin tener que concentrar toda la lógica en una única función.

Incorporación de dependencias

Para completar la integración, se han añadido las nuevas dependencias necesarias para el funcionamiento del módulo en el archivo utils/requirements.txt (o en el fichero de dependencias correspondiente).

Las dos librerías incorporadas son:

  • psutil: permite consultar información sobre el uso de los recursos del sistema, incluyendo CPU y memoria RAM.
  • apscheduler: proporciona la funcionalidad necesaria para programar y ejecutar tareas periódicas en segundo plano.

Con esta incorporación se garantiza que las dependencias utilizadas por el sistema de monitorización puedan instalarse correctamente durante los despliegues de la aplicación.

Resultado y conclusiones

Con esta implementación, Unibotics dispone de un sistema de monitorización autónoma del servidor central, capaz de recopilar y almacenar periódicamente información sobre el rendimiento del hardware y la actividad de los usuarios.

La integración de psutil permite obtener métricas de CPU y memoria RAM, mientras que el uso del gestor de sesiones de Django proporciona información sobre los usuarios activos. Por su parte, APScheduler automatiza la recopilación cada cinco minutos, eliminando la necesidad de ejecutar manualmente el proceso.

También se ha tenido en cuenta la compatibilidad entre los entornos de producción y desarrollo mediante la detección adaptativa de las rutas del sistema, así como la prevención de ejecuciones duplicadas durante la inicialización de Django.

Como resultado, se obtiene una infraestructura de monitorización integrada en el backend, con almacenamiento persistente en PostgreSQL y una arquitectura modular que permite ampliar las métricas recopiladas en el futuro.

Esta funcionalidad supone un primer paso para disponer de información histórica sobre el comportamiento del servidor central, facilitando futuras tareas de análisis, supervisión del rendimiento y detección de posibles problemas de capacidad o disponibilidad.