Tag Archives: monitorizacion

Monitorizar GlusterFS

Ayer vimos como construir un cluster de almacenamiento distribuido con GlusterFS y CentOS. Hoy vamos a ver las herramientas que ofrece el propio Gluster para monitorizar el rendimiento.

Preparando el volumen

Antes de poder consultar el rendimiento tenemos que habilitarlo en la definición del volumen. Para ello hacemos.

# gluster volume profile testvol start

Ahora veremos la siguiente información a la salida del estado del volumen.

# gluster volume info

Volume Name: testvol
Type: Stripe
Volume ID: f922da05-737d-4fb5-83cc-e50d6782b90c
Status: Started
Number of Bricks: 1 x 4 = 4
Transport-type: tcp
Bricks:
Brick1: server1.example.com:/data
Brick2: server2.example.com:/data
Brick3: server3.example.com:/data
Brick4: server4.example.com:/data
Options Reconfigured:
diagnostics.count-fop-hits: on
diagnostics.latency-measurement: on
auth.allow: 192.168.1.*

Mostrar la entrada/salida

# gluster volume profile testvol info
Brick: server1.example.com:/data
--------------------------------
Cumulative Stats:
   Block Size:               4096b+ 
 No. of Reads:                    0 
No. of Writes:                    4 
 %-latency   Avg-latency   Min-Latency   Max-Latency   No. of calls         Fop
 ---------   -----------   -----------   -----------   ------------        ----
      0.00       0.00 us       0.00 us       0.00 us              1        STAT
      0.00       0.00 us       0.00 us       0.00 us              2      FORGET
      0.00       0.00 us       0.00 us       0.00 us              3     RELEASE
      0.00       0.00 us       0.00 us       0.00 us             24  RELEASEDIR
      0.85     250.00 us     250.00 us     250.00 us              1     SETATTR
      1.50     440.00 us     440.00 us     440.00 us              1       FSTAT
      1.51     222.00 us     200.00 us     244.00 us              2       FLUSH
      1.66     488.00 us     488.00 us     488.00 us              1      STATFS
      1.70     500.00 us     500.00 us     500.00 us              1        READ
      2.47     363.00 us     306.00 us     420.00 us              2      UNLINK
      5.15     504.33 us     471.00 us     539.00 us              3      CREATE
      8.20     602.50 us     324.00 us    1221.00 us              4       WRITE
     15.00    4411.00 us    4411.00 us    4411.00 us              1       FSYNC
     16.82     235.48 us     154.00 us     344.00 us             21     OPENDIR
     45.15     282.43 us     129.00 us    1694.00 us             47      LOOKUP
 
    Duration: 4233 seconds
   Data Read: 0 bytes
Data Written: 16384 bytes
 
Interval 1 Stats:
   Block Size:               4096b+ 
 No. of Reads:                    0 
No. of Writes:                    4 
 %-latency   Avg-latency   Min-Latency   Max-Latency   No. of calls         Fop
 ---------   -----------   -----------   -----------   ------------        ----
      0.00       0.00 us       0.00 us       0.00 us              1        STAT
      0.00       0.00 us       0.00 us       0.00 us              2      FORGET
      0.00       0.00 us       0.00 us       0.00 us              2     RELEASE
      0.00       0.00 us       0.00 us       0.00 us             21  RELEASEDIR
      0.85     250.00 us     250.00 us     250.00 us              1     SETATTR
      1.50     440.00 us     440.00 us     440.00 us              1       FSTAT
      1.51     222.00 us     200.00 us     244.00 us              2       FLUSH
      1.66     488.00 us     488.00 us     488.00 us              1      STATFS
      1.70     500.00 us     500.00 us     500.00 us              1        READ
      2.47     363.00 us     306.00 us     420.00 us              2      UNLINK
      5.15     504.33 us     471.00 us     539.00 us              3      CREATE
      8.20     602.50 us     324.00 us    1221.00 us              4       WRITE
     15.00    4411.00 us    4411.00 us    4411.00 us              1       FSYNC
     16.82     235.48 us     154.00 us     344.00 us             21     OPENDIR
     45.15     282.43 us     129.00 us    1694.00 us             47      LOOKUP
 
    Duration: 3767 seconds
   Data Read: 0 bytes
Data Written: 16384 bytes

Esta información se repite por cada uno de los bricks que conforman el cluster.

Comandos TOP de Gluster

Hay una serie de comandos que nos muestran los picos de rendimiento del cluster, son los siguientes.

Ver los descriptores abiertos y la cuenta máxima de descriptores

# gluster volume top testvol open brick server1.example.com:/data
Brick: server1.example.com:/data
Current open fds: 1, Max open fds: 2, Max openfd time: 2014-07-30 09:39:44.312759

Ver ranking de llamadas a lectura de fichero

# gluster volume top testvol read brick server1.example.com:/data
Brick: server1.example.com:/data
Count		filename
=======================
1		/file.txt

