Module: monitoring-plugins
 Branch: master
 Commit: 5acd14fcfb419c9ef0d6bc38384dde4cd6b70bd9
 Author: Lorenz Kästle <12514511+rincewinds...@users.noreply.github.com>
   Date: Tue Feb 18 21:58:59 2025 +0100
    URL: 
https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=5acd14fc

Implement new output functionality for check_swap

---

 plugins/check_swap.c              | 132 ++++++++++++++++++++++++++++----------
 plugins/check_swap.d/check_swap.h |   4 ++
 plugins/check_swap.d/swap.c       |   2 +
 3 files changed, 104 insertions(+), 34 deletions(-)

diff --git a/plugins/check_swap.c b/plugins/check_swap.c
index bc90a90b..1f2d0273 100644
--- a/plugins/check_swap.c
+++ b/plugins/check_swap.c
@@ -28,6 +28,9 @@
  *****************************************************************************/
 
 #include "common.h"
+#include "output.h"
+#include "states.h"
+#include <limits.h>
 #ifdef HAVE_DECL_SWAPCTL
 #      ifdef HAVE_SYS_PARAM_H
 #              include <sys/param.h>
@@ -69,8 +72,6 @@ int main(int argc, char **argv) {
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);
 
-       char *status = strdup("");
-
        /* Parse extra opts if any */
        argv = np_extra_opts(&argc, argv, progname);
 
@@ -90,59 +91,101 @@ int main(int argc, char **argv) {
        }
 
        double percent_used;
