[monitoring-plugins] check_ntp_peer: implement new output functionality
Lorenz Kästle
git at monitoring-plugins.org
Wed Nov 5 12:20:12 CET 2025
Module: monitoring-plugins
Branch: master
Commit: 6392a0f77635d82b9b68bcbd1be4c6acc478767f
Author: Lorenz Kästle <12514511+RincewindsHat at users.noreply.github.com>
Date: Tue Nov 4 10:13:39 2025 +0100
URL: https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=6392a0f7
check_ntp_peer: implement new output functionality
---
plugins/check_ntp_peer.c | 248 ++++++++++++++++++++------------------
plugins/check_ntp_peer.d/config.h | 58 +++++----
2 files changed, 164 insertions(+), 142 deletions(-)
diff --git a/plugins/check_ntp_peer.c b/plugins/check_ntp_peer.c
index 37e481c7..0498a7d4 100644
--- a/plugins/check_ntp_peer.c
+++ b/plugins/check_ntp_peer.c
@@ -39,6 +39,9 @@ const char *progname = "check_ntp_peer";
const char *copyright = "2006-2024";
const char *email = "devel at monitoring-plugins.org";
+#include "output.h"
+#include "perfdata.h"
+#include <openssl/x509.h>
#include "thresholds.h"
#include "common.h"
#include "netutils.h"
@@ -329,7 +332,7 @@ ntp_request_result ntp_request(const check_ntp_peer_config config) {
if (verbose) {
printf("Getting offset, jitter and stratum for peer %.2x\n", ntohs(peers[i].assoc));
}
- xasprintf(&data, "");
+ data = strdup("");
do {
setup_control_request(&req, OP_READVAR, 2);
req.assoc = peers[i].assoc;
@@ -518,36 +521,76 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) {
case 'q':
result.config.quiet = true;
break;
- case 'w':
- result.config.owarn = optarg;
- break;
- case 'c':
- result.config.ocrit = optarg;
- break;
- case 'W':
+ case 'w': {
+ mp_range_parsed tmp = mp_parse_range_string(optarg);
+ if (tmp.error != MP_PARSING_SUCCES) {
+ die(STATE_UNKNOWN, "failed to parse warning offset threshold");
+ }
+
+ mp_thresholds_set_warn(result.config.offset_thresholds, tmp.range);
+ } break;
+ case 'c': {
+ mp_range_parsed tmp = mp_parse_range_string(optarg);
+ if (tmp.error != MP_PARSING_SUCCES) {
+ die(STATE_UNKNOWN, "failed to parse critical offset threshold");
+ }
+
+ mp_thresholds_set_crit(result.config.offset_thresholds, tmp.range);
+ } break;
+ case 'W': {
result.config.do_stratum = true;
- result.config.swarn = optarg;
- break;
- case 'C':
+ mp_range_parsed tmp = mp_parse_range_string(optarg);
+ if (tmp.error != MP_PARSING_SUCCES) {
+ die(STATE_UNKNOWN, "failed to parse warning stratum threshold");
+ }
+
+ mp_thresholds_set_warn(result.config.stratum_thresholds, tmp.range);
+ } break;
+ case 'C': {
result.config.do_stratum = true;
- result.config.scrit = optarg;
- break;
- case 'j':
+ mp_range_parsed tmp = mp_parse_range_string(optarg);
+ if (tmp.error != MP_PARSING_SUCCES) {
+ die(STATE_UNKNOWN, "failed to parse critical stratum threshold");
+ }
+
+ mp_thresholds_set_crit(result.config.stratum_thresholds, tmp.range);
+ } break;
+ case 'j': {
result.config.do_jitter = true;
- result.config.jwarn = optarg;
- break;
- case 'k':
+ mp_range_parsed tmp = mp_parse_range_string(optarg);
+ if (tmp.error != MP_PARSING_SUCCES) {
+ die(STATE_UNKNOWN, "failed to parse warning jitter threshold");
+ }
+
+ mp_thresholds_set_warn(result.config.jitter_thresholds, tmp.range);
+ } break;
+ case 'k': {
result.config.do_jitter = true;
- result.config.jcrit = optarg;
- break;
- case 'm':
+ mp_range_parsed tmp = mp_parse_range_string(optarg);
+ if (tmp.error != MP_PARSING_SUCCES) {
+ die(STATE_UNKNOWN, "failed to parse critical jitter threshold");
+ }
+
+ mp_thresholds_set_crit(result.config.jitter_thresholds, tmp.range);
+ } break;
+ case 'm': {
result.config.do_truechimers = true;
- result.config.twarn = optarg;
- break;
- case 'n':
+ mp_range_parsed tmp = mp_parse_range_string(optarg);
+ if (tmp.error != MP_PARSING_SUCCES) {
+ die(STATE_UNKNOWN, "failed to parse warning truechimer threshold");
+ }
+
+ mp_thresholds_set_warn(result.config.truechimer_thresholds, tmp.range);
+ } break;
+ case 'n': {
result.config.do_truechimers = true;
- result.config.tcrit = optarg;
- break;
+ mp_range_parsed tmp = mp_parse_range_string(optarg);
+ if (tmp.error != MP_PARSING_SUCCES) {
+ die(STATE_UNKNOWN, "failed to parse critical truechimer threshold");
+ }
+
+ mp_thresholds_set_crit(result.config.truechimer_thresholds, tmp.range);
+ } break;
case 'H':
if (!is_host(optarg)) {
usage2(_("Invalid hostname/address"), optarg);
@@ -581,11 +624,6 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) {
usage4(_("Hostname was not supplied"));
}
- set_thresholds(&result.config.offset_thresholds, result.config.owarn, result.config.ocrit);
- set_thresholds(&result.config.jitter_thresholds, result.config.jwarn, result.config.jcrit);
- set_thresholds(&result.config.stratum_thresholds, result.config.swarn, result.config.scrit);
- set_thresholds(&result.config.truechimer_thresholds, result.config.twarn, result.config.tcrit);
-
return result;
}
@@ -635,124 +673,100 @@ int main(int argc, char *argv[]) {
/* This returns either OK or WARNING (See comment preceding ntp_request) */
const ntp_request_result ntp_res = ntp_request(config);
- mp_state_enum result = STATE_UNKNOWN;
+ mp_check overall = mp_check_init();
+ mp_subcheck sc_offset = mp_subcheck_init();
+ xasprintf(&sc_offset.output, "offset");
if (ntp_res.offset_result == STATE_UNKNOWN) {
/* if there's no sync peer (this overrides ntp_request output): */
- result = (config.quiet ? STATE_UNKNOWN : STATE_CRITICAL);
+ sc_offset =
+ mp_set_subcheck_state(sc_offset, (config.quiet ? STATE_UNKNOWN : STATE_CRITICAL));
} else {
/* Be quiet if there's no candidates either */
- if (config.quiet && result == STATE_WARNING) {
- result = STATE_UNKNOWN;
+ mp_state_enum tmp = STATE_OK;
+ if (config.quiet && ntp_res.state == STATE_WARNING) {
+ tmp = STATE_UNKNOWN;
}
- result = max_state_alt(result, get_status(fabs(ntp_res.offset), config.offset_thresholds));
+
+ mp_perfdata pd_offset = perfdata_init();
+ pd_offset.value = mp_create_pd_value(fabs(ntp_res.offset));
+ pd_offset = mp_pd_set_thresholds(pd_offset, config.offset_thresholds);
+
+ tmp = max_state_alt(tmp, mp_get_pd_status(pd_offset));
+ sc_offset = mp_set_subcheck_state(sc_offset, tmp);
}
- mp_state_enum oresult = result;
- mp_state_enum tresult = STATE_UNKNOWN;
+ mp_add_subcheck_to_check(&overall, sc_offset);
+ // truechimers
if (config.do_truechimers) {
- tresult = get_status(ntp_res.num_truechimers, config.truechimer_thresholds);
- result = max_state_alt(result, tresult);
- }
+ mp_subcheck sc_truechimers;
+ xasprintf(&sc_truechimers.output, "truechimers: %i", ntp_res.num_truechimers);
- mp_state_enum sresult = STATE_UNKNOWN;
+ mp_perfdata pd_truechimers = perfdata_init();
+ pd_truechimers.value = mp_create_pd_value(ntp_res.num_truechimers);
+ mp_pd_set_thresholds(pd_truechimers, config.truechimer_thresholds);
+ mp_add_perfdata_to_subcheck(&sc_truechimers, pd_truechimers);
- if (config.do_stratum) {
- sresult = get_status((double)ntp_res.stratum, config.stratum_thresholds);
- result = max_state_alt(result, sresult);
+ sc_truechimers = mp_set_subcheck_state(sc_truechimers, mp_get_pd_status(pd_truechimers));
+
+ mp_add_subcheck_to_check(&overall, sc_truechimers);
}
- mp_state_enum jresult = STATE_UNKNOWN;
+ if (config.do_stratum) {
+ mp_subcheck sc_stratum = mp_subcheck_init();
+ xasprintf(&sc_stratum.output, "stratum: %li", ntp_res.stratum);
- if (config.do_jitter) {
- jresult = get_status(ntp_res.jitter, config.jitter_thresholds);
- result = max_state_alt(result, jresult);
+ mp_perfdata pd_stratum = perfdata_init();
+ pd_stratum.value = mp_create_pd_value(ntp_res.stratum);
+ pd_stratum = mp_pd_set_thresholds(pd_stratum, config.stratum_thresholds);
+ mp_add_perfdata_to_subcheck(&sc_stratum, pd_stratum);
+
+ sc_stratum = mp_set_subcheck_state(sc_stratum, mp_get_pd_status(pd_stratum));
+
+ mp_add_subcheck_to_check(&overall, sc_stratum);
}
- char *result_line;
- switch (result) {
- case STATE_CRITICAL:
- xasprintf(&result_line, _("NTP CRITICAL:"));
- break;
- case STATE_WARNING:
- xasprintf(&result_line, _("NTP WARNING:"));
- break;
- case STATE_OK:
- xasprintf(&result_line, _("NTP OK:"));
- break;
- default:
- xasprintf(&result_line, _("NTP UNKNOWN:"));
- break;
+ if (config.do_jitter) {
+ mp_subcheck sc_jitter = mp_subcheck_init();
+ xasprintf(&sc_jitter.output, "jitter: %f", ntp_res.jitter);
+
+ mp_perfdata pd_jitter = perfdata_init();
+ pd_jitter.value = mp_create_pd_value(ntp_res.jitter);
+ pd_jitter = mp_pd_set_thresholds(pd_jitter, config.jitter_thresholds);
+ mp_add_perfdata_to_subcheck(&sc_jitter, pd_jitter);
+
+ sc_jitter = mp_set_subcheck_state(sc_jitter, mp_get_pd_status(pd_jitter));
+ mp_add_subcheck_to_check(&overall, sc_jitter);
}
+ mp_subcheck sc_other_info = mp_subcheck_init();
+ sc_other_info = mp_set_subcheck_default_state(sc_other_info, STATE_OK);
if (!ntp_res.syncsource_found) {
- xasprintf(&result_line, "%s %s,", result_line, _("Server not synchronized"));
+ xasprintf(&sc_other_info.output, "%s", _("Server not synchronized"));
+ mp_add_subcheck_to_check(&overall, sc_other_info);
} else if (ntp_res.li_alarm) {
- xasprintf(&result_line, "%s %s,", result_line, _("Server has the LI_ALARM bit set"));
+ xasprintf(&sc_other_info.output, "%s", _("Server has the LI_ALARM bit set"));
+ mp_add_subcheck_to_check(&overall, sc_other_info);
}
- char *perfdata_line;
- if (ntp_res.offset_result == STATE_UNKNOWN) {
- xasprintf(&result_line, "%s %s", result_line, _("Offset unknown"));
- xasprintf(&perfdata_line, "");
- } else if (oresult == STATE_WARNING) {
- xasprintf(&result_line, "%s %s %.10g secs (WARNING)", result_line, _("Offset"),
- ntp_res.offset);
- } else if (oresult == STATE_CRITICAL) {
- xasprintf(&result_line, "%s %s %.10g secs (CRITICAL)", result_line, _("Offset"),
- ntp_res.offset);
- } else {
- xasprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), ntp_res.offset);
- }
- xasprintf(&perfdata_line, "%s", perfd_offset(ntp_res.offset, config.offset_thresholds));
-
- if (config.do_jitter) {
- if (jresult == STATE_WARNING) {
- xasprintf(&result_line, "%s, jitter=%f (WARNING)", result_line, ntp_res.jitter);
- } else if (jresult == STATE_CRITICAL) {
- xasprintf(&result_line, "%s, jitter=%f (CRITICAL)", result_line, ntp_res.jitter);
- } else {
- xasprintf(&result_line, "%s, jitter=%f", result_line, ntp_res.jitter);
- }
- xasprintf(&perfdata_line, "%s %s", perfdata_line,
- perfd_jitter(ntp_res.jitter, config.do_jitter, config.jitter_thresholds));
- }
+ {
+ mp_subcheck sc_offset = mp_subcheck_init();
+ sc_offset = mp_set_subcheck_default_state(sc_offset, STATE_OK);
+ xasprintf(&sc_offset.output, "offset: %.10gs", ntp_res.offset);
- if (config.do_stratum) {
- if (sresult == STATE_WARNING) {
- xasprintf(&result_line, "%s, stratum=%li (WARNING)", result_line, ntp_res.stratum);
- } else if (sresult == STATE_CRITICAL) {
- xasprintf(&result_line, "%s, stratum=%li (CRITICAL)", result_line, ntp_res.stratum);
- } else {
- xasprintf(&result_line, "%s, stratum=%li", result_line, ntp_res.stratum);
- }
- xasprintf(&perfdata_line, "%s %s", perfdata_line,
- perfd_stratum(ntp_res.stratum, config.do_stratum, config.stratum_thresholds));
- }
+ mp_perfdata pd_offset = perfdata_init();
+ pd_offset.value = mp_create_pd_value(ntp_res.offset);
+ pd_offset = mp_pd_set_thresholds(pd_offset, config.offset_thresholds);
- if (config.do_truechimers) {
- if (tresult == STATE_WARNING) {
- xasprintf(&result_line, "%s, truechimers=%i (WARNING)", result_line,
- ntp_res.num_truechimers);
- } else if (tresult == STATE_CRITICAL) {
- xasprintf(&result_line, "%s, truechimers=%i (CRITICAL)", result_line,
- ntp_res.num_truechimers);
- } else {
- xasprintf(&result_line, "%s, truechimers=%i", result_line, ntp_res.num_truechimers);
- }
- xasprintf(&perfdata_line, "%s %s", perfdata_line,
- perfd_truechimers(ntp_res.num_truechimers, config.do_truechimers,
- config.truechimer_thresholds));
+ sc_offset = mp_set_subcheck_state(sc_offset, ntp_res.offset_result);
}
- printf("%s|%s\n", result_line, perfdata_line);
-
if (config.server_address != NULL) {
free(config.server_address);
}
- exit(result);
+ mp_exit(overall);
}
void print_help(void) {
diff --git a/plugins/check_ntp_peer.d/config.h b/plugins/check_ntp_peer.d/config.h
index 00e6b05d..396edea6 100644
--- a/plugins/check_ntp_peer.d/config.h
+++ b/plugins/check_ntp_peer.d/config.h
@@ -1,6 +1,7 @@
#pragma once
#include "../../config.h"
+#include "perfdata.h"
#include "thresholds.h"
#include <stddef.h>
@@ -16,26 +17,18 @@ typedef struct {
// truechimer stuff
bool do_truechimers;
- char *twarn;
- char *tcrit;
- thresholds *truechimer_thresholds;
+ mp_thresholds truechimer_thresholds;
- char *owarn;
- char *ocrit;
- thresholds *offset_thresholds;
+ // offset thresholds
+ mp_thresholds offset_thresholds;
// stratum stuff
bool do_stratum;
- char *swarn;
- char *scrit;
- thresholds *stratum_thresholds;
+ mp_thresholds stratum_thresholds;
// jitter stuff
bool do_jitter;
- char *jwarn;
- char *jcrit;
- thresholds *jitter_thresholds;
-
+ mp_thresholds jitter_thresholds;
} check_ntp_peer_config;
check_ntp_peer_config check_ntp_peer_config_init() {
@@ -45,23 +38,38 @@ check_ntp_peer_config check_ntp_peer_config_init() {
.quiet = false,
.do_truechimers = false,
- .twarn = "0:",
- .tcrit = "0:",
- .truechimer_thresholds = NULL,
+ .truechimer_thresholds = mp_thresholds_init(),
- .owarn = "60",
- .ocrit = "120",
- .offset_thresholds = NULL,
+ .offset_thresholds = mp_thresholds_init(),
.do_stratum = false,
- .swarn = "-1:16",
- .scrit = "-1:16",
- .stratum_thresholds = NULL,
+ .stratum_thresholds = mp_thresholds_init(),
.do_jitter = false,
- .jwarn = "-1:5000",
- .jcrit = "-1:10000",
- .jitter_thresholds = NULL,
+ .jitter_thresholds = mp_thresholds_init(),
};
+
+ mp_range stratum_default = mp_range_init();
+ stratum_default = mp_range_set_start(stratum_default, mp_create_pd_value(-1));
+ stratum_default = mp_range_set_end(stratum_default, mp_create_pd_value(16));
+ tmp.stratum_thresholds = mp_thresholds_set_warn(tmp.stratum_thresholds, stratum_default);
+ tmp.stratum_thresholds = mp_thresholds_set_crit(tmp.stratum_thresholds, stratum_default);
+
+ mp_range jitter_w_default = mp_range_init();
+ jitter_w_default = mp_range_set_start(jitter_w_default, mp_create_pd_value(-1));
+ jitter_w_default = mp_range_set_end(jitter_w_default, mp_create_pd_value(5000));
+ tmp.jitter_thresholds = mp_thresholds_set_warn(tmp.jitter_thresholds, jitter_w_default);
+
+ mp_range jitter_c_default = mp_range_init();
+ jitter_c_default = mp_range_set_start(jitter_c_default, mp_create_pd_value(-1));
+ jitter_c_default = mp_range_set_end(jitter_c_default, mp_create_pd_value(10000));
+ tmp.jitter_thresholds = mp_thresholds_set_crit(tmp.jitter_thresholds, jitter_c_default);
+
+ mp_range offset_w_default = mp_range_init();
+ offset_w_default = mp_range_set_start(offset_w_default, mp_create_pd_value(60));
+ tmp.offset_thresholds = mp_thresholds_set_warn(tmp.offset_thresholds, offset_w_default);
+ mp_range offset_c_default = mp_range_init();
+ offset_c_default = mp_range_set_start(offset_c_default, mp_create_pd_value(120));
+ tmp.offset_thresholds = mp_thresholds_set_crit(tmp.offset_thresholds, offset_c_default);
return tmp;
}
More information about the Commits
mailing list