Ver ranking de llamadas a escritura de fichero

# gluster volume top testvol write brick server1.example.com:/data
Brick: server1.example.com:/data
Count		filename
=======================
4		/.file.txt.swp

Ver ranking de llamadas abiertas en directorios

# gluster volume top testvol opendir brick server1.example.com:/data
Brick: server1.example.com:/data
Count		filename
=======================
21		/prueba

Ver ranking de llamadas de lecturas en directorio

# gluster volume top testvol readdir brick server1.example.com:/data
Brick: server1.example.com:/data
Count		filename
=======================
4		/prueba

Ver la lista del rendimiento en lectura en cada brick

# gluster volume top testvol read-perf bs 256 count 1 brick server1.example.com:/data
Brick: server1.example.com:/data
Throughput 6.24 MBps time 0.0000 secs
MBps Filename                                        Time                      
==== ========                                        ====                      
   0 /file.txt                                       2014-07-30 09:39:44.388815

Ver la lista del rendimiento en escritura en cada brick

# gluster volume top testvol write-perf bs 256 count 1 brick server1.example.com:/data
Brick: server1.example.com:/data
Throughput 8.26 MBps time 0.0000 secs
MBps Filename                                        Time                      
==== ========                                        ====                      
  27 /prueba/.file.xls.swp                           2014-07-30 10:50:37.671327
  18 /.file.swp                                      2014-07-30 10:50:13.860439
   0 /prueba/file.xls                                2014-07-30 10:52:13.528054
   0 /file                                           2014-07-30 10:50:13.829870

Fuente

Es una chuleta de la documentación oficial que se puede consultar aquí y está más documentada pero la sintaxis de los comandos no está actualizada a día de hoy.

Crear un Demonio en Linux

En esta entrada vamos a explicar cómo proceder para escribir un demonio bajo GNU/Linux. Lo primero es definir que se entiende por un demonio, y citamos a la wikipedia:

Un demonio, daemon o dæmon (de sus siglas en inglés Disk And Execution MONitor), es un tipo especial de proceso informático no interactivo, es decir, que se ejecuta en segundo plano en vez de ser controlado directamente por el usuario. Este tipo de programas se ejecutan de forma continua (infinita), vale decir, que aunque se intente cerrar o matar el proceso, este continuará en ejecución o se reiniciará automáticamente. Todo esto sin intervención de terceros y sin dependencia de consola alguna.

Un ejemplo de demonio es Apache, permanece en ejecución en segundo plano esperando peticiones de páginas web para ser servidas. O cron que es un demonio temporal, es decir, realiza acciones basadas en el tiempo.

El primer paso que debemos tener en cuenta es qué va a realizar el demonio, Linux basa su programación en que cada programa resuelve un único problema pero lo hace bien. Para ilustrar esta entrada construiremos un demonio que supervise si el demonio Apache está funcionando.

Requisitos

Necesitamos un compilador de C, normalmente GCC, y las cabezeras de C para linux, esto en Debian se consigue con:

# apt-get install build-essential

Necesitaremos también un editor para escribir el código.

Estructura básica de un demonio

Durante la ejecución del demonio debemos realizar algunas tareas básicas que se resumen en:

  • Hacer fork del proceso padre.
  • Cambiar la máscara de fichero.
  • Abrir los archivos de registros necesarios.
  • Crear un identificador de sesión único.
  • Cambiar el directorio de trabajo hacia un sitio más seguro.
  • Cerrar los descriptores de ficheros estandard.
  • Escribir el código del demonio propiamente.

El código

He comentado el código con lo más importante y está bastante autoexplicativo:


#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>

