diff options
| author | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-11-04 10:13:39 +0100 |
|---|---|---|
| committer | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-11-04 10:13:39 +0100 |
| commit | 6392a0f77635d82b9b68bcbd1be4c6acc478767f (patch) | |
| tree | b606e7ec191ba2b7925f5ff42bab0c7deb22c80a /plugins/check_ntp_peer.c | |
| parent | e867c2ebd3eeea5726136dc8e7227b256b5e117d (diff) | |
| download | monitoring-plugins-6392a0f77635d82b9b68bcbd1be4c6acc478767f.tar.gz | |
check_ntp_peer: implement new output functionality
Diffstat (limited to 'plugins/check_ntp_peer.c')
| -rw-r--r-- | plugins/check_ntp_peer.c | 248 |
1 files changed, 131 insertions, 117 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"; | |||
| 39 | const char *copyright = "2006-2024"; | 39 | const char *copyright = "2006-2024"; |
| 40 | const char *email = "devel@monitoring-plugins.org"; | 40 | const char *email = "devel@monitoring-plugins.org"; |
| 41 | 41 | ||
| 42 | #include "output.h" | ||
| 43 | #include "perfdata.h" | ||
| 44 | #include <openssl/x509.h> | ||
| 42 | #include "thresholds.h" | 45 | #include "thresholds.h" |
| 43 | #include "common.h" | 46 | #include "common.h" |
| 44 | #include "netutils.h" | 47 | #include "netutils.h" |
| @@ -329,7 +332,7 @@ ntp_request_result ntp_request(const check_ntp_peer_config config) { | |||
| 329 | if (verbose) { | 332 | if (verbose) { |
| 330 | printf("Getting offset, jitter and stratum for peer %.2x\n", ntohs(peers[i].assoc)); | 333 | printf("Getting offset, jitter and stratum for peer %.2x\n", ntohs(peers[i].assoc)); |
| 331 | } | 334 | } |
| 332 | xasprintf(&data, ""); | 335 | data = strdup(""); |
| 333 | do { | 336 | do { |
| 334 | setup_control_request(&req, OP_READVAR, 2); | 337 | setup_control_request(&req, OP_READVAR, 2); |
| 335 | req.assoc = peers[i].assoc; | 338 | req.assoc = peers[i].assoc; |
| @@ -518,36 +521,76 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) { | |||
| 518 | case 'q': | 521 | case 'q': |
| 519 | result.config.quiet = true; | 522 | result.config.quiet = true; |
| 520 | break; | 523 | break; |
| 521 | case 'w': | 524 | case 'w': { |
| 522 | result.config.owarn = optarg; | 525 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 523 | break; | 526 | if (tmp.error != MP_PARSING_SUCCES) { |
| 524 | case 'c': | 527 | die(STATE_UNKNOWN, "failed to parse warning offset threshold"); |
| 525 | result.config.ocrit = optarg; | 528 | } |
| 526 | break; | 529 | |
| 527 | case 'W': | 530 | mp_thresholds_set_warn(result.config.offset_thresholds, tmp.range); |
| 531 | } break; | ||
| 532 | case 'c': { | ||
| 533 | mp_range_parsed tmp = mp_parse_range_string(optarg); | ||
| 534 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 535 | die(STATE_UNKNOWN, "failed to parse critical offset threshold"); | ||
| 536 | } | ||
| 537 | |||
| 538 | mp_thresholds_set_crit(result.config.offset_thresholds, tmp.range); | ||
| 539 | } break; | ||
| 540 | case 'W': { | ||
| 528 | result.config.do_stratum = true; | 541 | result.config.do_stratum = true; |
| 529 | result.config.swarn = optarg; | 542 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 530 | break; | 543 | if (tmp.error != MP_PARSING_SUCCES) { |
| 531 | case 'C': | 544 | die(STATE_UNKNOWN, "failed to parse warning stratum threshold"); |
| 545 | } | ||
| 546 | |||
| 547 | mp_thresholds_set_warn(result.config.stratum_thresholds, tmp.range); | ||
| 548 | } break; | ||
| 549 | case 'C': { | ||
| 532 | result.config.do_stratum = true; | 550 | result.config.do_stratum = true; |
| 533 | result.config.scrit = optarg; | 551 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 534 | break; | 552 | if (tmp.error != MP_PARSING_SUCCES) { |
| 535 | case 'j': | 553 | die(STATE_UNKNOWN, "failed to parse critical stratum threshold"); |
| 554 | } | ||
| 555 | |||
| 556 | mp_thresholds_set_crit(result.config.stratum_thresholds, tmp.range); | ||
| 557 | } break; | ||
| 558 | case 'j': { | ||
| 536 | result.config.do_jitter = true; | 559 | result.config.do_jitter = true; |
| 537 | result.config.jwarn = optarg; | 560 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 538 | break; | 561 | if (tmp.error != MP_PARSING_SUCCES) { |
| 539 | case 'k': | 562 | die(STATE_UNKNOWN, "failed to parse warning jitter threshold"); |
| 563 | } | ||
| 564 | |||
| 565 | mp_thresholds_set_warn(result.config.jitter_thresholds, tmp.range); | ||
| 566 | } break; | ||
| 567 | case 'k': { | ||
| 540 | result.config.do_jitter = true; | 568 | result.config.do_jitter = true; |
| 541 | result.config.jcrit = optarg; | 569 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 542 | break; | 570 | if (tmp.error != MP_PARSING_SUCCES) { |
| 543 | case 'm': | 571 | die(STATE_UNKNOWN, "failed to parse critical jitter threshold"); |
| 572 | } | ||
| 573 | |||
| 574 | mp_thresholds_set_crit(result.config.jitter_thresholds, tmp.range); | ||
| 575 | } break; | ||
| 576 | case 'm': { | ||
| 544 | result.config.do_truechimers = true; | 577 | result.config.do_truechimers = true; |
| 545 | result.config.twarn = optarg; | 578 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 546 | break; | 579 | if (tmp.error != MP_PARSING_SUCCES) { |
| 547 | case 'n': | 580 | die(STATE_UNKNOWN, "failed to parse warning truechimer threshold"); |
| 581 | } | ||
| 582 | |||
| 583 | mp_thresholds_set_warn(result.config.truechimer_thresholds, tmp.range); | ||
| 584 | } break; | ||
| 585 | case 'n': { | ||
| 548 | result.config.do_truechimers = true; | 586 | result.config.do_truechimers = true; |
| 549 | result.config.tcrit = optarg; | 587 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 550 | break; | 588 | if (tmp.error != MP_PARSING_SUCCES) { |
| 589 | die(STATE_UNKNOWN, "failed to parse critical truechimer threshold"); | ||
| 590 | } | ||
| 591 | |||
| 592 | mp_thresholds_set_crit(result.config.truechimer_thresholds, tmp.range); | ||
| 593 | } break; | ||
| 551 | case 'H': | 594 | case 'H': |
| 552 | if (!is_host(optarg)) { | 595 | if (!is_host(optarg)) { |
| 553 | usage2(_("Invalid hostname/address"), optarg); | 596 | usage2(_("Invalid hostname/address"), optarg); |
| @@ -581,11 +624,6 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) { | |||
| 581 | usage4(_("Hostname was not supplied")); | 624 | usage4(_("Hostname was not supplied")); |
| 582 | } | 625 | } |
| 583 | 626 | ||
| 584 | set_thresholds(&result.config.offset_thresholds, result.config.owarn, result.config.ocrit); | ||
| 585 | set_thresholds(&result.config.jitter_thresholds, result.config.jwarn, result.config.jcrit); | ||
| 586 | set_thresholds(&result.config.stratum_thresholds, result.config.swarn, result.config.scrit); | ||
| 587 | set_thresholds(&result.config.truechimer_thresholds, result.config.twarn, result.config.tcrit); | ||
| 588 | |||
| 589 | return result; | 627 | return result; |
| 590 | } | 628 | } |
| 591 | 629 | ||
| @@ -635,124 +673,100 @@ int main(int argc, char *argv[]) { | |||
| 635 | 673 | ||
| 636 | /* This returns either OK or WARNING (See comment preceding ntp_request) */ | 674 | /* This returns either OK or WARNING (See comment preceding ntp_request) */ |
| 637 | const ntp_request_result ntp_res = ntp_request(config); | 675 | const ntp_request_result ntp_res = ntp_request(config); |
| 638 | mp_state_enum result = STATE_UNKNOWN; | 676 | mp_check overall = mp_check_init(); |
| 639 | 677 | ||
| 678 | mp_subcheck sc_offset = mp_subcheck_init(); | ||
| 679 | xasprintf(&sc_offset.output, "offset"); | ||
| 640 | if (ntp_res.offset_result == STATE_UNKNOWN) { | 680 | if (ntp_res.offset_result == STATE_UNKNOWN) { |
| 641 | /* if there's no sync peer (this overrides ntp_request output): */ | 681 | /* if there's no sync peer (this overrides ntp_request output): */ |
| 642 | result = (config.quiet ? STATE_UNKNOWN : STATE_CRITICAL); | 682 | sc_offset = |
| 683 | mp_set_subcheck_state(sc_offset, (config.quiet ? STATE_UNKNOWN : STATE_CRITICAL)); | ||
| 643 | } else { | 684 | } else { |
| 644 | /* Be quiet if there's no candidates either */ | 685 | /* Be quiet if there's no candidates either */ |
| 645 | if (config.quiet && result == STATE_WARNING) { | 686 | mp_state_enum tmp = STATE_OK; |
| 646 | result = STATE_UNKNOWN; | 687 | if (config.quiet && ntp_res.state == STATE_WARNING) { |
| 688 | tmp = STATE_UNKNOWN; | ||
| 647 | } | 689 | } |
| 648 | result = max_state_alt(result, get_status(fabs(ntp_res.offset), config.offset_thresholds)); | 690 | |
| 691 | mp_perfdata pd_offset = perfdata_init(); | ||
| 692 | pd_offset.value = mp_create_pd_value(fabs(ntp_res.offset)); | ||
| 693 | pd_offset = mp_pd_set_thresholds(pd_offset, config.offset_thresholds); | ||
| 694 | |||
| 695 | tmp = max_state_alt(tmp, mp_get_pd_status(pd_offset)); | ||
| 696 | sc_offset = mp_set_subcheck_state(sc_offset, tmp); | ||
| 649 | } | 697 | } |
| 650 | 698 | ||
| 651 | mp_state_enum oresult = result; | 699 | mp_add_subcheck_to_check(&overall, sc_offset); |
| 652 | mp_state_enum tresult = STATE_UNKNOWN; | ||
| 653 | 700 | ||
| 701 | // truechimers | ||
| 654 | if (config.do_truechimers) { | 702 | if (config.do_truechimers) { |
| 655 | tresult = get_status(ntp_res.num_truechimers, config.truechimer_thresholds); | 703 | mp_subcheck sc_truechimers; |
| 656 | result = max_state_alt(result, tresult); | 704 | xasprintf(&sc_truechimers.output, "truechimers: %i", ntp_res.num_truechimers); |
| 657 | } | ||
| 658 | 705 | ||
| 659 | mp_state_enum sresult = STATE_UNKNOWN; | 706 | mp_perfdata pd_truechimers = perfdata_init(); |
| 707 | pd_truechimers.value = mp_create_pd_value(ntp_res.num_truechimers); | ||
| 708 | mp_pd_set_thresholds(pd_truechimers, config.truechimer_thresholds); | ||
| 709 | mp_add_perfdata_to_subcheck(&sc_truechimers, pd_truechimers); | ||
| 660 | 710 | ||
| 661 | if (config.do_stratum) { | 711 | sc_truechimers = mp_set_subcheck_state(sc_truechimers, mp_get_pd_status(pd_truechimers)); |
| 662 | sresult = get_status((double)ntp_res.stratum, config.stratum_thresholds); | 712 | |
| 663 | result = max_state_alt(result, sresult); | 713 | mp_add_subcheck_to_check(&overall, sc_truechimers); |
| 664 | } | 714 | } |
| 665 | 715 | ||
| 666 | mp_state_enum jresult = STATE_UNKNOWN; | 716 | if (config.do_stratum) { |
| 717 | mp_subcheck sc_stratum = mp_subcheck_init(); | ||
| 718 | xasprintf(&sc_stratum.output, "stratum: %li", ntp_res.stratum); | ||
| 667 | 719 | ||
| 668 | if (config.do_jitter) { | 720 | mp_perfdata pd_stratum = perfdata_init(); |
| 669 | jresult = get_status(ntp_res.jitter, config.jitter_thresholds); | 721 | pd_stratum.value = mp_create_pd_value(ntp_res.stratum); |
| 670 | result = max_state_alt(result, jresult); | 722 | pd_stratum = mp_pd_set_thresholds(pd_stratum, config.stratum_thresholds); |
| 723 | mp_add_perfdata_to_subcheck(&sc_stratum, pd_stratum); | ||
| 724 | |||
| 725 | sc_stratum = mp_set_subcheck_state(sc_stratum, mp_get_pd_status(pd_stratum)); | ||
| 726 | |||
| 727 | mp_add_subcheck_to_check(&overall, sc_stratum); | ||
| 671 | } | 728 | } |
| 672 | 729 | ||
| 673 | char *result_line; | 730 | if (config.do_jitter) { |
| 674 | switch (result) { | 731 | mp_subcheck sc_jitter = mp_subcheck_init(); |
| 675 | case STATE_CRITICAL: | 732 | xasprintf(&sc_jitter.output, "jitter: %f", ntp_res.jitter); |
| 676 | xasprintf(&result_line, _("NTP CRITICAL:")); | 733 | |
| 677 | break; | 734 | mp_perfdata pd_jitter = perfdata_init(); |
| 678 | case STATE_WARNING: | 735 | pd_jitter.value = mp_create_pd_value(ntp_res.jitter); |
| 679 | xasprintf(&result_line, _("NTP WARNING:")); | 736 | pd_jitter = mp_pd_set_thresholds(pd_jitter, config.jitter_thresholds); |
| 680 | break; | 737 | mp_add_perfdata_to_subcheck(&sc_jitter, pd_jitter); |
| 681 | case STATE_OK: | 738 | |
| 682 | xasprintf(&result_line, _("NTP OK:")); | 739 | sc_jitter = mp_set_subcheck_state(sc_jitter, mp_get_pd_status(pd_jitter)); |
| 683 | break; | 740 | mp_add_subcheck_to_check(&overall, sc_jitter); |
| 684 | default: | ||
| 685 | xasprintf(&result_line, _("NTP UNKNOWN:")); | ||
| 686 | break; | ||
| 687 | } | 741 | } |
| 688 | 742 | ||
| 743 | mp_subcheck sc_other_info = mp_subcheck_init(); | ||
| 744 | sc_other_info = mp_set_subcheck_default_state(sc_other_info, STATE_OK); | ||
| 689 | if (!ntp_res.syncsource_found) { | 745 | if (!ntp_res.syncsource_found) { |
| 690 | xasprintf(&result_line, "%s %s,", result_line, _("Server not synchronized")); | 746 | xasprintf(&sc_other_info.output, "%s", _("Server not synchronized")); |
| 747 | mp_add_subcheck_to_check(&overall, sc_other_info); | ||
| 691 | } else if (ntp_res.li_alarm) { | 748 | } else if (ntp_res.li_alarm) { |
| 692 | xasprintf(&result_line, "%s %s,", result_line, _("Server has the LI_ALARM bit set")); | 749 | xasprintf(&sc_other_info.output, "%s", _("Server has the LI_ALARM bit set")); |
| 750 | mp_add_subcheck_to_check(&overall, sc_other_info); | ||
| 693 | } | 751 | } |
| 694 | 752 | ||
| 695 | char *perfdata_line; | 753 | { |
| 696 | if (ntp_res.offset_result == STATE_UNKNOWN) { | 754 | mp_subcheck sc_offset = mp_subcheck_init(); |
| 697 | xasprintf(&result_line, "%s %s", result_line, _("Offset unknown")); | 755 | sc_offset = mp_set_subcheck_default_state(sc_offset, STATE_OK); |
| 698 | xasprintf(&perfdata_line, ""); | 756 | xasprintf(&sc_offset.output, "offset: %.10gs", ntp_res.offset); |
| 699 | } else if (oresult == STATE_WARNING) { | ||
| 700 | xasprintf(&result_line, "%s %s %.10g secs (WARNING)", result_line, _("Offset"), | ||
| 701 | ntp_res.offset); | ||
| 702 | } else if (oresult == STATE_CRITICAL) { | ||
| 703 | xasprintf(&result_line, "%s %s %.10g secs (CRITICAL)", result_line, _("Offset"), | ||
| 704 | ntp_res.offset); | ||
| 705 | } else { | ||
| 706 | xasprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), ntp_res.offset); | ||
| 707 | } | ||
| 708 | xasprintf(&perfdata_line, "%s", perfd_offset(ntp_res.offset, config.offset_thresholds)); | ||
| 709 | |||
| 710 | if (config.do_jitter) { | ||
| 711 | if (jresult == STATE_WARNING) { | ||
| 712 | xasprintf(&result_line, "%s, jitter=%f (WARNING)", result_line, ntp_res.jitter); | ||
| 713 | } else if (jresult == STATE_CRITICAL) { | ||
| 714 | xasprintf(&result_line, "%s, jitter=%f (CRITICAL)", result_line, ntp_res.jitter); | ||
| 715 | } else { | ||
| 716 | xasprintf(&result_line, "%s, jitter=%f", result_line, ntp_res.jitter); | ||
| 717 | } | ||
| 718 | xasprintf(&perfdata_line, "%s %s", perfdata_line, | ||
| 719 | perfd_jitter(ntp_res.jitter, config.do_jitter, config.jitter_thresholds)); | ||
| 720 | } | ||
| 721 | 757 | ||
| 722 | if (config.do_stratum) { | 758 | mp_perfdata pd_offset = perfdata_init(); |
| 723 | if (sresult == STATE_WARNING) { | 759 | pd_offset.value = mp_create_pd_value(ntp_res.offset); |
| 724 | xasprintf(&result_line, "%s, stratum=%li (WARNING)", result_line, ntp_res.stratum); | 760 | pd_offset = mp_pd_set_thresholds(pd_offset, config.offset_thresholds); |
| 725 | } else if (sresult == STATE_CRITICAL) { | ||
| 726 | xasprintf(&result_line, "%s, stratum=%li (CRITICAL)", result_line, ntp_res.stratum); | ||
| 727 | } else { | ||
| 728 | xasprintf(&result_line, "%s, stratum=%li", result_line, ntp_res.stratum); | ||
| 729 | } | ||
| 730 | xasprintf(&perfdata_line, "%s %s", perfdata_line, | ||
| 731 | perfd_stratum(ntp_res.stratum, config.do_stratum, config.stratum_thresholds)); | ||
| 732 | } | ||
| 733 | 761 | ||
| 734 | if (config.do_truechimers) { | 762 | sc_offset = mp_set_subcheck_state(sc_offset, ntp_res.offset_result); |
| 735 | if (tresult == STATE_WARNING) { | ||
| 736 | xasprintf(&result_line, "%s, truechimers=%i (WARNING)", result_line, | ||
| 737 | ntp_res.num_truechimers); | ||
| 738 | } else if (tresult == STATE_CRITICAL) { | ||
| 739 | xasprintf(&result_line, "%s, truechimers=%i (CRITICAL)", result_line, | ||
| 740 | ntp_res.num_truechimers); | ||
| 741 | } else { | ||
| 742 | xasprintf(&result_line, "%s, truechimers=%i", result_line, ntp_res.num_truechimers); | ||
| 743 | } | ||
| 744 | xasprintf(&perfdata_line, "%s %s", perfdata_line, | ||
| 745 | perfd_truechimers(ntp_res.num_truechimers, config.do_truechimers, | ||
| 746 | config.truechimer_thresholds)); | ||
| 747 | } | 763 | } |
| 748 | 764 | ||
| 749 | printf("%s|%s\n", result_line, perfdata_line); | ||
| 750 | |||
| 751 | if (config.server_address != NULL) { | 765 | if (config.server_address != NULL) { |
| 752 | free(config.server_address); | 766 | free(config.server_address); |
| 753 | } | 767 | } |
| 754 | 768 | ||
| 755 | exit(result); | 769 | mp_exit(overall); |
| 756 | } | 770 | } |
| 757 | 771 | ||
| 758 | void print_help(void) { | 772 | void print_help(void) { |
