[monitoring-plugins] check_ntp_time: add stratum thresholds (#2357)
GitHub
git at monitoring-plugins.org
Tue Sep 29 11:10:14 CEST 2026
Module: monitoring-plugins
Branch: master
Commit: 3b83b31b60931d943467f6ecdd70229a3ceea39b
Author: Carlos <5107748+Devstellar at users.noreply.github.com>
Committer: GitHub <noreply at github.com>
Date: Tue Sep 29 11:07:38 2026 +0200
URL: https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=3b83b31b
check_ntp_time: add stratum thresholds (#2357)
* check_ntp_time: add stratum thresholds
---------
Co-authored-by: Lorenz Kästle <12514511+RincewindsHat at users.noreply.github.com>
---
plugins/check_ntp_time.c | 79 ++++++++++++++++++++++++++++++---------
plugins/check_ntp_time.d/config.h | 6 +++
2 files changed, 68 insertions(+), 17 deletions(-)
diff --git a/plugins/check_ntp_time.c b/plugins/check_ntp_time.c
index 75986821..b082b04a 100644
--- a/plugins/check_ntp_time.c
+++ b/plugins/check_ntp_time.c
@@ -320,6 +320,7 @@ static int best_offset_server(const ntp_server_results *slist, int nservers) {
typedef struct {
mp_state_enum offset_result;
double offset;
+ int stratum;
} offset_request_wrapper;
static offset_request_wrapper offset_request(const char *host, const char *port, int time_offset,
const struct timespec poll_delay) {
@@ -505,6 +506,7 @@ static offset_request_wrapper offset_request(const char *host, const char *port,
offset_request_wrapper result = {
.offset = 0,
.offset_result = STATE_UNKNOWN,
+ .stratum = -1,
};
/* now, pick the best server from the list */
@@ -514,6 +516,8 @@ static offset_request_wrapper offset_request(const char *host, const char *port,
result.offset_result = STATE_UNKNOWN;
} else {
result.offset_result = STATE_OK;
+ result.stratum = servers[best_index].stratum;
+
/* finally, calculate the average offset */
for (int i = 0; i < servers[best_index].num_responses; i++) {
avg_offset += servers[best_index].offset[i];
@@ -542,23 +546,28 @@ static check_ntp_time_config_wrapper process_arguments(int argc, char **argv) {
enum {
output_format_index = CHAR_MAX + 1,
polling_delay_index,
+ stratum_warning_index,
+ stratum_critical_index,
};
- static struct option longopts[] = {{"version", no_argument, 0, 'V'},
- {"help", no_argument, 0, 'h'},
- {"verbose", no_argument, 0, 'v'},
- {"use-ipv4", no_argument, 0, '4'},
- {"use-ipv6", no_argument, 0, '6'},
- {"quiet", no_argument, 0, 'q'},
- {"time-offset", required_argument, 0, 'o'},
- {"warning", required_argument, 0, 'w'},
- {"critical", required_argument, 0, 'c'},
- {"timeout", required_argument, 0, 't'},
- {"hostname", required_argument, 0, 'H'},
- {"port", required_argument, 0, 'p'},
- {"poll-delay", required_argument, 0, polling_delay_index},
- {"output-format", required_argument, 0, output_format_index},
- {0, 0, 0, 0}};
+ static struct option longopts[] = {
+ {"version", no_argument, 0, 'V'},
+ {"help", no_argument, 0, 'h'},
+ {"verbose", no_argument, 0, 'v'},
+ {"use-ipv4", no_argument, 0, '4'},
+ {"use-ipv6", no_argument, 0, '6'},
+ {"quiet", no_argument, 0, 'q'},
+ {"time-offset", required_argument, 0, 'o'},
+ {"warning", required_argument, 0, 'w'},
+ {"critical", required_argument, 0, 'c'},
+ {"stratum-warning", required_argument, 0, stratum_warning_index},
+ {"stratum-critical", required_argument, 0, stratum_critical_index},
+ {"timeout", required_argument, 0, 't'},
+ {"hostname", required_argument, 0, 'H'},
+ {"port", required_argument, 0, 'p'},
+ {"poll-delay", required_argument, 0, polling_delay_index},
+ {"output-format", required_argument, 0, output_format_index},
+ {0, 0, 0, 0}};
if (argc < 2) {
mopl_utils_usage("\n");
@@ -620,6 +629,24 @@ static check_ntp_time_config_wrapper process_arguments(int argc, char **argv) {
result.config.offset_thresholds =
mp_thresholds_set_crit(result.config.offset_thresholds, tmp.range);
} break;
+ case stratum_warning_index: {
+ result.config.do_stratum = true;
+ mp_range_parsed tmp = mp_parse_range_string(optarg);
+ if (tmp.error != MP_PARSING_SUCCESS) {
+ die(STATE_UNKNOWN, "failed to parse warning stratum threshold");
+ }
+ result.config.stratum_thresholds =
+ mp_thresholds_set_warn(result.config.stratum_thresholds, tmp.range);
+ } break;
+ case stratum_critical_index: {
+ result.config.do_stratum = true;
+ mp_range_parsed tmp = mp_parse_range_string(optarg);
+ if (tmp.error != MP_PARSING_SUCCESS) {
+ die(STATE_UNKNOWN, "failed to parse critical stratum threshold");
+ }
+ result.config.stratum_thresholds =
+ mp_thresholds_set_crit(result.config.stratum_thresholds, tmp.range);
+ } break;
case 'H':
if (!mopl_net_is_host(optarg) && (optarg[0] != '/')) {
mopl_utils_usage2(_("Invalid hostname/address"), optarg);
@@ -733,6 +760,18 @@ int main(int argc, char *argv[]) {
mp_add_perfdata_to_subcheck(&sc_offset, pd_offset);
mp_add_subcheck_to_check(&overall, sc_offset);
+ if (config.do_stratum) {
+ mp_subcheck sc_stratum = mp_subcheck_init();
+ mopl_utils_xasprintf(&sc_stratum.output, "Stratum: %d", offset_result.stratum);
+ mp_perfdata pd_stratum = perfdata_init();
+ pd_stratum = mp_set_pd_value(pd_stratum, offset_result.stratum);
+ pd_stratum = mp_pd_set_thresholds(pd_stratum, config.stratum_thresholds);
+ pd_stratum.label = "stratum";
+ 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);
+ }
+
if (config.server_address != NULL) {
free(config.server_address);
}
@@ -760,6 +799,10 @@ void print_help(void) {
printf(" %s\n", _("Offset to result in warning status (seconds)"));
printf(" %s\n", "-c, --critical=THRESHOLD");
printf(" %s\n", _("Offset to result in critical status (seconds)"));
+ printf(" %s\n", "--stratum-warning=THRESHOLD");
+ printf(" %s\n", _("Warning threshold for NTP server stratum"));
+ printf(" %s\n", "--stratum-critical=THRESHOLD");
+ printf(" %s\n", _("Critical threshold for NTP server stratum"));
printf(" %s\n", "-o, --time-offset=INTEGER");
printf(" %s\n", _("Expected offset of the ntp server relative to local server (seconds)"));
printf(" %s\n", " --poll-delay=DELAY");
@@ -776,7 +819,7 @@ void print_help(void) {
printf("\n");
printf("%s\n", _("Notes:"));
- printf(" %s\n", _("If you'd rather want to monitor an NTP server, please use"));
+ printf(" %s\n", _("For ntpd-specific peer monitoring, please use"));
printf(" %s\n", _("check_ntp_peer."));
printf(" %s\n", _("--time-offset is useful for compensating for servers with known"));
printf(" %s\n", _("and expected clock skew."));
@@ -792,6 +835,8 @@ void print_help(void) {
void print_usage(void) {
printf("%s\n", _("Usage:"));
- printf(" %s -H <host> [-4|-6] [-w <warn>] [-c <crit>] [-v verbose] [-o <time offset>]\n",
+ printf(" %s -H <host> [-4|-6] [-w <warn>] [-c <crit>] [--stratum-warning <swarn>] "
+ "[--stratum-critical <scrit>] [-v verbose] "
+ "[-o <time offset>]\n",
progname);
}
diff --git a/plugins/check_ntp_time.d/config.h b/plugins/check_ntp_time.d/config.h
index 81194a95..c118f487 100644
--- a/plugins/check_ntp_time.d/config.h
+++ b/plugins/check_ntp_time.d/config.h
@@ -19,6 +19,9 @@ typedef struct {
mp_thresholds offset_thresholds;
+ bool do_stratum;
+ mp_thresholds stratum_thresholds;
+
bool output_format_is_set;
struct timespec poll_delay;
mp_output_format output_format;
@@ -34,6 +37,9 @@ check_ntp_time_config check_ntp_time_config_init() {
.offset_thresholds = mp_thresholds_init(),
+ .do_stratum = false,
+ .stratum_thresholds = mp_thresholds_init(),
+
.output_format_is_set = false,
.poll_delay = default_polling_delay,
};
More information about the Commits
mailing list