int main(void) {
  
  pid_t pid, sid;
  int apachePIDfile, apachePIDread, apachePID, daemonLogFileDesc;
  char buf[5], filename[255];        
          
  /* Forkeamos el proceso padre */
  pid = fork();
  if (pid < 0) {
    exit(EXIT_FAILURE);
  }
  /* Cuando tenemos un PID correcto podemos cerrar
   * el proceso padre.
   * Atención al control de errores, es una buena
   * técnica de programación comprobar todas las
   * situaciones donde se pueden dar errores. */
  if (pid > 0) {
    exit(EXIT_SUCCESS);
  }

  /* Cambiamos el modo de la mascara de ficheros */
  /* Hacemos esto para que los fichero generados por el
   * demonio sean accesibles por todo el mundo */
  umask(0);
          
  /* Abrimos los ficheros de logs del demonio */        
  /* Esto es opcional pero como vamos a cerrar los descriptores 
   * hacemos esto para que exista algo de comunicación con el demonio */
  daemonLogFileDesc = open ("log", O_WRONLY | O_CREAT, 0600);
  if (daemonLogFileDesc == -1) {
    perror ("Error en la apertura del log");
    exit (EXIT_FAILURE);
  }
  
  /* Creamos un nuevo SID */
  /* Esto se hace porque al haber matado al padre el hijo puede quedarse 
   * en el sistema como un proceso zombie, generando un nuevo SID hacemos
   * que el sistema se haga cargo del proceso huérfano otorgándole un nuevo SID */
  sid = setsid();
  if (sid < 0) {
    perror("new SID failed");
    exit(EXIT_FAILURE);
  }
    
  /* Por seguridad, cambiamos el directorio de trabajo */
  if ((chdir("/")) < 0) {
    perror("Change the current work directory failed");
    exit(EXIT_FAILURE);
  }
    
  /* Cerramos los descriptores standard */
  /* El demonio no puede usar la terminal, por lo que estos
   * descriptores son inútiles y un posible riesgo de seguridad.*/
  close(STDIN_FILENO);
  close(STDOUT_FILENO);
  close(STDERR_FILENO);
    
  /* El código del demonio */
  /* Obtenemos el PID con el que está corriendo el proceso apache */
  apachePIDfile = open("/var/run/apache2.pid", O_RDONLY, 0600);
  if (apachePIDfile == -1) {
    perror("Error en la apertura del fichero");
    exit(EXIT_FAILURE);
  }
  apachePIDread = read (apachePIDfile, buf, sizeof(buf));
    
  /* El gran bucle! */
  /* El demonio ejecutara este bucle toda su vida,
   * abrirá un archivo del pseudo sistema de ficheros /proc
   * y comprobará que existe, si existe Apache está corriendo y lo escribe
   * en el log, en caso contrario sale. */
  while (1) {
    apachePID = atoi (buf);
    snprintf(filename, sizeof(filename), "/proc/%d/cmdline", apachePID);
  
    if ((open (filename, O_RDONLY, 0600)) == -1) {
      perror ("No puedo abrir el fichero en proc");
      exit(EXIT_FAILURE);
    } else {
      write (daemonLogFileDesc, "Apache running\n", 15);
      sleep(30); /* espera 30 segundos */
    }
  }
  exit(EXIT_SUCCESS);
}

Compilamos

Para compilar hacemos lo siguiente:

# cc daemon1.c -o daemon1

A falta de un nombre más original, he llamado al demonio daemon1.

Ejecución

Para ejecutarlo hacemos:

# ./daemon1

Podemos ver que está corriendo tanto en el lista de procesos con ps como mirando el fichero log que hemos creado.

tailf log
...
Apache running
Apache running
Apache running
...

Referencias

Es una traducción/adaptación de la guía Linux Daemon Writing HOWTO, que es más teórica y aquí he querido dar una aplicación práctica, aunque es obvio que existe demonios de monitorización más avanzado quería marcar bien los conceptos de la construcción de un demonio aplicados a un caso particular.

Lanzar Acciones Basado en la Actividad del Sistema

Hoy os quiero presentar una utilidad tan simple como impresionante. Sentinella es una simple interface gráfica con una serie de eventos a monitorizar y una serie de acciones a ejecutar.

Para instalarla, en Debian/Ubuntu.

# apt-get install sentinella

En Fedora

# yum install sentinella

Si miramos la captura, es bastante autoexplicativa:

Sentinella

Sentinella

Podemos monitorizar:

  1. La carga de CPU.
  2. La memoria usada.
  3. El trafico de red.
  4. La fecha y la hora.
  5. El programa escogido.

Así, al escoger una de estas opciones decidimos que condición debe cumplir para la acción.

Las condiciones a cumplir son:

  • CPU: Mayor o menor que un tanto por ciento.
  • Memoria: Más o menos que una cantidad en MB.
  • Tráfico de red: Descarga o subida más o menos que una cantidad en KB/s.
  • Fecha y hora: La fecha u hora especificada.
  • El programa escogido muere: Cuando seleccionamos esta opción, nos saldrá una ventana con los procesos en ejecución para elegir uno, si el elegido muere, lanzará la acción.

Las condiciones de CPU, Memoria y Tráfico tienen además un control de tiempo, es decir, debe cumplirse la condición durante este tiempo para que se pase a la acción.

Una vez que la condición se cumple, pasamos a la acción, que enumeramos a continuación.

  1. Apagar.
  2. Reiniciar.
  3. Dormir.
  4. Ejecutar un comando.
  5. Lanzar la alarma. (tiene 3 tipos de alarma)
  6. Terminar el programa.

Algunos ejemplos, podemos apagar el PC configurando que el tráfico de red sea menor que 50KB/s en eth0 indicando que la descarga ha finalizado. Podemos hacer sonar la alarma cuando la carga de CPU sea menor que 20% indicando que el ya está rippeado el DVD para subirlo al Torrent. Podemos controlar que el Transmission funciona colocandolo en el menu de “El programa elegido muere”. Se me ocurren algunos ejemplos más pero creo que está bastante claro el uso. Una interface sencilla y bien estructurada hará de esta pequeña pieza de software las delicias de sus usuarios.

Página del proyecto.