+       mp_check overall = mp_check_init();
+       if (config.output_format_is_set) {
+               overall.format = config.output_format;
+       }
+       mp_subcheck sc1 = mp_subcheck_init();
+       sc1 = mp_set_subcheck_default_state(sc1, STATE_OK);
+
        /* if total_swap_mb == 0, let's not divide by 0 */
        if (data.metrics.total != 0) {
                percent_used = HUNDRED_PERCENT * ((double)data.metrics.used) / 
((double)data.metrics.total);
        } else {
-               printf(_("SWAP %s - Swap is either disabled, not present, or of 
zero "
-                                "size."),
-                          state_text(data.statusCode));
-               exit(config.no_swap_state);
+               sc1 = mp_set_subcheck_state(sc1, config.no_swap_state);
+               sc1.output = (char *)_("Swap is either disabled, not present, 
or of zero size.");
+
+               mp_add_subcheck_to_check(&overall, sc1);
+               mp_exit(overall);
        }
 
        if (verbose) {
                printf("Computed usage percentage: %g\n", percent_used);
        }
 
-       uint64_t warn_print = config.warn.value;
-       if (config.warn.is_percentage) {
-               warn_print = config.warn.value * (data.metrics.total / 
HUNDRED_PERCENT);
+       mp_perfdata pd = perfdata_init();
+       pd.label = "swap";
+       pd = mp_set_pd_value(pd, data.metrics.free);
+       pd.uom = "B";
+
+       if (config.warn_is_set) {
+               uint64_t warn_print = config.warn.value;
+               if (config.warn.is_percentage) {
+                       warn_print = config.warn.value * (data.metrics.total / 
HUNDRED_PERCENT);
+               }
+
+               mp_perfdata_value warn_pd = mp_create_pd_value(warn_print);
+
+               mp_range warn_range = mp_range_init();
+               warn_range.end_infinity = false;
+               warn_range.end = warn_pd;
+
+               pd.warn = warn_range;
+               pd.warn_present = true;
        }
 
-       uint64_t crit_print = config.crit.value;
-       if (config.crit.is_percentage) {
-               crit_print = config.crit.value * (data.metrics.total / 
HUNDRED_PERCENT);
+       if (config.crit_is_set) {
+               uint64_t crit_print = config.crit.value;
+               if (config.crit.is_percentage) {
+                       crit_print = config.crit.value * (data.metrics.total / 
HUNDRED_PERCENT);
+               }
+
+               mp_perfdata_value crit_pd = mp_create_pd_value(crit_print);
+
+               mp_range crit_range = mp_range_init();
+               crit_range.end_infinity = false;
+               crit_range.end = crit_pd;
+
+               pd.crit = crit_range;
+               pd.crit_present = true;
        }
 
-       char *perfdata = perfdata_uint64("swap", data.metrics.free, "B", 
config.warn_is_set, warn_print, config.crit_is_set, crit_print, true,
-                                                                        0, 
true, data.metrics.total);
+       mp_perfdata_value max = mp_create_pd_value(data.metrics.total);
+       pd.max = max;
+       pd.max_present = true;
+
+       mp_perfdata_value min = mp_create_pd_value(0);
+       pd.min = min;
+       pd.min_present = true;
+
+       mp_add_perfdata_to_subcheck(&sc1, pd);
+       if (verbose > 1) {
+               printf("Warn threshold value: %" PRIu64 "\n", 
config.warn.value);
+       }
 
        if (config.warn_is_set) {
-               if (verbose > 1) {
-                       printf("Warn threshold value: %" PRIu64 "\n", 
config.warn.value);
+               if ((config.warn.is_percentage && (percent_used >= (100 - 
(double)config.warn.value))) || config.warn.value >= data.metrics.free) {
+                       sc1 = mp_set_subcheck_state(sc1, STATE_WARNING);
                }
+       }
 
-               if ((config.warn.is_percentage && (percent_used >= 
(double)(HUNDRED_PERCENT - config.warn.value))) ||
-                       config.warn.value >= data.metrics.free) {
-                       data.statusCode = max_state(data.statusCode, 
STATE_WARNING);
-               }
+       if (verbose > 1) {
+               printf("Crit threshold value: %" PRIu64 "\n", 
config.crit.value);
        }
 
        if (config.crit_is_set) {
-               if (verbose > 1) {
-                       printf("Crit threshold value: %" PRIu64 "\n", 
config.crit.value);
-               }
-
-               if ((config.crit.is_percentage && (percent_used >= 
(double)(HUNDRED_PERCENT - config.crit.value))) ||
-                       config.crit.value >= data.metrics.free) {
-                       data.statusCode = max_state(data.statusCode, 
STATE_CRITICAL);
+               if ((config.crit.is_percentage && (percent_used >= (100 - 
(double)config.crit.value))) || config.crit.value >= data.metrics.free) {
+                       sc1 = mp_set_subcheck_state(sc1, STATE_CRITICAL);
                }
        }
 
-       printf(_("SWAP %s - %g%% free (%lluMiB out of %lluMiB) %s|%s\n"), 
state_text(data.statusCode), (HUNDRED_PERCENT - percent_used),
-                  BYTES_TO_MiB(data.metrics.free), 
BYTES_TO_MiB(data.metrics.total), status, perfdata);
+       xasprintf(&sc1.output, _("%g%% free (%lluMiB out of %lluMiB)"), (100 - 
percent_used), data.metrics.free >> 20,
+                         data.metrics.total >> 20);
+
+       overall.summary = "Swap";
+       mp_add_subcheck_to_check(&overall, sc1);
 
-       exit(data.statusCode);
+       mp_exit(overall);
 }
 
 int check_swap(float free_swap_mb, float total_swap_mb, swap_config config) {
@@ -172,15 +215,22 @@ int check_swap(float free_swap_mb, float total_swap_mb, 
swap_config config) {
        return STATE_OK;
 }
 
+#define output_format_index CHAR_MAX + 1
+
 /* process command-line arguments */
 swap_config_wrapper process_arguments(int argc, char **argv) {
        swap_config_wrapper conf_wrapper = {.errorcode = OK};
        conf_wrapper.config = swap_config_init();
 
-       static struct option longopts[] = {{"warning", required_argument, 0, 
'w'}, {"critical", required_argument, 0, 'c'},
-                                                                          
{"allswaps", no_argument, 0, 'a'},      {"no-swap", required_argument, 0, 'n'},
-                                                                          
{"verbose", no_argument, 0, 'v'},       {"version", no_argument, 0, 'V'},
-                                                                          
{"help", no_argument, 0, 'h'},          {0, 0, 0, 0}};
+       static struct option longopts[] = {{"warning", required_argument, 0, 
'w'},
+                                                                          
{"critical", required_argument, 0, 'c'},
+                                                                          
{"allswaps", no_argument, 0, 'a'},
+                                                                          
{"no-swap", required_argument, 0, 'n'},
+                                                                          
{"verbose", no_argument, 0, 'v'},
+                                                                          
{"version", no_argument, 0, 'V'},
+                                                                          
{"help", no_argument, 0, 'h'},
+                                                                          
{"output-format", required_argument, 0, output_format_index},
+                                                                          {0, 
0, 0, 0}};
 
        while (true) {
                int option = 0;
@@ -263,6 +313,18 @@ swap_config_wrapper process_arguments(int argc, char 
**argv) {
                case 'v': /* verbose */
                        verbose++;
                        break;
+               case output_format_index: {
+                       parsed_output_format parser = 
mp_parse_output_format(optarg);
+                       if (!parser.parsing_success) {
+                               // TODO List all available formats here, maybe 
add anothoer usage function
+                               printf("Invalid output format: %s\n", optarg);
+                               exit(STATE_UNKNOWN);
+                       }
+
+                       conf_wrapper.config.output_format_is_set = true;
+                       conf_wrapper.config.output_format = 
parser.output_format;
+                       break;
+               }
                case 'V': /* version */
                        print_revision(progname, NP_VERSION);
                        exit(STATE_UNKNOWN);
@@ -319,6 +381,8 @@ void print_help(swap_config config) {
                   _("Resulting state when there is no swap regardless of 
thresholds. "
                         "Default:"),
                   state_text(config.no_swap_state));
+       printf(" %s\n", "--output-format");
+       printf("    %s\n", _("Select output format. Valid values: \"one-line\", 
\"icingaweb2\", \"summary-only\", \"mp-test-json\""));
        printf(UT_VERBOSE);
 
        printf("\n");
diff --git a/plugins/check_swap.d/check_swap.h 
b/plugins/check_swap.d/check_swap.h
index 99039b21..1000fc9e 100644
--- a/plugins/check_swap.d/check_swap.h
+++ b/plugins/check_swap.d/check_swap.h
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "../common.h"
+#include "output.h"
 
 #ifndef SWAP_CONVERSION
 #      define SWAP_CONVERSION 1
@@ -32,6 +33,9 @@ typedef struct {
        check_swap_threshold crit;
        bool on_aix;
        int conversion_factor;
+
+       bool output_format_is_set;
+       mp_output_format output_format;
 } swap_config;
 
 swap_config swap_config_init(void);
diff --git a/plugins/check_swap.d/swap.c b/plugins/check_swap.d/swap.c
index 2fe4544f..180d5037 100644
--- a/plugins/check_swap.d/swap.c
+++ b/plugins/check_swap.d/swap.c
@@ -14,6 +14,8 @@ swap_config swap_config_init(void) {
        tmp.warn_is_set = false;
        tmp.crit_is_set = false;
 
+       tmp.output_format_is_set = false;
+
 #ifdef _AIX
        tmp.on_aix = true;
 #else

Reply via email to