Ir al contenido principal
Todas las coleccionesTutoriales de proyectos IoT
Construyendo un Monitor de Sistema Multiplataforma con Ubidots
Construyendo un Monitor de Sistema Multiplataforma con Ubidots

Construya un monitor de sistema multiplataforma en minutos. Reciba notificaciones cuando la CPU esté alta o cuando el espacio en disco libre sea bajo.

Sergio M avatar
Escrito por Sergio M
Actualizado hace más de 2 meses

Los monitores del sistema son herramientas que informan sobre los recursos y el rendimiento de un sistema informático determinado. Los puntos de datos sobre la CPU, la memoria y el disco duro son comunes en los monitores del sistema. Pero, ¿qué utilidad tienen estas variables? En un sistema de producción, las mediciones de estas variables proporcionan información crítica sobre cómo se está ejecutando tu código y qué tan bien la máquina lo está manejando. Los informes pueden llevar a diagnósticos de software sobre fugas de memoria, necesidad de hardware más rápido y causas detrás de operaciones de E/S fallidas.

Con el módulo psutil en Python, obtenemos una interfaz simple multiplataforma entre Python y el sistema para acceder a una amplia gama de información del sistema. Al informar estos valores a la API de Ubidots a intervalos regulares, tendremos un método para visualizar y analizar estas estadísticas en la nube.

En esta publicación, pasaremos por el proceso de crear un script para monitorear el uso de la CPU, el uso de la memoria y el uso del disco duro en la nube con Ubidots. El script que estamos construyendo se puede descargar completo si prefieres no leerlo como un tutorial.

Escribiendo el script

Comencemos. Nuestro objetivo es crear un programa que use la fuente de datos “<hostname> Monitor” para informar los valores de tres variables: cpu_percent (porcentaje de CPU en uso), mem_percent (porcentaje de RAM en uso) y disk_percent (porcentaje de disco duro en uso). Para darle un poco de sabor al programa, buscaremos estas variables y la fuente de datos por nombre, y las crearemos solo si es necesario.

La primera parte de cualquier programa en Python es la línea shebang y una descripción del programa en un docstring. Proporcionar una buena descripción es una práctica saludable.

#!/usr/bin/python"""Estadísticas de Monitoreo a través de UbidotsEste script envía estadísticas de Uso de CPU, Memoria y Disco aUbidots para visualización y análisis. Este script es multiplataformay funcionará en Windows, Linux y OS X."""

Importamos cuatro módulos. Tomamos solo la función gethostname() del módulo socket, y solo la variable argv del módulo sys.

from socket import gethostnamefrom sys import argvimport psutilimport ubidots

Ahora definamos el método principal. El programa tomará un argumento de línea de comandos, que será la clave de API de Ubidots. La última línea a continuación instancia una instancia de ApiClient que usaremos para el resto del programa.

def main():    """Rutina principal para el script."""    if len(argv) != 2:        print "Uso: %s API_KEY" % argv[0]        return            api = ubidots.ApiClient(argv[1])

Ahora escribiremos algo de código para buscar la fuente de datos que coincida con el nombre deseado de nuestra fuente de datos: “<hostname> Monitor.” Si no existe tal fuente de datos, nos tomaremos el tiempo para crearla.

    ds_name = gethostname() + " Monitor"    ds = None    for cur_ds in api.get_datasources():        if cur_ds.name == ds_name:            ds = cur_ds            break    if ds is None:        ds = api.create_datasource({"name": ds_name})

Con nuestra variable ds creada, ahora seguiremos un patrón similar de buscar y crear si no se encuentra para cada una de las variables. Fuera de tu función principal, define esta función auxiliar:

def get_var_by_name(var_name, ds):    """Buscar una variable en una fuente de datos. Si se encuentra,    devuelve la variable. Si no se encuentra, devuelve None."""    for var in ds.get_variables():        if var.name == var_name:            return var    return None

De vuelta en la función principal:

var_cpu = get_var_by_name("cpu_percent", ds)    var_mem = get_var_by_name("mem_percent", ds)    var_disk = get_var_by_name("disk_percent", ds)        if var_cpu is None:        var_cpu = ds.create_variable({"name": "cpu_percent",                                      "unit": "%"})            if var_mem is None:        var_mem = ds.create_variable({"name": "mem_percent",                                      "unit": "%"})        if var_disk is None:        var_disk = ds.create_variable({"name": "disk_percent",                                       "unit": "%"})

Ahora, al final de nuestra función principal, haremos llamadas apropiadas a funciones en el módulo psutil para guardar el valor. El código a continuación examina todas las particiones físicas disponibles y elige la primera para informar.

    # Utilizar el módulo psutil para enviar valores a Ubidots.    first_mnt = psutil.disk_partitions(all=False)[0].mountpoint        var_cpu.save_value({"value":        psutil.cpu_percent(interval=1)})    var_mem.save_value({"value":        psutil.virtual_memory().percent})    var_disk.save_value({"value":        psutil.disk_usage(first_mnt).percent})

Programación: cron y sin cron

Nuestro deseo es que este código se ejecute a intervalos regulares y oportunos. En Linux y Mac OS X, las tareas se pueden automatizar para ejecutarse a intervalos de N <minutos | horas | días> utilizando el servicio cron. Si vamos a programar nuestro script usando cron, debemos proceder de la siguiente manera:

if __name__ == "__main__":    main()

Ahora, para programarlo con cron, debemos guardar y cerrar el archivo, y escribir crontab -e en una nueva terminal. Una línea de cron de ejemplo para agregar es:

* * * * * python /home/daniel/ubidots-sysmon.py 74ccf3e7957be38eh382cgfd107d70870edbb463

Si no se programa durante cron, nuestra opción es hacer que el script se repita sobre las llamadas al método main(), pausando por un cierto tiempo para enviar resultados a intervalos regulares. La desventaja de esto es que el programa debe mantenerse en ejecución continuamente para seguir informando estadísticas. Sin embargo, el código para agregar al archivo de python se vería así:

if __name__ == ‘__main__’:    import time    while True:        main()        time.sleep(10) # pausa por 10 segundos

Conclusión

Ahí lo tenemos, en un número insignificante de líneas puedes monitorear tu sistema Windows, Linux o OS X desde la nube.

¿A dónde ir desde aquí? Para personalizar el script o cambiar las variables que informa, consulta la documentación de psutil para obtener una lista completa de mediciones al alcance de tu mano. Igualmente importante, recuerda que Ubidots puede notificarte sobre eventos en tus datos y proporcionar información.

Los eventos pueden ayudarte a detectar problemas antes de que se conviertan en un problema. Si la E/S del disco es un componente importante de un servicio que se ejecuta en tu sistema, considera configurar un evento para que te notifique cuando tu disco esté casi lleno. Considera configurar otro evento para que te notifique cuando el uso de memoria supere el 90% -- y atrapa el sistema antes de que ocurra paginación.

Los insights también pueden proporcionarte más información sobre tus datos. Para ver cuánta memoria está utilizando un servicio en un dispositivo, podemos determinar el porcentaje promedio de uso de memoria del día anterior. La figura a continuación muestra que, en promedio, el 49.56% de la memoria estaba en uso ayer.

Para concluir, espero haber demostrado que, aunque los sensores que miden el mundo exterior son los más fáciles de imaginar emparejados con Ubidots, Ubidots es igualmente capaz de emparejarse con sensores que miden el interior de una máquina.

¿Tienes otra idea de proyecto? ¡Crea una cuenta en Ubidots y comienza!

Publicado originalmente en Ubidots Blog el 24 de octubre de 2013

¿Ha quedado contestada tu pregunta?