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 significaría 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 podrá 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 podrán 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.
Creación del servidor de datos externo
Primero, cargue el contenedor externo de datos del archivo y cree el servidor de datos externo:
1 2 |
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:
1 2 3 4 |
CREATE FOREIGN TABLE loadavg (one text, five text, fifteen text, scheduled text, pid text) SERVER fileserver OPTIONS (filename '/proc/loadavg', format 'text', delimiter ' '); |
Creación de Tabla:
La creación de la tabla que le permitirá consultar información de memoria, desde el archivo /proc/meminfo, es similar:
1 2 3 4 |
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.
1 2 3 4 5 |
postgres=# SELECT * FROM loadavg; one | five | fifteen | scheduled | pid ------+------+---------+-----------+------- 0.00 | 0.01 | 0.05 | 1/124 | 27961 (1 fila) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
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 |
Consultar datos
Por supuesto, siempre puedes consultar partes específicas de meminfo de esta manera:
1 2 3 4 5 6 |
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.
1 2 3 4 5 6 7 8 9 |
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); |
Inserción de datos
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.
1 2 |
INSERT INTO memory (stat, value, datetime) SELECT stat, LTRIM(replace(value, ' kB', '')), now() FROM meminfo WHERE stat IN ('MemTotal','MemFree', 'MemAvailable'); |
1 2 3 4 5 6 7 8 9 10 11 12 |
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