diff --git a/META.yml b/META.yml index 0a6605d1..09bb4d40 100644 --- a/META.yml +++ b/META.yml @@ -1,6 +1,6 @@ --- #YAML:1.0 name : check_postgres.pl -version : 2.21.0 +version : 2.22.0 abstract : Postgres monitoring script author: - Greg Sabino Mullane @@ -30,7 +30,7 @@ recommends: provides: check_postgres: file : check_postgres.pl - version : 2.21.0 + version : 2.22.0 keywords: - Postgres diff --git a/Makefile.PL b/Makefile.PL index b5fd73a9..82e3948c 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -6,7 +6,7 @@ use strict; use warnings; use 5.006001; -my $VERSION = '2.21.0'; +my $VERSION = '2.22.0'; if ($VERSION =~ /_/) { print "WARNING! This is a test version ($VERSION) and should not be used in production!\n"; diff --git a/SIGNATURE b/SIGNATURE index 866791d0..e569acd8 100644 --- a/SIGNATURE +++ b/SIGNATURE @@ -1,5 +1,5 @@ This file contains message digests of all files listed in MANIFEST, -signed via the Module::Signature module, version 0.68. +signed via the Module::Signature module, version 0.73. To verify the content in this distribution, first make sure you have Module::Signature installed, then type: @@ -16,20 +16,20 @@ Hash: RIPEMD160 SHA1 3daf641677071210a1702e075f9837becd504d9d MANIFEST SHA1 98fcae49e2adf1d73e0687998ca33992451984d6 MANIFEST.SKIP -SHA1 221581ac5b59c2cf634f6a521f02f5e4659e048d META.yml -SHA1 2c4d6ce8e44d088b6068dc07bfe902b7f3f350b3 MYMETA.yml -SHA1 6d4a6c15891a90886fdb9a4f37e80c3a1ccbc492 Makefile.PL -SHA1 0382a8d7bd1e6c8e2e85be867173ab231f78a66b README +SHA1 9689ee994df28f41713cb2da473eb4a62c453471 META.yml +SHA1 9650a23dd9d93c30c3dd22b1fa03fae83faf7d2a MYMETA.yml +SHA1 5da8d06b767684943819dd877d96709a9ec57046 Makefile.PL +SHA1 890ae0574b8633891c13f7f93463b868d47a65fd README SHA1 e4e41aec52387ddfb9ebe9257a5eee40700adb00 TODO -SHA1 49424a5f4aae35cda48709bc42b47a3bea94c345 check_postgres.pl -SHA1 f34b99a45f1670576d28eacb42b0e8c56c3245a0 check_postgres.pl.asc -SHA1 0bda94edc7eeab34fc73bfe105f566a6f6def2f5 check_postgres.pl.html +SHA1 9c857b8994c428dcf90cd2be8bdaf867d5728c44 check_postgres.pl +SHA1 5623669d7a48aabadaccd5ef6302d56dce6343db check_postgres.pl.asc +SHA1 c8b61de8a5bb8cd5678df67c327f66b6b58996e1 check_postgres.pl.html SHA1 3dc431ab18171fa977f919cddcee504b4b74392f perlcriticrc SHA1 ef43082a685d993fdd151de16590ce0f6832de7a t/00_basic.t SHA1 29700e8331d1780e87b858581054cd190e4f4ecb t/00_signature.t SHA1 439053254ee01e2ec406f9d1605dc5e28257b8bd t/00_test_tester.t SHA1 02f59725d968d85d855b0bcc771c99003c6e0389 t/01_validate_range.t -SHA1 7b9ef508bc0fc1624dc81129b4014a1b9704db7e t/02_autovac_freeze.t +SHA1 d0e8919a1c1bddb6438cfd104634cff3f31a9257 t/02_autovac_freeze.t SHA1 c50f069d276e44b95408fe16aefa46c24745a038 t/02_backends.t SHA1 923acca525a528ccefd630eef8e015007a1bc5d0 t/02_bloat.t SHA1 58f04f98539371d9469ca93890b3f61a990fa343 t/02_checkpoint.t @@ -62,12 +62,12 @@ SHA1 033bb1162ad990161da1c591d5fb9f7c452ee4c9 t/02_query_time.t SHA1 bdd9a4a73bbce6a5450cbc04e1fe357f3bc587a7 t/02_relation_size.t SHA1 94fd92c8a3453e86d80114009f8a40ccb709704b t/02_replicate_row.t SHA1 e36d0632a32b22ebdded6ab91fd46aca7f8b2b31 t/02_same_schema.t -SHA1 23df28d99d8799d85e7edb55ccbdcfc68fbfa22f t/02_sequence.t +SHA1 e62fdc6f164dc16faa08fecdbcafc1dbafd8d6a6 t/02_sequence.t SHA1 65ea5ff56452e71fefde682bf5e874d30800bd37 t/02_settings_checksum.t SHA1 17ab792f132cd6fabd6fa33598b5a4d502428543 t/02_slony_status.t SHA1 64493100381abd82aa1eb06a46d67456f4e8486d t/02_timesync.t -SHA1 221d3c78eece2a5fc796611e3133e5ccc8f8fad0 t/02_txn_idle.t -SHA1 7c77be0301c936974778c7c92186088ef9b06526 t/02_txn_time.t +SHA1 43c69ea3053a5ba268cb6126a15877edc37acfed t/02_txn_idle.t +SHA1 02f0434dfe2e852e676695871f2f2b4e0a764b15 t/02_txn_time.t SHA1 24ff2b5b0690557e1a45227d5c1131226c9ff30a t/02_txn_wraparound.t SHA1 2270e466a5761256be6b69cc0c7e8c03f2414e3b t/02_version.t SHA1 93c5da727c39f3dbb1953d061fa6f96578ba7952 t/02_wal_files.t @@ -75,10 +75,10 @@ SHA1 dad138868393ead7c170f24017a7c04b80fe5f87 t/03_translations.t SHA1 eb66336f915f77a1cd82c1b19b44acc7dc2d5038 t/04_timeout.t SHA1 e01ec73ad338765ee20afed29718b12c2ed83d82 t/05_docs.t SHA1 96e6e5da3e1f6753a469e7afc8cf070024b33b23 t/99_cleanup.t -SHA1 095c6b9fdc944faf7890f13d5330b179f41710a1 t/CP_Testing.pm +SHA1 b91ca27953271e32413b433ce4676e174a872b1c t/CP_Testing.pm -----BEGIN PGP SIGNATURE----- -iEYEAREDAAYFAlJB46QACgkQvJuQZxSWSshIPACgwFPjhdZ2REkyKirLaMYSwznp -ptIAn0ttmsPV4cKBfUp/wFUumCMi/A/y -=+efS +iEYEAREDAAYFAlWSvDwACgkQvJuQZxSWSsipRgCg4UXqpln34lmkpwRNMVQR13CA +g4cAnRarbGaEM2j4SC9GwM6UHWwjpwWy +=msbg -----END PGP SIGNATURE----- diff --git a/check_postgres.pl b/check_postgres.pl index a7a2a767..39fd9e20 100755 --- a/check_postgres.pl +++ b/check_postgres.pl @@ -32,7 +32,7 @@ package check_postgres; binmode STDOUT, ':encoding(UTF-8)'; -our $VERSION = '2.21.0'; +our $VERSION = '2.22.0'; use vars qw/ %opt $PGBINDIR $PSQL $res $COM $SQL $db /; @@ -97,7 +97,7 @@ package check_postgres; 'backends-oknone' => q{No connections}, 'backends-po' => q{sorry, too many clients already}, 'backends-users' => q{$1 for number of users must be a number or percentage}, - 'bloat-index' => q{(db $1) index $2 rows:$3 pages:$4 shouldbe:$5 ($6X) wasted bytes:$7 ($8)}, + 'bloat-index' => q{(db $1) index $2.$3 rows:$4 pages:$5 shouldbe:$6 ($7X) wasted bytes:$8 ($9)}, 'bloat-nomin' => q{no relations meet the minimum bloat criteria}, 'bloat-table' => q{(db $1) table $2.$3 rows:$4 pages:$5 shouldbe:$6 ($7X) wasted size:$8 ($9)}, 'bug-report' => q{Please report these details to check_postgres@bucardo.org:}, @@ -343,6 +343,262 @@ package check_postgres; 'wal-numfound' => q{WAL files found: $1}, 'wal-numfound2' => q{WAL "$2" files found: $1}, }, +'es' => { + 'address' => q{dirección}, + 'age' => q{edad}, + 'backends-fatal' => q{No es posible conectar: demasiadas conexiones}, + 'backends-mrtg' => q{DB=$1 Max conexiones=$2}, + 'backends-msg' => q{$1 de $2 conexiones ($3%)}, + 'backends-nomax' => q{No es posible determinar max_connections}, + 'backends-oknone' => q{No hay conexiones}, + 'backends-po' => q{lo siento, hay demasiados clientes}, + 'backends-users' => q{$1 debe ser un número o porcentaje de usuarios}, + 'bloat-index' => q{(bd $1) índice $2 filas:$3 páginas:$4 deberíaser:$5 ($6X) bytes desperdiciados:$7 ($8)}, + 'bloat-nomin' => q{ninguna relación cumple el criterio de bloat mínimo}, + 'bloat-table' => q{(bd $1) tabla $2.$3 filas:$4 páginas:$5 deberíaser:$6 ($7X) bytes desperdiciados:$8 ($9)}, + 'bug-report' => q{Por favor reporte estos detalles a check_postgres@bucardo.org:}, + 'checkcluster-id' => q{Identificador de la base de datos:}, + 'checkcluster-msg' => q{cluster_id: $1}, + 'checkcluster-nomrtg'=> q{Debe proporcionar un número con la opción --mrtg}, + 'checkmode-prod' => q{en producción}, + 'checkmode-recovery' => q{en recuperación de archivo}, + 'checkmode-state' => q{Estado del clúster de base de datos:}, + 'checkpoint-baddir' => q{Directorio de datos inválido: "$1"}, + 'checkpoint-baddir2' => q{pg_controldata no pudo leer el directorio de datos: "$1"}, + 'checkpoint-badver' => q{Fallo al ejecutar pg_controldata - probable que la versión sea incorrecta ($1)}, + 'checkpoint-badver2' => q{Fallo al ejecutar pg_controldata - verifique que es la versión correcta}, + 'checkpoint-nodir' => q{Debe especificar el argumento --datadir o definir la variable de ambiente PGDATA}, + 'checkpoint-nodp' => q{Debe instalar el módulo Perl Date::Parse para usar la acción checkpoint}, + 'checkpoint-noparse' => q{No se pudo interpretar la salida de pg_controldata: "$1"}, + 'checkpoint-noregex' => q{No se pudo encontrar la expresion regular para este chequeo}, + 'checkpoint-nosys' => q{No es posible ejecutar pg_controldata: $1}, + 'checkpoint-ok' => q{El último checkpoint fue hace 1 segundo}, + 'checkpoint-ok2' => q{El último checkpoint fue hace $1 segundo}, + 'checkpoint-po' => q{Instante del último checkpoint:}, + 'checksum-msg' => q{checksum: $1}, + 'checksum-nomd' => q{Debe instalar el módulo Perl Digest::MD5 para usar la acción checksum}, + 'checksum-nomrtg' => q{Debe proporcionar un checksum con la opción --mrtg}, + 'custom-invalid' => q{Formato devuelto por la consulta personalizada es inválido}, + 'custom-norows' => q{No se obtuvieron filas}, + 'custom-nostring' => q{Debe proporcionar el texto con la consulta}, + 'database' => q{base de datos}, + 'dbsize-version' => q{La base de datos debe ser version 8.1 o superior para utilizar la acción database_size}, + 'depr-pgcontroldata' => q{PGCONTROLDATA es obsoleta, en su lugar use PGBINDIR.}, + 'die-action-version' => q{No es posible ejecutar "$1": versión del servidor debe ser >= $2, pero es $3}, + 'die-badtime' => q{El valor de '$1' debe ser un tiempo valido. Ejemplos: -$2 1s -$2 "10 minutes"}, + 'die-badversion' => q{Cadena de versión no válida: $1}, + 'die-noset' => q{No puede ejecutar "$1": la opción $2 no esta activa}, + 'die-nosetting' => q{No fue posible obtener configuración '$1'}, + 'diskspace-fail' => q{Resultado inválido en el comando "$1": $2}, + 'diskspace-msg' => q{FS $1 montado en $2 esta usando $3 de $4 ($5%)}, + 'diskspace-nodata' => q{No fue posible determinar el data_directory: se está conectando como superusuario?}, + 'diskspace-nodf' => q{No se encuentra el ejecutable requerido /bin/df}, + 'diskspace-nodir' => q{No fue posible encontrar el directorio de datos "$1"}, + 'file-noclose' => q{No puedo cerrar $1: $2}, + 'files' => q{archivos}, + 'fsm-page-highver' => q{No se puede comprobar fsm_pages en servidores con versión 8.4 o posterior}, + 'fsm-page-msg' => q{ranuras de páginas FSM utilizadas: $1 de $2 ($3%)}, + 'fsm-rel-highver' => q{No se puede comprobar fsm_relations en servidores con versión 8.4 o posterior}, + 'fsm-rel-msg' => q{relaciones FSM utilizadas: $1 de $2 ($3%)}, + 'hs-future-replica' => q{El esclavo reporta que el reloj del maestro está adelantado, comprobar sincronización de tiempo}, + 'hs-no-role' => q{No es un par maestro/esclavo}, + 'hs-no-location' => q{No pude obtener ubicación actual de xlog en $1}, + 'hs-receive-delay' => q{receive-delay}, + 'hs-replay-delay' => q{replay_delay}, + 'hs-time-delay' => q{time_delay}, + 'hs-time-version' => q{La base de datos debes ser versión 9.1 or superior para comprobar el tiempo de retraso del esclavo}, + 'index' => q{Indice}, + 'invalid-option' => q{Opción inválida}, + 'invalid-query' => q{Se devolvió una consulta inválida: $1}, + 'language' => q{Idioma}, + 'listener-msg' => q{escuchas encontrados: $1}, + 'listening' => q{escuchado}, + 'locks-msg' => q{total "$1" bloqueos: $2}, + 'locks-msg2' => q{total bloqueos: $1}, + 'logfile-bad' => q{Archivo de registro inválido "$1"}, + 'logfile-debug' => q{Archivo de registro final: $1}, + 'logfile-dne' => q{El archivo de registo $1 no existe!}, + 'logfile-fail' => q{Fallo al registrar en: $1}, + 'logfile-ok' => q{registrando en: $1}, + 'logfile-openfail' => q{El archivo de registro "$1" no se pudo abrir: $2}, + 'logfile-opt-bad' => q{Opción de registro inválida}, + 'logfile-seekfail' => q{Fallo al buscar en $1: $2}, + 'logfile-stderr' => q{La salida de registro ha sido redirigida a STDERR: por favor proporcione un nombre de archivo}, + 'logfile-syslog' => q{La base de datos está usando syslog, por favor especifique una ruta con la opción --logfile (fac=$1)}, + 'mode-standby' => q{Servidor en modo "standby"}, + 'mode' => q{modo}, + 'mrtg-fail' => q{La acción $1 fracasó: $2}, + 'new-ver-nocver' => q{No fue posible descargar la información de versión para $1}, + 'new-ver-badver' => q{No fue posible interpretar la información de versión para $1}, + 'new-ver-dev' => q{No es posible comparar versiones de desarrollo: usted tiene $1 versión $2}, + 'new-ver-nolver' => q{No fue posible determinar información de versión local para $1}, + 'new-ver-ok' => q{La versión $1 es la última para $2}, + 'new-ver-warn' => q{Por favor actualice a la versión $1 de $2. Usted esta ejecutando $3}, + 'new-ver-tt' => q{Su versión de $1 ($2) parece ser más nueva que la versión actual! ($3)}, + 'no-db' => q{No hay bases de datos}, + 'no-match-db' => q{No hay bases de datos coincidentes debido a las opciones de exclusión/inclusión}, + 'no-match-fs' => q{No se encuentran sistemas de archivos coincidentes debido a las opciones de exclusión/inclusión}, + 'no-match-rel' => q{No se encuentran relaciones coincidentes debido a las opciones de exclusión/inclusión}, + 'no-match-set' => q{No se encuentran opciones de configuración coincidentes debido a las opciones de exclusión/inclusión}, + 'no-match-table' => q{No se encuentran tablas coincidentes debido a las opciones de exclusión/inclusión}, + 'no-match-user' => q{No se encuentran entradas coincidentes debido a las opciones de exclusión/inclusión}, + 'no-parse-psql' => q{No se pudo interpretar la salida de psql!}, + 'no-time-hires' => q{No se encontró Time::HiRes, necesario si 'showtime' es verdadero}, + 'opt-output-invalid' => q{Formato de salida inválido: debe ser 'nagios' o 'mrtg' o 'simple' o 'cacti'}, + 'opt-psql-badpath' => q{Argumento psql es inválido: debe ser una ruta absoluta a un archivo con nombre psql}, + 'opt-psql-noexec' => q{El archivo "$1" no parece ser ejecutable}, + 'opt-psql-noexist' => q{No se puede encontrar el ejecutable psql: $1}, + 'opt-psql-nofind' => q{No fue posible encontrar un ejecutable psql}, + 'opt-psql-nover' => q{No fue posible determinar la versión de psql}, + 'opt-psql-restrict' => q{No puede usar la opción --PGBINDIR o --PSQL si NO_PSQL_OPTION está habilitado}, + 'pgagent-jobs-ok' => q{No hay trabajos fallidos}, + 'pgbouncer-pool' => q{Pool=$1 $2=$3}, + 'pgb-backends-mrtg' => q{BD=$1 Max conexiones=$2}, + 'pgb-backends-msg' => q{$1 de $2 conexiones ($3%)}, + 'pgb-backends-none' => q{No nay conexiones}, + 'pgb-backends-users' => q{$1 debe ser un número o porcentaje de usuarios}, + 'PID' => q{PID}, + 'port' => q{puerto}, + 'preptxn-none' => q{No se encontraron transacciones preparadas}, + 'psa-disabled' => q{No hay consultas - están deshabilitados stats_command_string o track_activities?}, + 'psa-noexact' => q{Error desconocido}, + 'psa-nosuper' => q{No hay coincidencias - por favor ejecute como superusuario}, + 'qtime-count-msg' => q{Total de consultas: $1}, + 'qtime-count-none' => q{no mas que $1 consultas}, + 'qtime-for-msg' => q{$1 consultas más largas que $2s, más larga: $3s$4 $5}, + 'qtime-msg' => q{consulta más larga: $1s$2 $3}, + 'qtime-none' => q{no hay consultas}, + 'query' => q{consulta}, + 'queries' => q{consultas}, + 'query-time' => q{query_time}, + 'range-badcs' => q{Opción '$1' inválida: debe ser un "checksum"}, + 'range-badlock' => q{Opción '$1' inválida: debe ser el número de bloqueos, o "type1=#:type2=#"}, + 'range-badpercent' => q{Opción '$1' inválida: debe ser un porcentaje}, + 'range-badpercsize' => q{Opción '$1' inválida: debe ser un tamaño o un porcentaje}, + 'range-badsize' => q{Tamaño inválido para la opción '$1'}, + 'range-badtype' => q{validate_range solicitado con tipo desconocido '$1'}, + 'range-badversion' => q{Cadena inválida para la opción '$1': $2}, + 'range-cactionly' => q{Esta acción es solo para uso en cacti y no acepta parámetros warning o critical}, + 'range-int' => q{Valor inválido para la opción '$1': debe ser un entero}, + 'range-int-pos' => q{Valor inválido para la opción '$1': debe ser un entero positivo}, + 'range-neg-percent' => q{No puede especificar un porcentaje negativo!}, + 'range-none' => q{No se requieren opciones de warning o critical}, + 'range-noopt-both' => q{Debe especificar ambas opciones de 'warning' y 'critical'}, + 'range-noopt-one' => q{Debe especificar una opción 'warning' o 'critical'}, + 'range-noopt-only' => q{Puede especifiar solo una de las opciónes 'warning' o 'critical'}, + 'range-noopt-orboth' => q{Debe especificar un valor de 'warning', de 'critical', o ambos}, + 'range-noopt-size' => q{Debe especificar un tamaño de warning y/o critical}, + 'range-nosize' => q{Debe especificar un tamaño de warning y/o critical}, + 'range-notime' => q{Debe especificar un tamaño de warning y/o critical}, + 'range-seconds' => q{Valor inválido para la opción '$1': debe ser número de segundos}, + 'range-version' => q{debe ser en el formato X.Y o X.Y.Z, donde X es el número mayor de la versión, }, + 'range-warnbig' => q{El valor de la opción 'warning' no puede ser mayor que el de 'critical'}, + 'range-warnbigsize' => q{El valor de la opción 'warning' ($1 bytes) no puede ser mayor que el de 'critical ($2 bytes)'}, + 'range-warnbigtime' => q{El valor de la opción 'warning' ($1 s) no puede ser mayor que el de 'critical ($2 s)'}, + 'range-warnsmall' => q{El valor de la opción 'warning' no puede ser menor que el de 'critical'}, + 'range-nointfortime' => q{Valor inválido para las opciones '$1': debe ser un entero o un valor de tiempo}, + 'relsize-msg-ind' => q{el índice más grande es "$1": $2}, + 'relsize-msg-reli' => q{la relación más grande es el índice "$1": $2}, + 'relsize-msg-relt' => q{la relación más grande es la tabla "$1": $2}, + 'relsize-msg-tab' => q{la tabla más grande es "$1": $2}, + 'rep-badarg' => q{Parámetro invalido para repinfo: se esperan 6 valores separados por coma}, + 'rep-duh' => q{No tiene sentido probar la replicación con los mismos valores}, + 'rep-fail' => q{Fila no replicada en el esclavo $1}, + 'rep-noarg' => q{Necesita un valor para repinfo}, + 'rep-norow' => q{La fila del origen de la replicación no fue encontrada: $1}, + 'rep-noslaves' => q{No se encontraron esclavos}, + 'rep-notsame' => q{No se puede probar la replicación: los valores no coinciden}, + 'rep-ok' => q{La fila fue replicada}, + 'rep-sourcefail' => q{Falló la actualización del origen}, + 'rep-timeout' => q{La fila no fue replicada. Timeout: $1}, + 'rep-unknown' => q{Chequeo de replicación fallido}, + 'rep-wrongvals' => q{No puedo verificar la replicación: los valores no son correctos ('$1' no '$2' ni '$3')}, + 'runcommand-err' => q{Error desconocido en la función "run_command"}, + 'runcommand-nodb' => q{No se encontró ninguna base de datos buscada}, + 'runcommand-nodupe' => q{No fue posible duplicar STDERR}, + 'runcommand-noerr' => q{No fue posible abrir STDERR?!}, + 'runcommand-nosys' => q{Llamada al sistema falló con $1}, + 'runcommand-pgpass' => q{Se creo archivo temporal pgpass $1}, + 'runcommand-timeout' => q{Tiempo de espera del comando agotado! Considere incrementar --timeout a valor mayor que $1}, + 'runtime-badmrtg' => q{valor de queryname inválido?}, + 'runtime-badname' => q{Opción queryname inválida: debe ser el nombre de una única vista}, + 'runtime-msg' => q{tiempo de la consulta: $1 seg}, + 'schema' => q{Esquema}, + 'ss-createfile' => q{Archivo creado $1}, + 'ss-different' => q{"$1" es diferente:}, + 'ss-existson' => q{Existe en:}, + 'ss-failed' => q{Las bases de datos son diferentes. Elementos no coincidentes: $1}, + 'ss-matched' => q{Todas las bases tienen los mismos elementos}, + 'ss-missingon' => q{Desaparecido en:}, + 'ss-noexist' => q{$1 "$2" no existe en todas las bases de datos:}, + 'ss-notset' => q{"$1" no está definido en todas las bases de datos:}, + 'ss-suffix' => q{Error: no puede usar sufijos a menos que este buscando esquemas basados en tiempo}, + 'seq-die' => q{No es posible obtener información sobre la secuencia $1}, + 'seq-msg' => q{$1=$2% (llamadas pendientes=$3)}, + 'seq-none' => q{No se encontraron secuencias}, + 'size' => q{tamaño}, + 'slony-noschema' => q{No fue posible determinar el esquema para Slony}, + 'slony-nonumber' => q{El llamado a sl_status no devolvió un número}, + 'slony-lagtime' => q{Slony lag time: $1}, + 'symlink-create' => q{Creado "$1"}, + 'symlink-done' => q{No se crea "$1": El enlace $2 ya apunta a "$3"}, + 'symlink-exists' => q{No se crea "$1": El archivo $2 ya existe}, + 'symlink-fail1' => q{No fue posible desvincular "$1": $2}, + 'symlink-fail2' => q{No pude crear enlace simbolico de $1 a $2: $3}, + 'symlink-name' => q{Este comando no va a funcionar a menos que el programa tenga la palabra "postgres" en su nombre}, + 'symlink-unlink' => q{Desvinculando "$1":$2 }, + 'table' => q{Tabla}, + 'testmode-end' => q{END OF TEST MODE}, + 'testmode-fail' => q{Connexión fallida: $1 $2}, + 'testmode-norun' => q{No puede ejecutar "$1" en $2: versión debe ser >= $3, pero es $4}, + 'testmode-noset' => q{No puede ejecutar "$1" en $2: la opción $3 no está activa}, + 'testmode-nover' => q{Could not find version for $1}, + 'testmode-ok' => q{Connection ok: $1}, + 'testmode-start' => q{BEGIN TEST MODE}, + 'time-day' => q{día}, + 'time-days' => q{días}, + 'time-hour' => q{hora}, + 'time-hours' => q{horas}, + 'time-minute' => q{minuto}, + 'time-minutes' => q{minutos}, + 'time-month' => q{mes}, + 'time-months' => q{meses}, + 'time-second' => q{segundo}, + 'time-seconds' => q{segundos}, + 'time-week' => q{semana}, + 'time-weeks' => q{semanas}, + 'time-year' => q{año}, + 'time-years' => q{años}, + 'timesync-diff' => q{diff}, + 'timesync-msg' => q{timediff=$1 BD=$2 Local=$3}, + 'transactions' => q{transacciones}, + 'trigger-msg' => q{Disparadores desactivados: $1}, + 'txn-time' => q{transaction_time}, + 'txnidle-count-msg' => q{Total transacciones inactivas: $1}, + 'txnidle-count-none' => q{no más de $1 transacciones inactivas}, + 'txnidle-for-msg' => q{$1 transacciones inactivas mayores que $2s, más larga: $3s$4 $5}, + 'txnidle-msg' => q{transacción inactiva más larga: $1s$2 $3}, + 'txnidle-none' => q{no hay transacciones inactivas}, + 'txntime-count-msg' => q{Total de transacciones: $1}, + 'txntime-count-none' => q{no más que $1 transacciones}, + 'txntime-for-msg' => q{$1 transacciones más largas que $2s, más larga: $3s$4 $5}, + 'txntime-msg' => q{transacción más larga: $1s$2 $3}, + 'txntime-none' => q{No hay transacciones}, + 'txnwrap-cbig' => q{El valor 'critical' debe ser menor a 2000 millones}, + 'txnwrap-wbig' => q{El valor 'warning' debe ser menor a 2000 millones}, + 'unknown-error' => q{Error desconocido}, + 'usage' => qq{\nUso: \$1 \n Pruebe "\$1 --help" para obtener lista completa de opciones\n Pruebe "\$1 --man" para acceder al manual completo\n}, + 'user' => q{Usuario}, + 'username' => q{nombre-de-usuario}, + 'vac-nomatch-a' => q{No hay tablas coincidentes que hayan sido analizadas}, + 'vac-nomatch-v' => q{No hay tablas coincidentes que hayan sido vaciadas}, + 'version' => q{versión $1}, + 'version-badmrtg' => q{Argumento de versión mrtg inválido}, + 'version-fail' => q{versión $1, pero se esperaba $2}, + 'version-ok' => q{versión $1}, + 'wal-numfound' => q{Archivos WAL encontrados: $1}, + 'wal-numfound2' => q{Archivos WAL "$2" encontrados: $1}, +}, 'fr' => { 'address' => q{adresse}, 'age' => q{âge}, @@ -400,10 +656,13 @@ package check_postgres; 'fsm-page-msg' => q{emplacements de pages utilisés par la FSM : $1 sur $2 ($3%)}, 'fsm-rel-highver' => q{Ne peut pas vérifier fsm_relations sur des serveurs en version 8.4 ou ultérieure}, 'fsm-rel-msg' => q{relations tracées par la FSM : $1 sur $2 ($3%)}, +'hs-future-replica' => q{Slave reporting master server clock is ahead, check time sync}, 'hs-no-role' => q{Pas de couple ma??tre/esclave}, 'hs-no-location' => q{N'a pas pu obtenir l'emplacement courant dans le journal des transactions sur $1}, 'hs-receive-delay' => q{délai de réception}, 'hs-replay-delay' => q{délai de rejeu}, +'hs-time-delay' => q{time_delay}, +'hs-time-version' => q{Database must be version 9.1 or higher to check slave lag by time}, 'index' => q{Index}, 'invalid-option' => q{Option invalide}, 'invalid-query' => q{Une requête invalide a renvoyé : $1}, @@ -605,10 +864,6 @@ package check_postgres; 'backends-po' => q{tut mir leid, schon zu viele Verbindungen}, 'checkpoint-po' => q{Zeit des letzten Checkpoints:}, }, -'es' => { - 'backends-po' => q{lo siento, ya tenemos demasiados clientes}, - 'checkpoint-po' => q{Instante de �ltimo checkpoint:}, -}, 'fa' => { 'checkpoint-po' => q{زمان آخرین وارسی:}, }, @@ -920,7 +1175,8 @@ package check_postgres; ## These options are multiples ('@s') for my $arr (qw/include exclude includeuser excludeuser host port - dbuser dbname dbpass dbservice schema/) { + dbuser dbname dbpass dbservice schema excludeapp + includeapp/) { next if $name ne $arr and $name ne "${arr}2"; push @{$tempopt{$name}} => $value; ## Don't set below as a normal value @@ -961,6 +1217,8 @@ package check_postgres; 'exclude=s@', 'includeuser=s@', 'excludeuser=s@', + 'excludeapp=s@', + 'includeapp=s@', 'host|dbhost|H|dbhost1|H1=s@', 'port|dbport|p|port1|dbport1|p1=s@', @@ -988,6 +1246,7 @@ package check_postgres; 'filter=s@', ## used by same_schema only 'suffix=s', ## used by same_schema only 'replace', ## used by same_schema only + 'lsfunc=s', ## used by wal_files and archive_ready ); die $USAGE if ! keys %opt and ! @ARGV; @@ -1224,6 +1483,8 @@ package check_postgres; --exclude=name(s) items to specifically exclude (e.g. tables), depends on the action --includeuser=include objects owned by certain users --excludeuser=exclude objects owned by certain users + --excludeapp=exclude objects by application_name + --includeapp=include objects by application_name Other options: --assume-standby-mode assume that server in continious WAL recovery mode @@ -1871,6 +2132,52 @@ sub finishup { } } +our $APPWHERECLAUSE = ''; +if ($opt{includeapp}) { + my %applist; + for my $app (@{$opt{includeapp}}) { + for my $a2 (split /,/ => $app) { + $applist{$a2}++; + } + } + my $safeapp; + if (1 == keys %applist) { + ($safeapp = each %applist) =~ s/'/''/g; + $APPWHERECLAUSE = " AND application_name = '$safeapp'"; + } + else { + $APPWHERECLAUSE = ' AND application_name IN ('; + for my $app (sort keys %applist) { + ($safeapp = $app) =~ s/'/''/g; + $APPWHERECLAUSE .= "'$safeapp',"; + } + chop $APPWHERECLAUSE; + $APPWHERECLAUSE .= ')'; + } +} +elsif ($opt{excludeapp}) { + my %applist; + for my $app (@{$opt{excludeapp}}) { + for my $a2 (split /,/ => $app) { + $applist{$a2}++; + } + } + my $safeapp; + if (1 == keys %applist) { + ($safeapp = each %applist) =~ s/'/''/g; + $APPWHERECLAUSE = " AND application_name <> '$safeapp'"; + } + else { + $APPWHERECLAUSE = ' AND application_name NOT IN ('; + for my $app (sort keys %applist) { + ($safeapp = $app) =~ s/'/''/g; + $APPWHERECLAUSE .= "'$safeapp',"; + } + chop $APPWHERECLAUSE; + $APPWHERECLAUSE .= ')'; + } +} + ## Check number of connections, compare to max_connections check_backends() if $action eq 'backends'; @@ -3704,14 +4011,14 @@ sub check_bloat { ## Now the index, if it exists if ($index ne '?') { - my $nicename = perfname($index); + my $nicename = perfname("$schema.$index"); $perf{$iwb}{$nicename}++; - my $msg = msg('bloat-index', $dbname, $index, $irows, $ipages, $iotta, $ibloat, $iwb, $iws); + my $msg = msg('bloat-index', $dbname, $schema, $index, $irows, $ipages, $iotta, $ibloat, $iwb, $iws); my $ok = 1; my $iperbloat = $ibloat * 100; if ($MRTG) { - $stats{index}{"DB=$dbname INDEX=$index"} = [$iwb, $ibloat]; + $stats{index}{"DB=$dbname INDEX=$schema.$index"} = [$iwb, $ibloat]; next; } if ($critical->($iwb, $iperbloat)) { @@ -4430,7 +4737,7 @@ sub check_disk_space { ## Check log_directory: relative or absolute if (length $logdir) { - if ($logdir =~ /^\w/) { ## relative, check only if symlinked + if ($logdir =~ /^\w/ || $logdir =~ /^\.\//) { ## relative, check only if symlinked $logdir = "$datadir/$logdir"; if (-l $logdir) { my $linkdir = readlink($logdir); @@ -4809,12 +5116,12 @@ sub check_hot_standby_delay { my $replay = $db->{slurp}[0]{replay}; $time_delta = $db->{slurp}[0]{seconds}; - if (defined $receive) { + if (defined $receive and length $receive) { my ($a, $b) = split(/\//, $receive); $s_rec_offset = (hex('ff000000') * hex($a)) + hex($b); } - if (defined $replay) { + if (defined $replay and length $replay) { my ($a, $b) = split(/\//, $replay); $s_rep_offset = (hex('ff000000') * hex($a)) + hex($b); } @@ -4846,12 +5153,13 @@ sub check_hot_standby_delay { ## Compute deltas $db = $saved_db; - my $rec_delta = $moffset - $s_rec_offset; - my $rep_delta = $moffset - $s_rep_offset; + my ($rec_delta, $rep_delta); + $rec_delta = $moffset - $s_rec_offset if defined $s_rec_offset; + $rep_delta = $moffset - $s_rep_offset if defined $s_rep_offset; # Make sure it's always positive or zero - $rec_delta = 0 if $rec_delta < 0; - $rep_delta = 0 if $rep_delta < 0; + $rec_delta = 0 if defined $rec_delta and $rec_delta < 0; + $rep_delta = 0 if defined $rep_delta and $rep_delta < 0; if (defined $time_delta and $time_delta < 0) { add_unknown msg('hs-future-replica'); return; @@ -4861,10 +5169,14 @@ sub check_hot_standby_delay { {one => $rep_delta, two => $rec_delta, three => $time_delta} : {one => $rep_delta, two => $rec_delta}); - $db->{perf} = sprintf ' %s=%s;%s;%s ', - perfname(msg('hs-replay-delay')), $rep_delta, $warning, $critical; - $db->{perf} .= sprintf ' %s=%s;%s;%s', - perfname(msg('hs-receive-delay')), $rec_delta, $warning, $critical; + if (defined $rep_delta) { + $db->{perf} = sprintf ' %s=%s;%s;%s ', + perfname(msg('hs-replay-delay')), $rep_delta, $warning, $critical; + } + if (defined $rec_delta) { + $db->{perf} .= sprintf ' %s=%s;%s;%s', + perfname(msg('hs-receive-delay')), $rec_delta, $warning, $critical; + } if ($psql_version >= 9.1) { $db->{perf} .= sprintf ' %s=%s;%s;%s', perfname(msg('hs-time-delay')), $time_delta, $wtime, $ctime; @@ -7599,7 +7911,7 @@ sub check_txn_idle { $SQL = q{SELECT datname, datid, procpid AS pid, usename, client_addr, xact_start, current_query AS current_query, '' AS state, }. q{CASE WHEN client_port < 0 THEN 0 ELSE client_port END AS client_port, }. qq{COALESCE(ROUND(EXTRACT(epoch FROM now()-$start)),0) AS seconds }. - qq{FROM pg_stat_activity WHERE ($clause)$USERWHERECLAUSE }. + qq{FROM pg_stat_activity WHERE ($clause)$USERWHERECLAUSE $APPWHERECLAUSE }. q{ORDER BY xact_start, query_start, procpid DESC}; ## Craft an alternate version for old servers that do not have the xact_start column: ($SQL2 = $SQL) =~ s/xact_start/query_start AS xact_start/; @@ -7609,7 +7921,7 @@ sub check_txn_idle { $SQL2 = $SQL = q{SELECT datname, datid, procpid AS pid, usename, client_addr, current_query AS current_query, '' AS state, }. q{CASE WHEN client_port < 0 THEN 0 ELSE client_port END AS client_port, }. qq{COALESCE(ROUND(EXTRACT(epoch FROM now()-$start)),0) AS seconds }. - qq{FROM pg_stat_activity WHERE ($clause)$USERWHERECLAUSE }. + qq{FROM pg_stat_activity WHERE ($clause)$USERWHERECLAUSE $APPWHERECLAUSE }. q{ORDER BY query_start, procpid DESC}; } @@ -7652,13 +7964,13 @@ sub check_txn_idle { my $st = $r->{state} || ''; ## Return unknown if we cannot see because we are a non-superuser - if ($cq =~ /insufficient/o) { + if ($cq =~ /^insufficient/o) { add_unknown msg('psa-nosuper'); return; } ## Return unknown if stats_command_string / track_activities is off - if ($cq =~ /disabled/o or $cq =~ //) { + if ($cq =~ /^disabled/o or $cq =~ /^/) { add_unknown msg('psa-disabled'); return; } @@ -7935,8 +8247,11 @@ sub check_wal_files { my ($warning, $critical) = validate_range($arg); + my $lsfunc = $opt{lsfunc} || 'pg_ls_dir'; + my $lsargs = $opt{lsfunc} ? "" : "'pg_xlog$subdir'"; + ## Figure out where the pg_xlog directory is - $SQL = qq{SELECT count(*) AS count FROM pg_ls_dir('pg_xlog$subdir') WHERE pg_ls_dir ~ E'^[0-9A-F]{24}$extrabit\$'}; ## no critic (RequireInterpolationOfMetachars) + $SQL = qq{SELECT count(*) AS count FROM $lsfunc($lsargs) WHERE $lsfunc ~ E'^[0-9A-F]{24}$extrabit\$'}; ## no critic (RequireInterpolationOfMetachars) my $info = run_command($SQL, {regex => qr[\d] }); @@ -7974,7 +8289,7 @@ =head1 NAME B - a Postgres monitoring script for Nagios, MRTG, Cacti, and others -This documents describes check_postgres.pl version 2.21.0 +This documents describes check_postgres.pl version 2.22.0 =head1 SYNOPSIS @@ -8327,7 +8642,7 @@ =head2 B (C) Checks how many WAL files with extension F<.ready> exist in the F directory, which is found -off of your B. This action must be run as a superuser, in order to access the +off of your B. If the I<--lsfunc> option is not used then this action must be run as a superuser, in order to access the contents of the F directory. The minimum version to use this action is Postgres 8.1. The I<--warning> and I<--critical> options are simply the number of F<.ready> files in the F directory. @@ -8337,9 +8652,26 @@ =head2 B If the archive command fail, number of WAL in your F directory will grow until exhausting all the disk space and force PostgreSQL to stop immediately. -Example 1: Check that the number of ready WAL files is 10 or less on host "pluto" +To avoid connecting as a database superuser, a wrapper function around +C should be defined as a superuser with SECURITY DEFINER, +and the I<--lsfunc> option used. This example function, if defined by +a superuser, will allow the script to connect as a normal user +I with I<--lsfunc=ls_archive_status_dir> + + BEGIN; + CREATE FUNCTION ls_archive_status_dir() + RETURNS SETOF TEXT + AS $$ SELECT pg_ls_dir('pg_xlog/archive_status') $$ + LANGUAGE SQL + SECURITY DEFINER; + REVOKE ALL ON FUNCTION ls_archive_status_dir() FROM PUBLIC; + GRANT EXECUTE ON FUNCTION ls_archive_status_dir() to nagios; + COMMIT; + +Example 1: Check that the number of ready WAL files is 10 or less on host "pluto", +using a wrapper function C to avoid the need for superuser permissions - check_postgres_archive_ready --host=pluto --critical=10 + check_postgres_archive_ready --host=pluto --critical=10 --lsfunc=ls_archive_status_dir For MRTG output, reports the number of ready WAL files on line 1. @@ -8857,7 +9189,7 @@ =head2 B to it. The slave server must be in hot_standby (e.g. read only) mode, therefore the minimum version to use this action is Postgres 9.0. The I<--warning> and I<--critical> options are the delta between the xlog locations. Since these values are byte offsets in the WAL they should match the expected transaction volume -of your application to prevent false postives or negatives. +of your application to prevent false positives or negatives. The first "--dbname", "--host", and "--port", etc. options are considered the master; the second belongs to the slave. @@ -8869,7 +9201,7 @@ =head2 B form 'I and I