summaryrefslogtreecommitdiffstats
path: root/plugins/check_cluster.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_cluster.c')
-rw-r--r--plugins/check_cluster.c206
1 files changed, 122 insertions, 84 deletions
diff --git a/plugins/check_cluster.c b/plugins/check_cluster.c
index b40c38c7..1cbdcd60 100644
--- a/plugins/check_cluster.c
+++ b/plugins/check_cluster.c
@@ -26,45 +26,25 @@ const char *progname = "check_cluster";
26const char *copyright = "2000-2024"; 26const char *copyright = "2000-2024";
27const char *email = "devel@monitoring-plugins.org"; 27const char *email = "devel@monitoring-plugins.org";
28 28
29#include "output.h"
30#include "states.h"
29#include "common.h" 31#include "common.h"
30#include "utils.h" 32#include "utils.h"
31#include "utils_base.h" 33#include "utils_base.h"
32 34#include "check_cluster.d/config.h"
33enum {
34 CHECK_SERVICES = 1,
35 CHECK_HOSTS = 2
36};
37 35
38static void print_help(void); 36static void print_help(void);
39void print_usage(void); 37void print_usage(void);
40 38
41static int total_services_ok = 0;
42static int total_services_warning = 0;
43static int total_services_unknown = 0;
44static int total_services_critical = 0;
45
46static int total_hosts_up = 0;
47static int total_hosts_down = 0;
48static int total_hosts_unreachable = 0;
49
50static char *warn_threshold;
51static char *crit_threshold;
52
53static int check_type = CHECK_SERVICES;
54
55static char *data_vals = NULL;
56static char *label = NULL;
57
58static int verbose = 0; 39static int verbose = 0;
59 40
60static int process_arguments(int /*argc*/, char ** /*argv*/); 41typedef struct {
42 int errorcode;
43 check_cluster_config config;
44} check_cluster_config_wrapper;
45static check_cluster_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
61 46
62int main(int argc, char **argv) { 47int main(int argc, char **argv) {
63 char *ptr;
64 int data_val;
65 int return_code = STATE_OK;
66 thresholds *thresholds = NULL;
67
68 setlocale(LC_ALL, ""); 48 setlocale(LC_ALL, "");
69 bindtextdomain(PACKAGE, LOCALEDIR); 49 bindtextdomain(PACKAGE, LOCALEDIR);
70 textdomain(PACKAGE); 50 textdomain(PACKAGE);
@@ -72,20 +52,35 @@ int main(int argc, char **argv) {
72 /* Parse extra opts if any */ 52 /* Parse extra opts if any */
73 argv = np_extra_opts(&argc, argv, progname); 53 argv = np_extra_opts(&argc, argv, progname);
74 54
75 if (process_arguments(argc, argv) == ERROR) 55 check_cluster_config_wrapper tmp_config = process_arguments(argc, argv);
56 if (tmp_config.errorcode == ERROR) {
76 usage(_("Could not parse arguments")); 57 usage(_("Could not parse arguments"));
58 }
59
60 const check_cluster_config config = tmp_config.config;
61
62 if (config.output_format_is_set) {
63 mp_set_format(config.output_format);
64 }
77 65
78 /* Initialize the thresholds */ 66 /* Initialize the thresholds */
79 set_thresholds(&thresholds, warn_threshold, crit_threshold); 67 if (verbose) {
80 if (verbose) 68 print_thresholds("check_cluster", config.thresholds);
81 print_thresholds("check_cluster", thresholds); 69 }
82 70
71 int data_val;
72 int total_services_ok = 0;
73 int total_services_warning = 0;
74 int total_services_unknown = 0;
75 int total_services_critical = 0;
76 int total_hosts_up = 0;
77 int total_hosts_down = 0;
78 int total_hosts_unreachable = 0;
83 /* check the data values */ 79 /* check the data values */
84 for (ptr = strtok(data_vals, ","); ptr != NULL; ptr = strtok(NULL, ",")) { 80 for (char *ptr = strtok(config.data_vals, ","); ptr != NULL; ptr = strtok(NULL, ",")) {
85
86 data_val = atoi(ptr); 81 data_val = atoi(ptr);
87 82
88 if (check_type == CHECK_SERVICES) { 83 if (config.check_type == CHECK_SERVICES) {
89 switch (data_val) { 84 switch (data_val) {
90 case 0: 85 case 0:
91 total_services_ok++; 86 total_services_ok++;
@@ -119,101 +114,141 @@ int main(int argc, char **argv) {
119 } 114 }
120 } 115 }
121 116
117 mp_check overall = mp_check_init();
118 mp_subcheck sc_real_test = mp_subcheck_init();
119 sc_real_test = mp_set_subcheck_default_state(sc_real_test, STATE_OK);
120
122 /* return the status of the cluster */ 121 /* return the status of the cluster */
123 if (check_type == CHECK_SERVICES) { 122 if (config.check_type == CHECK_SERVICES) {
124 return_code = get_status(total_services_warning + total_services_unknown + total_services_critical, thresholds); 123 sc_real_test = mp_set_subcheck_state(
125 printf("CLUSTER %s: %s: %d ok, %d warning, %d unknown, %d critical\n", state_text(return_code), 124 sc_real_test,
126 (label == NULL) ? "Service cluster" : label, total_services_ok, total_services_warning, total_services_unknown, 125 get_status(total_services_warning + total_services_unknown + total_services_critical,
127 total_services_critical); 126 config.thresholds));
127 xasprintf(&sc_real_test.output, "%s: %d ok, %d warning, %d unknown, %d critical",
128 (config.label == NULL) ? "Service cluster" : config.label, total_services_ok,
129 total_services_warning, total_services_unknown, total_services_critical);
128 } else { 130 } else {
129 return_code = get_status(total_hosts_down + total_hosts_unreachable, thresholds); 131 sc_real_test = mp_set_subcheck_state(
130 printf("CLUSTER %s: %s: %d up, %d down, %d unreachable\n", state_text(return_code), (label == NULL) ? "Host cluster" : label, 132 sc_real_test,
131 total_hosts_up, total_hosts_down, total_hosts_unreachable); 133 get_status(total_hosts_down + total_hosts_unreachable, config.thresholds));
134 xasprintf(&sc_real_test.output, "%s: %d up, %d down, %d unreachable\n",
135 (config.label == NULL) ? "Host cluster" : config.label, total_hosts_up,
136 total_hosts_down, total_hosts_unreachable);
132 } 137 }
133 138
134 return return_code; 139 mp_add_subcheck_to_check(&overall, sc_real_test);
140
141 mp_exit(overall);
135} 142}
136 143
137int process_arguments(int argc, char **argv) { 144check_cluster_config_wrapper process_arguments(int argc, char **argv) {
138 int c; 145 enum {
139 char *ptr; 146 output_format_index = CHAR_MAX + 1,
140 int option = 0; 147 };
141 static struct option longopts[] = {{"data", required_argument, 0, 'd'}, {"warning", required_argument, 0, 'w'}, 148
142 {"critical", required_argument, 0, 'c'}, {"label", required_argument, 0, 'l'}, 149 static struct option longopts[] = {{"data", required_argument, 0, 'd'},
143 {"host", no_argument, 0, 'h'}, {"service", no_argument, 0, 's'}, 150 {"warning", required_argument, 0, 'w'},
144 {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, 151 {"critical", required_argument, 0, 'c'},
145 {"help", no_argument, 0, 'H'}, {0, 0, 0, 0}}; 152 {"label", required_argument, 0, 'l'},
153 {"host", no_argument, 0, 'h'},
154 {"service", no_argument, 0, 's'},
155 {"verbose", no_argument, 0, 'v'},
156 {"version", no_argument, 0, 'V'},
157 {"help", no_argument, 0, 'H'},
158 {"output-format", required_argument, 0, output_format_index},
159 {0, 0, 0, 0}};
160
161 check_cluster_config_wrapper result = {
162 .errorcode = OK,
163 .config = check_cluster_config_init(),
164 };
146 165
147 /* no options were supplied */ 166 /* no options were supplied */
148 if (argc < 2) 167 if (argc < 2) {
149 return ERROR; 168 result.errorcode = ERROR;
150 169 return result;
151 while (1) { 170 }
152 171
153 c = getopt_long(argc, argv, "hHsvVw:c:d:l:", longopts, &option); 172 int option = 0;
173 char *warn_threshold = NULL;
174 char *crit_threshold = NULL;
175 while (true) {
176 int option_index = getopt_long(argc, argv, "hHsvVw:c:d:l:", longopts, &option);
154 177
155 if (c == -1 || c == EOF || c == 1) 178 if (option_index == -1 || option_index == EOF || option_index == 1) {
156 break; 179 break;
180 }
157 181
158 switch (c) { 182 switch (option_index) {
159
160 case 'h': /* host cluster */ 183 case 'h': /* host cluster */
161 check_type = CHECK_HOSTS; 184 result.config.check_type = CHECK_HOSTS;
162 break; 185 break;
163
164 case 's': /* service cluster */ 186 case 's': /* service cluster */
165 check_type = CHECK_SERVICES; 187 result.config.check_type = CHECK_SERVICES;
166 break; 188 break;
167
168 case 'w': /* warning threshold */ 189 case 'w': /* warning threshold */
169 warn_threshold = strdup(optarg); 190 warn_threshold = strdup(optarg);
170 break; 191 break;
171
172 case 'c': /* warning threshold */ 192 case 'c': /* warning threshold */
173 crit_threshold = strdup(optarg); 193 crit_threshold = strdup(optarg);
174 break; 194 break;
175
176 case 'd': /* data values */ 195 case 'd': /* data values */
177 data_vals = (char *)strdup(optarg); 196 result.config.data_vals = strdup(optarg);
178 /* validate data */ 197 /* validate data */
179 for (ptr = data_vals; ptr != NULL; ptr += 2) { 198 for (char *ptr = result.config.data_vals; ptr != NULL; ptr += 2) {
180 if (ptr[0] < '0' || ptr[0] > '3') 199 if (ptr[0] < '0' || ptr[0] > '3') {
181 return ERROR; 200 result.errorcode = ERROR;
182 if (ptr[1] == '\0') 201 return result;
202 }
203 if (ptr[1] == '\0') {
183 break; 204 break;
184 if (ptr[1] != ',') 205 }
185 return ERROR; 206 if (ptr[1] != ',') {
207 result.errorcode = ERROR;
208 return result;
209 }
186 } 210 }
187 break; 211 break;
188
189 case 'l': /* text label */ 212 case 'l': /* text label */
190 label = (char *)strdup(optarg); 213 result.config.label = strdup(optarg);
191 break; 214 break;
192
193 case 'v': /* verbose */ 215 case 'v': /* verbose */
194 verbose++; 216 verbose++;
195 break; 217 break;
196
197 case 'V': /* version */ 218 case 'V': /* version */
198 print_revision(progname, NP_VERSION); 219 print_revision(progname, NP_VERSION);
199 exit(STATE_UNKNOWN); 220 exit(STATE_UNKNOWN);
200 break; 221 break;
201
202 case 'H': /* help */ 222 case 'H': /* help */
203 print_help(); 223 print_help();
204 exit(STATE_UNKNOWN); 224 exit(STATE_UNKNOWN);
205 break; 225 break;
226 case output_format_index: {
227 parsed_output_format parser = mp_parse_output_format(optarg);
228 if (!parser.parsing_success) {
229 // TODO List all available formats here, maybe add anothoer usage function
230 printf("Invalid output format: %s\n", optarg);
231 exit(STATE_UNKNOWN);
232 }
206 233
234 result.config.output_format_is_set = true;
235 result.config.output_format = parser.output_format;
236 break;
237 }
207 default: 238 default:
208 return ERROR; 239 result.errorcode = ERROR;
240 return result;
209 break; 241 break;
210 } 242 }
211 } 243 }
212 244
213 if (data_vals == NULL) 245 if (result.config.data_vals == NULL) {
214 return ERROR; 246 result.errorcode = ERROR;
247 return result;
248 }
215 249
216 return OK; 250 set_thresholds(&result.config.thresholds, warn_threshold, crit_threshold);
251 return result;
217} 252}
218 253
219void print_help(void) { 254void print_help(void) {
@@ -247,6 +282,8 @@ void print_help(void) {
247 282
248 printf(UT_VERBOSE); 283 printf(UT_VERBOSE);
249 284
285 printf(UT_OUTPUT_FORMAT);
286
250 printf("\n"); 287 printf("\n");
251 printf("%s\n", _("Notes:")); 288 printf("%s\n", _("Notes:"));
252 printf(UT_THRESHOLDS_NOTES); 289 printf(UT_THRESHOLDS_NOTES);
@@ -254,7 +291,8 @@ void print_help(void) {
254 printf("\n"); 291 printf("\n");
255 printf("%s\n", _("Examples:")); 292 printf("%s\n", _("Examples:"));
256 printf(" %s\n", "check_cluster -s -d 2,0,2,0 -c @3:"); 293 printf(" %s\n", "check_cluster -s -d 2,0,2,0 -c @3:");
257 printf(" %s\n", _("Will alert critical if there are 3 or more service data points in a non-OK")); 294 printf(" %s\n",
295 _("Will alert critical if there are 3 or more service data points in a non-OK"));
258 printf(" %s\n", _("state.")); 296 printf(" %s\n", _("state."));
259 297
260 printf(UT_SUPPORT); 298 printf(UT_SUPPORT);