Monitoreo de CPU y memoria de Servidor de Base de datos PostgreSQL

El monitoreo de nuestros servidores es una tarea importante para los devops, supongamos que se tiene un clúster de servidores de bases de datos PostgreSQL y se desea de una manera facil administrar el uso de recursos de la memoria y CPU.

Se puede implementar un sistema de monitoreo como Nagios, Collectd, Munin, zabbix, etc., pero eso significaria abrir otro puerto en su firewall y mantener otro proceso en ejecución. Si lo único que se busca es información básica como CPU y uso de memoria, con los siguientes pasos se podra realizar.

Crearemos dos tablas de base de datos que le permitirán consultar el uso de CPU y memoria desde la conexión de la base de datos. De esta manera, sus aplicaciones podran controlar el estado de los servidores sin necesidad de preocuparse por otra conexión u otro protocolo.

Puede ejecutar estos comandos en la base de datos maestra y también se propagarán a todas las bases de datos esclavas.

Primero, cargue el contenedor externo de datos del archivo y cree el servidor de datos externo:

CREATE EXTENSION file_fdw;
CREATE SERVER fileserver FOREIGN DATA WRAPPER file_fdw;

A continuación, crearemos la tabla que carga loadavg de CPU desde el archivo /proc/loadavg:

CREATE FOREIGN TABLE loadavg
(one text, five text, fifteen text, scheduled text, pid text)
SERVER fileserver
OPTIONS (filename '/proc/loadavg', format 'text', delimiter ' ');

La creación de la tabla que le permitirá consultar información de memoria, desde el archivo /proc/meminfo, es similar:

CREATE FOREIGN TABLE meminfo
(stat text, value text)
SERVER fileserver
OPTIONS (filename '/proc/meminfo', format 'csv', delimiter ':');

Ahora puede ejecutar consultas SELECT para ver la información.

postgres=# SELECT * FROM loadavg;
 one  | five | fifteen | scheduled |  pid
------+------+---------+-----------+-------
 0.00 | 0.01 | 0.05    | 1/124     | 27961
(1 fila)
postgres=# SELECT * FROM meminfo;
       stat        |         value
-------------------+------------------------
 MemTotal          |         1883660 kB
 MemFree           |           765008 kB
 MemAvailable      |     1543596 kB
 Buffers           |                0 kB
 Cached            |            921048 kB
 SwapCached        |         10492 kB
 Active            |            681904 kB
 Inactive          |          289636 kB
 Active(anon)      |       41520 kB
 Inactive(anon)    |     54328 kB
 Active(file)      |      640384 kB
 Inactive(file)    |    235308 kB
 Unevictable       |            0 kB
 Mlocked           |                0 kB
 SwapTotal         |        3145724 kB
 SwapFree          |         3088712 kB
 Dirty             |                 96 kB
 Writeback         |              0 kB
 AnonPages         |          42400 kB
 Mapped            |             55696 kB
 Shmem             |              45356 kB
 Slab              |               99112 kB
 SReclaimable      |       68144 kB
 SUnreclaim        |         30968 kB
 KernelStack       |         2000 kB
 PageTables        |          7168 kB
 NFS_Unstable      |           0 kB
 Bounce            |                 0 kB
 WritebackTmp      |           0 kB
 CommitLimit       |      4087552 kB
 Committed_AS      |      478740 kB
 VmallocTotal      |    34359738367 kB
 VmallocUsed       |         9016 kB
 VmallocChunk      |    34359726680 kB
 HardwareCorrupted |      0 kB
 AnonHugePages     |      16384 kB
 HugePages_Total   |        0
 HugePages_Free    |         0
 HugePages_Rsvd    |         0
 HugePages_Surp    |         0
 Hugepagesize      |        2048 kB

Por supuesto, siempre puedes consultar partes específicas de meminfo de esta manera:

postgres=# SELECT * FROM meminfo WHERE stat IN ('MemTotal','MemFree');
   stat   |        value
----------+---------------------
 MemTotal |         1883660 kB
 MemFree  |           764884 kB
(2 filas)

Como se puede observar, los datos de meminfo están un poco desordenados debido a los espacios en blanco en /proc/meminfo, por lo que esto requerirá cierta limpieza al momento de hacer la consulta.

Para tener nuestros datos un poco mas ordenados, crearemos una tabla donde se almacenará esta información.

CREATE TABLE public.memory
(
  id integer NOT NULL DEFAULT nextval('memory_seq'::regclass),
  stat text,
  value text,
  datetime timestamp with time zone,
  CONSTRAINT memory_pkey PRIMARY KEY (id)
)
WITH (OIDS=FALSE);

Luego se puede crear una tarea que se ejecute cada cierta cantidad de minutos, horas, o de acuerdo a demanda y que inserte los valores en la tabla creada.

INSERT INTO memory (stat, value, datetime)
SELECT stat, LTRIM(replace(value, ' kB', '')), now() FROM meminfo WHERE stat IN ('MemTotal','MemFree', 'MemAvailable');
postgres=# SELECT id, stat, value, datetime  FROM public.memory;
  id  |     stat     |  value  |           datetime
------+--------------+---------+-------------------------------
    1 | MemTotal     | 2915984 | 2018-02-19 12:41:35.815396-05
    2 | MemFree      | 2095552 | 2018-02-19 12:41:35.815396-05
    3 | MemAvailable | 2522564 | 2018-02-19 12:41:35.815396-05
    4 | MemTotal     | 2915984 | 2018-02-19 12:42:47.506419-05
    5 | MemFree      | 2093708 | 2018-02-19 12:42:47.506419-05
    6 | MemAvailable | 2520736 | 2018-02-19 12:42:47.506419-05
    7 | MemTotal     | 2915984 | 2018-02-19 12:43:47.579134-05
    8 | MemFree      | 2093552 | 2018-02-19 12:43:47.579134-05
    9 | MemAvailable | 2520580 | 2018-02-19 12:43:47.579134-05

Del mismo se podría crear una tabla e ir registrando periódicamente los valores del archivo /proc/loadavg

Share on FacebookTweet about this on TwitterShare on Google+

Agregue un comentario

Su dirección de correo no se hará público. Los campos requeridos están marcados *