Archive for August, 2011
Zabbix-PostgreSQL Monitoreo de sesiones.
1Hace unos dias arranque con un pequeño script para el monitoreo de las sesiones en un motor de base de datos PostgreSQL (PostgreSQL Sessions Monitor). Ahora toca explicar como integrarlo directamente con un servidor de monitoreo Zabbix.
Para esta tarea se utilizo el mismo script pgmon, solo que modificamos la lina donde seteamos el OUTPUTFORMAT, para que por defecto no devuelva los resultados formateados para pantalla:
if [ "$OUTPUTFORMAT" == "" ]; then OUTPUTFORMAT=0 fi
En la linea 15, reemplazamos OUTPUTFORMAT=1 por OUTPUTFORMAT=0
La configuración puede varias segun la distribución linux utilizada. Lo primero que debermos hacer es crear un link a pgmon en alguna ubicacion contenida dentro de la variable de entorno PATH. En gentoo, el lugar ideal para estas aplicaciones de “terceros” es /opt/bin
mkdir /opt/bin ln -s /root/utils/scripts/monitoreo/pgmon /opt/bin/pgmon
El agente zabbix corre como el usuario del sistema zabbix. Para contabilizar las sesiones se realiza una conexión a la base de datos, por lo tanto el usuario que ejecute pgmon debe tener autenticación IDENT a PostgreSQL. Otra alternativa es utilizar sudo para permitir la ejecución de pgmon como otro usuario, en este caso lo ejecutaremos como root (No muy recomendable, seria mejor ejecutarlo como postgres).
Para dar acceso a zabbix a sudo, debemos modificar /etc/sudoers agregando la siguiente linea al final:
zabbix ALL=NOPASSWD: /opt/bin/pgmon
Ahora simplemente modificamos la configuracion del agente zabbix para crear el nuevo parametro de usuario (/etc/zabbix/zabbix_agentd.conf)
UserParameter=pgmon[*],sudo /opt/bin/pgmon \$1
El siguiente paso es configurar nuestro servidor zabbix para que consulte este nuevo “monitor”, para ellos nos dirigimos a nuestro panel zabbix -> Configuración -> Equipos -> Monitores del equipo donde corre nuestro PostgreSQL.
Aquí abrimos “Crear monitor” (Parte superior derecha) y configuramos un nuevo monitor con el valor “pgmon[-s -n]” para contabilizar las sesiones totales. También podemos crear un monitor para ver las sesiones actualmente ejecutando alguna consulta (Busy Sessions), aquí debemos usar el monitor “pgmon[-s -b]“.
Ejemplo de pantalla de configuración de monitor:

Configuración de nuevo monitor
Una vez que tenemos los monitores configurados y corriendo, podremos crear un grafico que plasme la cantidad de sesiones abiertas (persistentes) sobre la cantidad de sesiones realmente ejecutando consultas.
PostgreSQL Sessions Monitor
1Hace unos días me encontré con la necesidad de contar con una herramienta rápida para chequear las sesiones actualmente corriendo en una base de datos PostgreSQL. La idea era contar con una herramienta para monitorear por consola y adicionalmente poder integrarlo al servidor Zabbix que actualmente tengo corriendo para monitorear todos los servidores.
Como no encontre nada simple decidí hacer un pequeñisimo script para pode monitorear algunas variables. La versión inicial monitorea:
El código se explica por si solo y es bastante simple.
#!/bin/bash # # Script para monitoreo de servidor PostgreSQL # # @author Emiliano Romero <emilianoromero@gmail.com> # @www about.me/reflex # Config Vars DEFAULTDB="db3g" DEFAULTUSER="postgres" DEFAULTPASSWD="" # Static Vars VERSION="0.1rc1" if [ "$OUTPUTFORMAT" == "" ]; then OUTPUTFORMAT=1 fi ###################### # FUNTIONS # ###################### # Help function showhelp { echo "PGMon $VERSION" echo "Usage PGMon [MonitorType] [TypeOptions]" echo " -s: Sessions Monitor" echo " -n: Shows number of open connections" echo " -b: Shows number of busy connections" echo " -d: Shows list of running queries" echo " -p <pid>: Shows detailed information about <pid> PostgreSQL process" echo " -h: Shows this help information" echo " " echo "Examples: pgmon -s -d" echo " pgmon -s -p 1234" } # Sessions Monitor function sessionmon { case $2 in # Count sessions -n) sessionmon_count ;; -b) sessionmon_running ;; -d) sessionmon_detail $* ;; -p) sessionmon_pid $* ;; *) showhelp ;; esac } # Sessions Total Count function sessionmon_count { sesscount=$(SQLExec 'SELECT COUNT(*) FROM "pg_stat_activity";') formatecho "Sessions Number:" $sesscount } # Sessions Busy Count function sessionmon_running { sesscount=$(SQLExec 'SELECT COUNT(*) FROM "pg_stat_activity" where "current_query"!='"'"'<IDLE>'"'"';') formatecho "Busy Sessions:" $sesscount } # Sessions Detail function sessionmon_detail { cols=$(tput cols) sqllen=$(($cols - 60)) if [ $sqllen -lt 1 ]; then sqllen=1 fi SQLExec_formated 'SELECT "datname" as database,"procpid" as pid,"usename", substring(replace(regexp_replace("current_query",E'"'"'/\\*.*\\*/'"'"','"'"''"'"'),E'"'"'\n'"'"','"'"''"'"') from 1 for '"$sqllen"') as query, date_trunc('"'"'seconds'"'"', (now() - "query_start")) as running, "client_addr" as ip from "pg_stat_activity" where "current_query" != '"'"'<IDLE>'"'"' order by running desc;' } # Sessions PID Details function sessionmon_pid { COLOR_TITLE="\e[1;37m" COLOR_VALUE="\e[0;37m" DATA=$(SQLExec 'SELECT *,date_trunc('"'"'seconds'"'"', (now() - "query_start")) as running FROM "pg_stat_activity" where "procpid"='"$3"'') #datid|datname|procpid|usesysid|usename|current_query|waiting|xact_start|query_start|backend_start|client_addr|client_port # Split IFS="|"; declare -a Array=($DATA) datname=${Array[1]} procpid=${Array[2]} usename=${Array[4]} current_query=${Array[5]} waiting=${Array[6]} xact_start=${Array[7]} query_start=${Array[8]} backend_start=${Array[9]} client_addr=${Array[10]} client_port=${Array[11]} running=${Array[12]} echo -e "\e[1mPostgreSQL PID \e[1;32m$procpid \e[0m\e[1mdetails\e[0m" echo -e "${COLOR_TITLE}Username: ${COLOR_VALUE}$usename \t\t${COLOR_TITLE}IP: ${COLOR_VALUE}$client_addr:$client_port" echo -e "${COLOR_TITLE}Database: ${COLOR_VALUE}$datname" echo -e "${COLOR_TITLE}Waiting: ${COLOR_VALUE}$waiting" echo -e "${COLOR_TITLE}Connection Start: ${COLOR_VALUE}$backend_start" echo -e "${COLOR_TITLE}Running: \e[1;31m$running" echo -e "${COLOR_TITLE}SQL Query ${COLOR_VALUE}" echo -e "$current_query" } #SQLExec function SQLExec { echo "$1" | psql -tA -U $DEFAULTUSER $DEFAULTDB } # SQLExec for printing function SQLExec_formated { echo "$1" | psql -U $DEFAULTUSER $DEFAULTDB } # FormatEcho <text> <value> function formatecho { if [ $OUTPUTFORMAT -eq 0 ]; then echo $2 else echo "$1 $2" fi } #################### # MAIN # #################### case $1 in -s) sessionmon $* ;; -h|*) showhelp ;; esac
Si necesitamos que el script largue los resultados de la cantidad de sesiones limpio (Sin titulo), simplemente seteamos la variable OUTPUTFORMAT=0.
OUTPUTFORMAT=0 ./pgmon -s -b
En estos días subo un nuevo Post para integrarlo con zabbix.