aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2020-02-14 12:55:04 +0200
committerSergey Poznyakoff <gray@gnu.org>2020-02-14 15:31:19 +0200
commita744738cb14e7d0c9cb5d4ea6d64247db5a8822c (patch)
treee8359c41040a8aa9ff338d7ba1d141da7f318f53
parent4263bf8b57b7d8a0b5f73a586c55e9ee2a07b6ca (diff)
downloadping903-a744738cb14e7d0c9cb5d4ea6d64247db5a8822c.tar.gz
ping903-a744738cb14e7d0c9cb5d4ea6d64247db5a8822c.tar.bz2
Version 0.2v0.2
* NEWS: Update. * README: Update. * THANKS: Update. * doc/ping903.8: Spell checking. * doc/ping903q.1: Likewise. * src/Makefile.am: Distribute ping903.conf * src/ping903.h (HOST_STAT_INIT) (HOST_STAT_VALID,HOST_STAT_PENDING) (HOST_STAT_INVALID): New constants. (host_stat): New member "status". (host_stat_is_valid): Rewrite using status. * src/ping903q.c: "status" is string now. Handle particular values. * src/pinger.c: Maintain current status of each host_stat structure in the status member. (host_stat): Mark object as valid. (host_reset): Update status. (get_host_stat): Report object validity in the "validity" member, and its current status in "status" (string). * src/json.c: Implement json_value_copy. * src/json.h (json_value_copy): New proto. * src/ping903.c (ept_config): Return particular setting, if so requested.
-rw-r--r--NEWS9
-rw-r--r--README357
-rw-r--r--THANKS2
-rw-r--r--configure.ac2
-rw-r--r--doc/ping903.86
-rw-r--r--doc/ping903q.12
-rw-r--r--src/Makefile.am2
-rw-r--r--src/json.c126
-rw-r--r--src/json.h1
-rw-r--r--src/ping903.c29
-rw-r--r--src/ping903.h11
-rw-r--r--src/ping903q.c12
-rw-r--r--src/pinger.c24
13 files changed, 557 insertions, 26 deletions
diff --git a/NEWS b/NEWS
index 3f433a4..5cc9052 100644
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,12 @@
-Ping903 -- history of user-visible changes. 2020-02-07
+Ping903 -- history of user-visible changes. 2020-02-14
See the end of file for copying conditions.
-Please send Ping903 bug reports to <gray@gnu.org.ua>
+Please send Ping903 bug reports to <gray@gnu.org>
+
+Version 0.2, 2020-02-14
+
+* Initial release
-No news is good news.
=========================================================================
Copyright information:
diff --git a/README b/README
index 47d21b5..b80f596 100644
--- a/README
+++ b/README
@@ -1 +1,356 @@
-FIXME: Nothing so far \ No newline at end of file
+Ping903 README
+See the end of file for copying conditions.
+
+* Overview
+
+Ping903 is designed to periodically monitor a very large number of
+remote hosts using ICMP ECHO packets. The system is built using the
+client-server architecture. The main component (ping903) is a daemon
+that sits in memory and wakes up periodically to send certain number
+of ICMP echo packets to a preconfigured number of hosts and to collect
+replies. The round-trip statistics it collects is made available via
+REST API.
+
+The daemon reads its settings from a plain text configuration file.
+Most settings have sensible defaults, the only thing that the user
+must supply is a list of IP addresses to monitor. This list is
+referred to in this document as "ip-list".
+
+A simple command line client utility (ping903q) allows the user to
+communicate with the daemon, obtaining the needed information about
+each host in particular, or all monitored hosts at once. This utility
+can operate in several modes. In particular, it can be used as
+Nagios external check tool, instead of the standard check_ping tool.
+
+* Installation
+
+To build ping903 you will need GNU Libmicrohttpd library[3]. It is
+available for download from http://ftp.gnu.org/gnu/libmicrohttpd.
+
+When building from source package, usual incantations apply:
+
+ ./configure
+ make
+ make install
+
+This will install the package under /usr/local. That is, the server
+will be installed as /usr/local/sbin/ping903, the client program as
+/usr/local/bin/ping903q, etc. You can give a number of options to
+./configure in order to customize your installation, in particular to
+alter the default installation paths. For example, to install to the
+/usr file hierarchy, use
+
+ ./configure --prefix=/usr
+
+Please refer to the INSTALL document in this directory for a
+discussion of available options to configure and their effect.
+
+After installing the package, copy the file src/ping903.conf to
+/etc/ping903.conf and edit it to your liking. This file contains
+configuration settings that control the behavior of the server daemon
+and, to a certain extent, that of a query tool. The file contains
+short annotations before each statement to help you navigate in it.
+You will find a detailed discussion of the configuration file in the
+manpage ping903.conf(5). What follows is a short outline intended
+for quick start:
+
+At the very beginning you can leave most settings at their default
+values. The only statement that you must provide in your
+configuration is
+
+ ip-list FILENAME
+
+Replace FILENAME with the name of the file with IP addresses to
+monitor. In this file, each IP address must occupy a separate line.
+Empty lines, leading and trailing whitespace and comments are ignored.
+Comments are introduced by a hash sign (#) appearing as the first
+non-whitespace character on a line.
+
+You are not required to keep all your IP addresses in a single file.
+If necessary, you can scatter them among several files and list each
+of them in a separate ip-list statement.
+
+Normally, the ip-list file should contain IP addresses of the hosts to
+monitor. It is OK, however, to use symbolic DNS names, too. If a
+hostname resolves to a single A record such usage is equivalent to
+placing that IP in the ip-list. However, if the hostnames resolves to
+multiple IPs, only first one will be used.
+
+By default, the server will wake up each minute and send 10 echo
+requests within 1 second intervals to each registered IP. If the
+number of collected replies is less than 7, the IP will be declared as
+dead ("alive": false, in the returned JSON). Otherwise it is
+considered alive ("alive": true).
+
+The following settings control these parameters:
+
+ probe-interval N
+ Interval between wake-ups in seconds.
+ Default N=60.
+
+ ping-count N
+ Number of ICMP packets to send within each probe.
+ Default N=10.
+
+ ping-interval N
+ Interval in seconds between two sequential echo requests.
+ Default N=1.
+
+ tolerance N
+ Maximum number of lost requests after which the host is considered
+ dead.
+ Default N=3.
+
+Another statement worth your attention is "listen". It configures the
+IP address and port on which the server will listen for incoming HTTP
+requests. The default is localhost:8080. Change this if this port is
+already occupied on your system.
+
+The access to the HTTP interface is protected by the default access
+control library (the files /etc/hosts.allow and /etc/hosts.deny).
+Refer to hosts_access(3) for details.
+
+When you have configured the daemon, start it. Just run ping903.
+Check if there are no errors (on the standard error and in the
+syslog channel "daemon"). To verify if it is operational, run
+
+ curl http://localhost:8080/config
+
+This should return the running configuration.
+
+Within next probe-interval seconds the server will collect enough
+statistics to answer your queries. You can request information about
+any particular IP from your ip-list by running
+
+ ping903q IP
+
+This will return the current status of the IP, e.g.
+
+ $ ping903q 203.0.113.1
+ 203.0.113.1 is alive
+
+To get the detailed statistics use the -v option. The result will be
+formatted in a ping(8)-like manner:
+
+ $ ping903q -v 203.0.113.1
+ 203.0.113.1 is alive
+ --- 203.0.113.1 ping statistics ---
+ 10 packets transmitted, 10 received, 0% packet loss, time 9414ms
+ rtt min/avg/max/mdev = 41.212/41.265/41.374/0.046 ms
+
+You can check the current status of all hosts by running
+
+ $ ping903q
+
+without arguments. Note, that depending on your settings the output
+can be huge.
+
+Please refer to ping903q(1), for a detailed discussion of the tool.
+
+* Nagios external check
+
+The ping903q tool can be used as a Nagios external check program. The
+following snipped illustrates the simple Nagios configuration that
+makes use of it:
+
+ # Define the check_ping903 command
+ define command {
+ command_name check_ping903
+ command_line /usr/bin/ping903q -r -H $HOSTADDRESS$ -w $ARG1$ -c $ARG2$
+ }
+
+ # Define the service using the new command
+ define service {
+ host_name server.example.net
+ address 203.0.113.1
+ service_description Server status
+ check_command check_ping903!200.0,20%!600.0,60%
+ check_interval 5
+ retry_interval 1
+ }
+
+* Installation from a git clone
+
+If you are building from a clone of the Git repository, you will need
+GNU autotools to bootstrap the package first. Run
+
+ ./bootstrap
+
+in the top level source directory. This will create the configure
+script and populate the directory with the missing files. Then proceed
+as described above.
+
+* REST API
+
+The default channel for communication with the ping903 daemon is the
+HTTP socket open on localhost port 8080. Only GET requests are
+allowed. The following endpoints are provided:
+
+** /host/NAME
+
+NAME is the IP address or hostname. The server will look up this
+string in the list of configured hosts and, if found, return the
+statistics information for that host. Note that NAME is treated as a
+character string and must coincide exactly with the IP or hostname as
+it was supplied in configuration. In particular, if a host was
+specified by its symbolic DNS name in the configuration, exactly that
+name must be used in URL to obtain statistics for that host. If you
+wish to use IP, see the </ip> or </match> endpoints, discussed below.
+
+On success a JSON object is returned. The following keys are defined
+in that object:
+
+- "name": string
+
+The IP or hostname of the host under which it was supplied in the
+ip-list.
+
+- "validity": boolean
+
+Status of this record. If false, the data has not been collected yet
+or the host is unreachable. More detailed information is available in
+the "status" member (see below). If "validity" is false, only the
+following keys are warranted to be present in the object: "name",
+"validity", "status", and "xmit-timestamp". If it is true, full
+statistics is available as described below.
+
+- "status": string
+
+Detailed status of the object. Following values are defined:
+
+ "init"
+ Initial state: data are being collected ("validity":false).
+ "valid"
+ The object is valid and its statistics is reliable ("validity": true).
+ "pending"
+ The object is valid, it contains reliable statistics. The host
+ is being probed at the moment and the object will be updated
+ soon ("validity": true).
+ "invalid"
+ Host is unreachable. No statistics available ("validity": false).
+
+- "xmit-timestamp": number
+
+Time (the number of seconds since the Epoch) when the last ICMP
+ECHO request was transmitted.
+
+- "start-timestamp": number
+
+Time when the recent probe sequence was initiated.
+
+- "stop-timestamp": number
+
+Time when the recent probe sequence was finished.
+
+- "xmit": number
+
+Number of ICMP ECHO requests transmitted during the probe.
+
+- "recv": number
+
+Number of ICMP ECHO responses received during the probe.
+
+- "loss": number
+
+Percentage of lost packets.
+
+- "tmin": number
+
+Minimal round-trip time observed during the probe.
+
+- "tmax": number
+
+Maximal round-trip time observed during the probe.
+
+- "avg": number
+
+Average round-trip time.
+
+- "stddev": number
+
+Standard deviation of round-trip times.
+
+- "alive": boolean
+
+Host status computed as a result of the probe. It is true, if the
+difference between "xmit" and "recv" parameters is less than the
+"tolerance" configuration setting, and false otherwise.
+
+Example of the returned JSON for a reachable host:
+
+ {
+ "alive":true,
+ "avg":25.85150,
+ "loss":0.00000,
+ "name":"203.0.113.1",
+ "recv":10.00000,
+ "start-timestamp":1581666176.01285,
+ "status":true,
+ "stddev":0.03201,
+ "stop-timestamp":1581666185.27210,
+ "tmax":25.91400,
+ "tmin":25.81200,
+ "xmit":10.00000,
+ "xmit-timestamp":1581666185.24628
+ }
+
+Example of the returned JSON for an unreachable host:
+
+ {
+ "name":"203.0.113.2",
+ "status":false,
+ "xmit-timestamp":1581666176.01373
+ }
+
+** /host
+
+Return statistics for all monitored hosts. The result is returned as
+an array of JSON objects described above.
+
+This is an experimental endpoint. Be careful with it, as it may cause
+considerable strain on the server.
+
+** /ip/ADDR
+
+Request statistics about a particular IP address. The response is the
+same as for </host/NAME>. Use this API if hostnames are used in your
+ip-list and you need to request statistics using an IP as opposed to
+the hostname.
+
+** /match/NAME-OR-IP
+
+Return host names that correspond to NAME-OR-IP (a JSON array of
+strings). If no matches found, empty array is returned. Multiple
+entries can be returned if NAME-OR-IP is a hostname that has multiple
+DNS A records, several of which are registered in the ip-list.
+
+** /config
+
+Return current server configuration as a JSON object.
+
+** /config/KEYWORD
+
+Return the value of a particular configuration setting.
+
+* Copyright information:
+
+Copyright (C) 2020 Sergey Poznyakoff
+
+ Permission is granted to anyone to make or distribute verbatim copies
+ of this document as received, in any medium, provided that the
+ copyright notice and this permission notice are preserved,
+ thus giving the recipient permission to redistribute in turn.
+
+ Permission is granted to distribute modified versions
+ of this document, or of portions of it,
+ under the above conditions, provided also that they
+ carry prominent notices stating who last changed them.
+
+Local Variables:
+mode: outline
+paragraph-separate: "[ ]*$"
+version-control: never
+End:
+
+
+
diff --git a/THANKS b/THANKS
index 47d21b5..266b7cd 100644
--- a/THANKS
+++ b/THANKS
@@ -1 +1 @@
-FIXME: Nothing so far \ No newline at end of file
+Thanks to Peter Markeloff for urging me to write the tool.
diff --git a/configure.ac b/configure.ac
index 906d459..3105332 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,7 +15,7 @@
# along with Ping903. If not, see <http://www.gnu.org/licenses/>.
AC_PREREQ([2.69])
-AC_INIT([Ping903], [0.1], [gray@gnu.org],
+AC_INIT([Ping903], [0.2], [gray@gnu.org],
[ping903],
[https://puszcza.gnu.org.ua/projects/ping903/])
AC_CONFIG_SRCDIR([src/main.c])
diff --git a/doc/ping903.8 b/doc/ping903.8
index b18bd54..0649aa2 100644
--- a/doc/ping903.8
+++ b/doc/ping903.8
@@ -13,7 +13,7 @@
.\"
.\" You should have received a copy of the GNU General Public License
.\" along with Ping903. If not, see <http://www.gnu.org/licenses/>.
-.TH PING903 8 "February 13, 2020" "PING903" "System Administration"
+.TH PING903 8 "February 14, 2020" "PING903" "System Administration"
.SH NAME
ping903 \- high-performance ICMP monitoring daemon
.SH SYNOPSIS
@@ -28,7 +28,7 @@ predefined number of ICMP requests sent with certain interval between
them. Probes are repeated periodically.
.PP
The round-trip statistics is collected for each host and is available
-for querying via RESTful API. A separate querying utility
+for querying via REST API. A separate querying utility
.BR ping903q (1)
is provided, which allows the user to request the information about
each particular host, or all monitored hosts at once.
@@ -44,7 +44,7 @@ The monitoring process, in turn, is responsible for periodic polling
of the configured hosts, maintaining the statistics information and
answering the REST requests.
.PP
-The progam logs its activities using syslog channel \fBdaemon\fR.
+The program logs its activities using syslog channel \fBdaemon\fR.
.PP
The list of IP addresses to monitor is supplied by an \fIip\-list\fR
file specified in the configuration. Probes for each IP from the list
diff --git a/doc/ping903q.1 b/doc/ping903q.1
index 326ca81..ab57518 100644
--- a/doc/ping903q.1
+++ b/doc/ping903q.1
@@ -105,7 +105,7 @@ Print program version, copyright information, and exit.
.B \-v
Turn on verbose output.
.SS Options specific for Nagios check mode
-The presense of any of these options switches \fBping903q\fR to Nagios
+The presence of any of these options switches \fBping903q\fR to Nagios
check mode. For this mode to succeed, all three options must be specified.
.TP
\fB\-H \fIHOST\fR
diff --git a/src/Makefile.am b/src/Makefile.am
index cc6f1ff..3fcec9f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -34,3 +34,5 @@ LDADD = ./libping903.a
noinst_LIBRARIES = libping903.a
libping903_a_SOURCES = json.c json.h mem.c logger.c defs.h
+EXTRA_DIST = ping903.conf
+
diff --git a/src/json.c b/src/json.c
index 370d830..b7ad44a 100644
--- a/src/json.c
+++ b/src/json.c
@@ -86,6 +86,12 @@ json_value_create(int type)
typedef void (*json_format_fun)(struct json_format *, struct json_value *, size_t);
typedef void (*json_free_fun)(struct json_value *);
+typedef int (*json_copy_fun)(struct json_value *, struct json_value **);
+
+static int json_copy_generic(struct json_value *, struct json_value **);
+static int json_copy_string(struct json_value *, struct json_value **);
+static int json_copy_array(struct json_value *, struct json_value **);
+static int json_copy_object(struct json_value *, struct json_value **);
static void json_format_null(struct json_format *, struct json_value *,
size_t level);
@@ -108,21 +114,27 @@ static void json_free_object(struct json_value *);
static struct json_value_meth {
json_format_fun format_fun;
json_free_fun free_fun;
+ json_copy_fun copy_fun;
} json_value_meth[] = {
- [json_null] = { json_format_null, NULL },
- [json_bool] = { json_format_bool, NULL },
- [json_number] = { json_format_number, NULL },
- [json_string] = { json_format_string, json_free_string },
- [json_array] = { json_format_array, json_free_array },
- [json_object] = { json_format_object, json_free_object }
+ [json_null] = { json_format_null, NULL, json_copy_generic },
+ [json_bool] = { json_format_bool, NULL, json_copy_generic },
+ [json_number] = { json_format_number, NULL, json_copy_generic },
+ [json_string] = { json_format_string, json_free_string, json_copy_string },
+ [json_array] = { json_format_array, json_free_array, json_copy_array },
+ [json_object] = { json_format_object, json_free_object, json_copy_object }
};
static inline int
+is_valid_type(int type)
+{
+ return type >= 0
+ && type < sizeof(json_value_meth) / sizeof(json_value_meth[0]);
+}
+
+static inline int
is_valid_value(struct json_value *obj)
{
- return obj
- && obj->type >= 0
- && obj->type < sizeof(json_value_meth)/sizeof(json_value_meth[0]);
+ return obj && is_valid_type(obj->type);
}
void
@@ -136,6 +148,17 @@ json_value_free(struct json_value *obj)
}
int
+json_value_copy(struct json_value *val, struct json_value **new_val)
+{
+ if (is_valid_value(val))
+ return json_value_meth[val->type].copy_fun(val, new_val);
+ else {
+ errno = EINVAL;
+ return -1;
+ }
+}
+
+int
json_value_format(struct json_value *obj, struct json_format *fmt, size_t level)
{
++level;
@@ -151,6 +174,30 @@ json_value_format(struct json_value *obj, struct json_format *fmt, size_t level)
return -1;
}
+static int
+json_copy_generic(struct json_value *val, struct json_value **ret_val)
+{
+ struct json_value *p;
+
+ if (!val) {
+ p = json_new_null();
+ if (!p)
+ return -1;
+ } else if (is_valid_type(val->type)) {
+ p = json_value_create(val->type);
+ if (p)
+ memcpy(&p->v, &val->v, sizeof(p->v));
+ } else {
+ errno = EINVAL;
+ }
+
+ if (!p)
+ return -1;
+
+ *ret_val = p;
+ return 0;
+}
+
/* Null value */
struct json_value *
json_new_null(void)
@@ -220,6 +267,20 @@ json_free_string(struct json_value *val)
free(val->v.s);
}
+static int
+json_copy_string(struct json_value *val, struct json_value **ret_val)
+{
+ struct json_value *newval = json_value_create(json_string);
+ if (!newval)
+ return -1;
+ if ((newval->v.s = strdup(val->v.s)) == NULL) {
+ free(newval);
+ return -1;
+ }
+ *ret_val = newval;
+ return 0;
+}
+
enum { ESCAPE, UNESCAPE };
static int
@@ -286,6 +347,32 @@ json_free_array(struct json_value *val)
free(val->v.a);
}
+static int
+json_copy_array(struct json_value *val, struct json_value **ret_val)
+{
+ struct json_value *newval;
+ size_t i;
+
+ newval = json_new_array();
+ if (!newval)
+ return -1;
+ if (!(newval->v.a->ov =
+ calloc(val->v.a->oc, sizeof(val->v.a->ov[0])))) {
+ free(newval);
+ return -1;
+ }
+ newval->v.a->oc = newval->v.a->on = val->v.a->oc;
+ for (i = 0; i < val->v.a->oc; i++) {
+ if (json_value_copy(val->v.a->ov[i], &newval->v.a->ov[i])) {
+ newval->v.a->oc = i;
+ json_value_free(newval);
+ return -1;
+ }
+ }
+ *ret_val = newval;
+ return 0;
+}
+
int
json_array_expand(struct json_value *jv)
{
@@ -411,6 +498,27 @@ json_free_object(struct json_value *val)
}
static int
+json_copy_object(struct json_value *val, struct json_value **ret_val)
+{
+ struct json_value *newval;
+ struct json_pair *p;
+
+ if (!(newval = json_new_object()))
+ return -1;
+ for (p = val->v.o->head; p; p = p->next) {
+ struct json_value *elt = NULL;
+
+ if (json_value_copy(p->v, &elt)
+ || json_object_set(newval, p->k, elt)) {
+ json_value_free(elt);
+ json_value_free(newval);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int
json_object_lookup_or_install(struct json_object *obj, char const *name,
int install,
struct json_pair **retval)
diff --git a/src/json.h b/src/json.h
index 8e4a169..f5ca92c 100644
--- a/src/json.h
+++ b/src/json.h
@@ -51,6 +51,7 @@ struct json_format
int json_value_format(struct json_value *obj, struct json_format *fmt,
size_t level);
void json_value_free(struct json_value *);
+int json_value_copy(struct json_value *val, struct json_value **new_val);
void *json_2nrealloc(void *p, size_t *pn, size_t s);
diff --git a/src/ping903.c b/src/ping903.c
index 99e3a80..4e5310f 100644
--- a/src/ping903.c
+++ b/src/ping903.c
@@ -263,10 +263,37 @@ ept_config(struct MHD_Connection *conn,
{
struct json_value *val;
+ while (*suffix == '/')
+ suffix++;
+
val = config_to_json();
if (!val)
return http_error(conn, method, url,
MHD_HTTP_INTERNAL_SERVER_ERROR);
+
+ if (*suffix) {
+ struct json_value *jv, *cp;
+ int ret;
+
+ if (json_object_get(val, suffix, &jv)) {
+ ret = http_error(conn, method, url,
+ (errno == ENOENT)
+ ? MHD_HTTP_NOT_FOUND
+ : MHD_HTTP_INTERNAL_SERVER_ERROR);
+ json_value_free(val);
+ return ret;
+ }
+
+ if (json_value_copy(jv, &cp)) {
+ ret = http_error(conn, method, url,
+ MHD_HTTP_INTERNAL_SERVER_ERROR);
+ json_value_free(val);
+ return ret;
+ }
+ json_value_free(val);
+ val = cp;
+ }
+
return httpd_json_response(conn, url, method, val);
}
@@ -375,7 +402,7 @@ struct endpoint {
};
static struct endpoint endpoint[] = {
- { "/config", EPT_EXACT, MHD_HTTP_METHOD_GET, ept_config },
+ { "/config", EPT_PREFIX, MHD_HTTP_METHOD_GET, ept_config },
{ "/host", EPT_PREFIX, MHD_HTTP_METHOD_GET, ept_host_stat },
{ "/ip", EPT_PREFIX, MHD_HTTP_METHOD_GET, ept_ip_stat },
{ "/match", EPT_PREFIX, MHD_HTTP_METHOD_GET, ept_ip_match },
diff --git a/src/ping903.h b/src/ping903.h
index 57123a1..5d8dd5b 100644
--- a/src/ping903.h
+++ b/src/ping903.h
@@ -61,7 +61,16 @@ int cf_syslog_facility(int mode, union cf_callback_arg *arg, void *data);
char *get_remote_ip(struct MHD_Connection *conn);
+enum {
+ HOST_STAT_INIT, /* Initial state: data are being collected */
+ HOST_STAT_VALID, /* The record is valid */
+ HOST_STAT_PENDING, /* The record is valid; new data are being
+ collected */
+ HOST_STAT_INVALID /* The record is invalid (host unreachable) */
+};
+
struct host_stat {
+ int status;
struct timeval start_tv;
struct timeval stop_tv;
unsigned long xmit_count;
@@ -73,7 +82,7 @@ struct host_stat {
};
static inline int host_stat_is_valid(struct host_stat const *hs) {
- return hs->start_tv.tv_sec > 0;
+ return hs->status == HOST_STAT_VALID || hs->status == HOST_STAT_PENDING;
}
typedef struct hostaddr {
diff --git a/src/ping903q.c b/src/ping903q.c
index 7007745..b8a1053 100644
--- a/src/ping903q.c
+++ b/src/ping903q.c
@@ -417,14 +417,18 @@ print_host_status(struct json_value *obj, void *unused)
jv = ejson_get(obj, "name", json_string);
name = jv->v.s;
- jv = ejson_get(obj, "status", json_bool);
- if (!jv->v.b) {
+ jv = ejson_get(obj, "status", json_string);
+ if (strcmp(jv->v.s, "init") == 0) {
+ printf("%s: no data available yet; try later\n", name);
+ return EX_NAGIOS_UNKNOWN;
+ } else if (strcmp(jv->v.s, "invalid") == 0) {
printf("no response from %s\n", name);
return EX_NAGIOS_CRITICAL;
}
+ /* Status values "pending" and "valid" are OK */
alive = ejson_get(obj, "alive", json_bool)->v.b;
- printf("%s %s\n", name, alive ? "alive" : "not alive");
+ printf("%s is %s\n", name, alive ? "alive" : "not alive");
if (verbose) {
double xmit = ejson_get(obj, "xmit", json_number)->v.n;
double recv = ejson_get(obj, "recv", json_number)->v.n;
@@ -673,7 +677,7 @@ nagios_check(struct json_value *obj, void *data)
jv = ejson_get(obj, "status", json_bool);
if (!jv->v.b) {
- printf("PING CRITICAL - Packet loss = 100%");
+ printf("PING CRITICAL - Packet loss = 100%%");
print_perfdata(cd->cth.round_trip, 100.0, cd);
exit(EX_NAGIOS_CRITICAL);
}
diff --git a/src/pinger.c b/src/pinger.c
index 8ce22d1..b722fcf 100644
--- a/src/pinger.c
+++ b/src/pinger.c
@@ -343,6 +343,7 @@ host_stat(HOSTADDR *host, struct timeval const *tv)
host->stat_last.avg = avg;
host->stat_last.stddev = nsqrt(vari, 0.0005);
}
+ host->stat_last.status = HOST_STAT_VALID;
}
/* Reset runtime statistics counters */
@@ -355,6 +356,18 @@ host_reset(HOSTADDR *host)
host->tmax = 0;
host->tsum = 0;
host->tsumsq = 0;
+ switch (host->stat_last.status) {
+ case HOST_STAT_INIT:
+ break;
+ case HOST_STAT_VALID:
+ host->stat_last.status = HOST_STAT_PENDING;
+ break;
+ case HOST_STAT_PENDING:
+ host->stat_last.status = HOST_STAT_INVALID;
+ break;
+ case HOST_STAT_INVALID:
+ break;
+ }
}
static inline double
@@ -369,6 +382,12 @@ get_host_stat(HOSTADDR *host, struct json_value **retval)
struct json_value *obj, *v;
struct host_stat const *st = &host->stat_last;
double ts;
+ static char const *host_stat_status[] = {
+ "init",
+ "valid",
+ "pending",
+ "invalid"
+ };
if (!(obj = json_new_object()))
goto err;
@@ -377,8 +396,11 @@ get_host_stat(HOSTADDR *host, struct json_value **retval)
|| json_object_set(obj, "name", v))
goto err;
if (!(v = json_new_bool(host_stat_is_valid(st)))
- || json_object_set(obj, "status", v))
+ || json_object_set(obj, "validity", v))
goto err;
+ if (!(v = json_new_string(host_stat_status[st->status]))
+ || json_object_set(obj, "status", v))
+ goto err;
ts = timeval_to_double(&host->xmit_tv);
if (!(v = json_new_number(ts))
|| json_object_set(obj, "xmit-timestamp", v))

Return to:

Send suggestions and report system problems to the System administrator.