Script para monitorizar carga CPU en un servidor Linux

Resultado final del script de monitorización de load CPU

Esta es la historia de hace unos meses, cuando migré un sitio web con mucha carga y visitantes simultáneos a un servidor más económico. Durante los primeras semanas teníamos problemas de carga de la web, sobre todo de madrugada, por tareas de mantenimiento, generación de backups, etc.

Por ello, consideré oportuno la necesidad de algún script que monitorizara la carga de CPU periódicamente con el objetivo de poder ver una gráfica y determinar qué puntos exactamente eran los críticos. De ésta forma, analizando el inicio de los momentos de mucha carga de CPU, podría casar la hora de comienzo con la tarea de CRONTAB del sistema.

En éste artículo voy a contar cómo montar un script muy muy sencillo que almacenará en un fichero, cada cinco minutos, la carga de CPU y desde un fichero PHP con el generador de gráficas highcharts de javascript pintaremos una gráfica con los datos recopilados. Gracias a esto, fui capaz de mover las tareas programadas a otros momentos y repartir la carga para que la web no fallase.

El CRON que mencionaba anteriormente, para aquellos que sean nuevos en Linux, es un administrador de procesos que sirve para ejecutar scripts en intervalos regulares. Los procesos a ejecutar se configura en el fichero CRONTAB al que más adelante os contaré cómo acceder.

El script que vamos a crear se simplifica en leer el “uptime” del sistema, que nos da información de tiempo up del servidor y el load actual, la media de los últimos cinco minutos y la media de los últimos quince minutos. Lo que vamos a hacer es extraer de esa cadena de texto la cifra que calcula el load de los últimos cinco minutos.

Cada día generará un log nuevo con la fecha del día y lo almacenará en un directorio “cpuloadlog” en /var/log/ que tendremos que crear.

Creamos el directorio:

sudo mkdir /var/log/cpuloadlog

Y comenzamos con la tarea. Lo primero, creamos un fichero de nombre cpuloadlog.sh que contendrá el script de captura de carga.

sudo nano /usr/local/bin/cpuloadlog.sh

Y le añadimos lo siguiente:

#!/bin/bash

LOG_PATH="/var/log/cpuloadlog/"
LOG_NAME=`date +%Y-%m-%d`.log
MOMENTO=`date +%Y-%m-%d-%H:%M`

load="$($_CMD uptime |awk -F'average:' '{ print $2}')"
x="$(echo $load | sed s/,//g | awk '{ print $2}')"

echo $MOMENTO " " $x >> $LOG_PATH$LOG_NAME

Para salir del editor y guardar hacemos CTRL + X, pulsamos Y para aceptar los cambios e INTRO para confirmar el nombre.

Importante asignarle permiso de ejecución al fichero:

sudo chmod +x /usr/local/bin/cpuloadlog.sh

A continuación, añadimos una línea al CRONTAB del sistema para que ejecute nuestro script periódicamente. Como nos hemos basado en el AVG de los últimos 5 minutos, haremos que CRON lo ejecute cada 5 minutos.

sudo crontab -e

El comando anterior nos abrirá un editor donde se listan todas las tareas CRON que ya había definidas. No tocamos nada y nos vamos al final del fichero. Añadimos la siguiente línea:

*/5 * * * * /usr/local/bin/cpuloadlog.sh

Para salir, dependiendo del editor, si utilizáis nano, igual que antes: CTRL + X y después INTRO.

Con esto, acabamos la parte de recuperación de datos, ahora sólo queda leerlos. Para ello, vamos a generar un fichero PHP muy sencillo, por ello, no os asustéis si no veis la etiqueta <body>, <html>, ni nada. Lo único que hace es mostrar los datos. Dejo en vuestras manos el completar éste fichero y ponerlo elegante.

Por supuesto, es imprescindible tener instalado un servidor web. En donde tengáis configurada una web, cread un fichero carga.php con el siguiente contenido:

<?php
$fecha = str_replace(".", "", $_GET['fecha']);
if($fecha==""){
	$fecha = date("Y-m-d", time());
}
$nombre_fichero = "/var/log/cpuloadlog/".$fecha.".log";
// Comprobamos si el fichero existe
if(!file_exists($nombre_fichero)){
	die("Error: El fichero no existe.");
}
// Leemos el fichero
$handle = fopen($nombre_fichero, "r");
if ($handle) {
	while (($line = fgets($handle)) !== false) {
		$data[] = explode("   ",$line);
	}
}
fclose($handle);

// Creamos el script con todos los datos. Éste se lo pasaremos a highcharts
echo '<script>';
echo 'var labels = [';
if($data)
foreach($data as $linea){
	echo '"'.$linea[0].'",';
}
echo '];';

echo 'var data = [';
if($data)
foreach($data as $linea){
	echo ''.$linea[1].',';
}
echo '];';

echo '</script>';
?>
<meta charset="UTF-8">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>

<div id="container" style="min-width: 1000px; height: 400px; margin: 0 auto"></div>

<script>$(function () {
	$('#container').highcharts({
		title: {
			text: "Monitorización <?php echo $fecha; ?>",
		},
		chart: {
			zoomType: 'x'
		},
		xAxis: {
			categories: labels,
			labels: { enabled: false }
		},
		yAxis: {
			min: 0,
			title: {
				text: 'Carga CPU'
			}
		},
		series: [{
			name: 'Datos',
			data: data
		}]
	});
});
</script>

Y con esto hemos acabado. Si accedéis a carga.php en vuestra web al cabo de 5-10 minutos, empezaréis a ver los primeros puntos.

Por cierto, éste script admite ver las gráficas de carga de diferentes días. Para ello, tendréis que acceder así: carga.php?YYYY-MM-DD

Espero que este simple script os ayude a solucionar problemas de carga en vuestro servidor. En internet podréis encontrar soluciones mucho más completas pero yo quería algo muy simple, algo que no supusiera carga adicional al servidor y simplemente recuperara el load.

Actualización 17-03-2015: Highcharts se ha actualizado y con la nueva versión (la del CDN) la gráfica fallaba, se ha corregido el javascript que la pinta para adaptarse a la nueva versión.

Ibai

Apasionado por la tecnología, el software, las interfaces de usuario (UX UI) y los sistemas. Utilizo este canal de comunicación para transmitir de manera informal, y muchas veces "rápido", pequeñas aportaciones a la comunidad software.

3 thoughts on “Script para monitorizar carga CPU en un servidor Linux

  1. Hola, muy buen post, quería decirte que hay un error en la línea 48 después de «Monitorización <? falta la etiqueta php.

    Otra modificación que hice para que el chart me diera valores entre 1% y 100% fue:
    Script cpuloadlog.sh
    línea 8 incluí un "/10" sin las comillas justo despues del $2
    x="$(echo $load | sed s/,//g | awk '{ print $2/10}')"

    Carga.php
    Incluí un max : 100,
    yAxis: {
    min: 0, max: 100,
    title: {
    text: 'Carga CPU'
    }

    Espero que sea de ayuda
    Saludos

    1. Hola James,
      Muchas gracias por tu aportación! Es cierto, solucionado lo de la línea 48. En su día, los Short_tags de PHP estaban bien vistos. Hoy en día no, con lo que acepto el cambio.
      En relación al porcentaje, ojo: el load average no es un porcentaje, es un índice de carga basado en el número de núcleos del procesador, con lo que no va de 0 a 1. Dependiendo de tu CPU deberías de hacer una operación diferente.
      Un saludo y gracias!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *


El periodo de verificación de reCAPTCHA ha caducado. Por favor, recarga la página.

*

Artículos relacionados