PostgreSQL Sessions Monitor
Hace 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.