--- check_pgsql.original 2006-03-07 12:40:11.000000000 -0700 +++ check_pgsql.c 2006-03-07 12:47:48.000000000 -0700 @@ -21,5 +21,5 @@ const char *progname = "check_pgsql"; const char *revision = "$Revision: 1.31 $"; -const char *copyright = "1999-2004"; +const char *copyright = "1999-2006"; const char *email = "nagiosplug-devel@lists.sourceforge.net"; @@ -36,5 +36,7 @@ DEFAULT_PORT = 5432, DEFAULT_WARN = 2, - DEFAULT_CRIT = 8 + DEFAULT_CRIT = 8, + DEFAULT_WARNING_XID_AGE = 500000000, /* 500M */ + DEFAULT_CRITICAL_XID_AGE = 1000000000 /* 1B */ }; @@ -58,4 +60,6 @@ double twarn = (double)DEFAULT_WARN; double tcrit = (double)DEFAULT_CRIT; +int warning_xid_age = DEFAULT_WARNING_XID_AGE; +int critical_xid_age = DEFAULT_CRITICAL_XID_AGE; PGconn *conn; @@ -124,4 +128,9 @@ int elapsed_time; int status = STATE_UNKNOWN; + int i,j; + int nFields; + const char *paramValues[1]; + char param[100]; + PGresult *res; /* begin, by setting the parameters for a backend connection if the @@ -167,8 +176,43 @@ } else { + snprintf(param, 100, "%d", warning_xid_age); + paramValues[0] = param; + res = PQexecParams(conn, + "SELECT datname,age(datvacuumxid) FROM pg_database WHERE age(datvacuumxid) > $1 ORDER BY age(datvacuumxid) DESC", + 1, NULL, paramValues, NULL, NULL, 0); + if (PQresultStatus(res) != PGRES_TUPLES_OK) + { + printf (_("CRITICAL - error '%s' running query on '%s' (%s).\n"), + PQerrorMessage(conn), dbName, PQerrorMessage (conn)); + PQclear (res); + PQfinish (conn); + return STATE_CRITICAL; + } + + if (PQntuples(res) > 0) + { + j = atoi(PQgetvalue(res, 0, 1)); + + printf (_("%s: Databases in danger of XID wraparound: "), + ((j > critical_xid_age) ? "CRITICAL" : "WARNING")); + + for (i = 0; i < PQntuples(res); i++) + { + printf (_("%s age %s"), PQgetvalue(res, i, 0), PQgetvalue(res, i, 1)); + if (i < PQntuples(res) - 1) + printf (_(",")); + else + printf (_("\n\n")); + } + PQclear (res); + PQfinish (conn); + return (j > critical_xid_age) ? STATE_CRITICAL : STATE_WARNING; + } + + PQclear(res); status = STATE_OK; } PQfinish (conn); - printf (_(" %s - database %s (%d sec.)|%s\n"), + printf (_(" %s - database %s (%ds, XIDs OK)|%s\n"), state_text(status), dbName, elapsed_time, fperfdata("time", elapsed_time, "s", @@ -198,9 +242,11 @@ {"port", required_argument, 0, 'P'}, {"database", required_argument, 0, 'd'}, + {"warnxid", required_argument, 0, 'x'}, + {"critxid", required_argument, 0, 'y'}, {0, 0, 0, 0} }; while (1) { - c = getopt_long (argc, argv, "hVt:c:w:H:P:d:l:p:a:", + c = getopt_long (argc, argv, "hVt:c:w:H:P:d:l:p:a:x:y:", longopts, &option); @@ -259,4 +305,16 @@ pguser = optarg; break; + case 'x': + if (!is_intpos(optarg)) + usage2 (_("Warning XID age must be a positive integer"), optarg); + else + warning_xid_age = atoi(optarg); + break; + case 'y': + if (!is_intpos(optarg)) + usage2 (_("Critical XID age must be a positive integer"), optarg); + else + critical_xid_age = atoi(optarg); + break; case 'p': /* authentication password */ case 'a': @@ -403,11 +461,17 @@ printf (_("\ - -d, --database=STRING\n\ + -d, --database=STRING\n\ Database to check (default: %s)\n\ - -l, --logname = STRING\n\ + -l, --logname = STRING\n\ Login name of user\n\ - -p, --password = STRING\n\ + -p, --password = STRING\n\ Password (BIG SECURITY ISSUE)\n"), DEFAULT_DB); + printf (_("\ + -x, --warnxid=INTEGER\n\ + Minimum XID age to generate a warning (default: %d)\n\ + -y, --critxid=INTEGER\n\ + Minimum XID age to generate a critical (default: %d)\n"), DEFAULT_WARNING_XID_AGE, DEFAULT_CRITICAL_XID_AGE); + printf (_(UT_WARN_CRIT)); @@ -442,4 +506,5 @@ printf ("\ Usage: %s [-H ] [-P ] [-c ] [-w ]\n\ - [-t ] [-d ] [-l ] [-p ]\n", progname); + [-t ] [-d ] [-l ] [-p ]\n\ + [-x ] [-y ]\n", progname); }