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.c351
1 files changed, 184 insertions, 167 deletions
diff --git a/plugins/check_cluster.c b/plugins/check_cluster.c
index e1ede9f7..1cbdcd60 100644
--- a/plugins/check_cluster.c
+++ b/plugins/check_cluster.c
@@ -1,92 +1,87 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2 *
3* check_cluster.c - Host and Service Cluster Plugin for Monitoring 3 * check_cluster.c - Host and Service Cluster Plugin for Monitoring
4* 4 *
5* License: GPL 5 * License: GPL
6* Copyright (c) 2000-2004 Ethan Galstad (nagios@nagios.org) 6 * Copyright (c) 2000-2004 Ethan Galstad (nagios@nagios.org)
7* Copyright (c) 2007 Monitoring Plugins Development Team 7 * Copyright (c) 2007-2024 Monitoring Plugins Development Team
8* 8 *
9* This program is free software: you can redistribute it and/or modify 9 * This program is free software: you can redistribute it and/or modify
10* it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
11* the Free Software Foundation, either version 3 of the License, or 11 * the Free Software Foundation, either version 3 of the License, or
12* (at your option) any later version. 12 * (at your option) any later version.
13* 13 *
14* This program is distributed in the hope that it will be useful, 14 * This program is distributed in the hope that it will be useful,
15* but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17* GNU General Public License for more details. 17 * GNU General Public License for more details.
18* 18 *
19* You should have received a copy of the GNU General Public License 19 * You should have received a copy of the GNU General Public License
20* along with this program. If not, see <http://www.gnu.org/licenses/>. 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21* 21 *
22* 22 *
23*****************************************************************************/ 23 *****************************************************************************/
24 24
25const char *progname = "check_cluster"; 25const char *progname = "check_cluster";
26const char *copyright = "2000-2007"; 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"
34#include "check_cluster.d/config.h"
32 35
33#define CHECK_SERVICES 1 36static void print_help(void);
34#define CHECK_HOSTS 2 37void print_usage(void);
35 38
36void print_help (void); 39static int verbose = 0;
37void print_usage (void);
38 40
39int total_services_ok=0; 41typedef struct {
40int total_services_warning=0; 42 int errorcode;
41int total_services_unknown=0; 43 check_cluster_config config;
42int total_services_critical=0; 44} check_cluster_config_wrapper;
45static check_cluster_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
43 46
44int total_hosts_up=0; 47int main(int argc, char **argv) {
45int total_hosts_down=0; 48 setlocale(LC_ALL, "");
46int total_hosts_unreachable=0; 49 bindtextdomain(PACKAGE, LOCALEDIR);
47 50 textdomain(PACKAGE);
48char *warn_threshold;
49char *crit_threshold;
50
51int check_type=CHECK_SERVICES;
52
53char *data_vals=NULL;
54char *label=NULL;
55
56int verbose=0;
57
58int process_arguments(int,char **);
59
60
61
62int 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, "");
69 bindtextdomain (PACKAGE, LOCALEDIR);
70 textdomain (PACKAGE);
71 51
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 81 data_val = atoi(ptr);
86 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++;
92 break; 87 break;
@@ -101,10 +96,9 @@ int main(int argc, char **argv){
101 break; 96 break;
102 default: 97 default:
103 break; 98 break;
104 } 99 }
105 } 100 } else {
106 else{ 101 switch (data_val) {
107 switch(data_val){
108 case 0: 102 case 0:
109 total_hosts_up++; 103 total_hosts_up++;
110 break; 104 break;
@@ -116,125 +110,150 @@ int main(int argc, char **argv){
116 break; 110 break;
117 default: 111 default:
118 break; 112 break;
119 } 113 }
120 } 114 }
121 } 115 }
122 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);
123 120
124 /* return the status of the cluster */ 121 /* return the status of the cluster */
125 if(check_type==CHECK_SERVICES){ 122 if (config.check_type == CHECK_SERVICES) {
126 return_code=get_status(total_services_warning+total_services_unknown+total_services_critical, thresholds); 123 sc_real_test = mp_set_subcheck_state(
127 printf("CLUSTER %s: %s: %d ok, %d warning, %d unknown, %d critical\n", 124 sc_real_test,
128 state_text(return_code), (label==NULL)?"Service cluster":label, 125 get_status(total_services_warning + total_services_unknown + total_services_critical,
129 total_services_ok,total_services_warning, 126 config.thresholds));
130 total_services_unknown,total_services_critical); 127 xasprintf(&sc_real_test.output, "%s: %d ok, %d warning, %d unknown, %d critical",
131 } 128 (config.label == NULL) ? "Service cluster" : config.label, total_services_ok,
132 else{ 129 total_services_warning, total_services_unknown, total_services_critical);
133 return_code=get_status(total_hosts_down+total_hosts_unreachable, thresholds); 130 } else {
134 printf("CLUSTER %s: %s: %d up, %d down, %d unreachable\n", 131 sc_real_test = mp_set_subcheck_state(
135 state_text(return_code), (label==NULL)?"Host cluster":label, 132 sc_real_test,
136 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);
137 } 137 }
138 138
139 return return_code; 139 mp_add_subcheck_to_check(&overall, sc_real_test);
140}
141 140
141 mp_exit(overall);
142}
142 143
144check_cluster_config_wrapper process_arguments(int argc, char **argv) {
145 enum {
146 output_format_index = CHAR_MAX + 1,
147 };
143 148
144int process_arguments(int argc, char **argv){ 149 static struct option longopts[] = {{"data", required_argument, 0, 'd'},
145 int c; 150 {"warning", required_argument, 0, 'w'},
146 char *ptr; 151 {"critical", required_argument, 0, 'c'},
147 int option=0; 152 {"label", required_argument, 0, 'l'},
148 static struct option longopts[]={ 153 {"host", no_argument, 0, 'h'},
149 {"data", required_argument,0,'d'}, 154 {"service", no_argument, 0, 's'},
150 {"warning", required_argument,0,'w'}, 155 {"verbose", no_argument, 0, 'v'},
151 {"critical", required_argument,0,'c'}, 156 {"version", no_argument, 0, 'V'},
152 {"label", required_argument,0,'l'}, 157 {"help", no_argument, 0, 'H'},
153 {"host", no_argument, 0,'h'}, 158 {"output-format", required_argument, 0, output_format_index},
154 {"service", no_argument, 0,'s'}, 159 {0, 0, 0, 0}};
155 {"verbose", no_argument, 0,'v'}, 160
156 {"version", no_argument, 0,'V'}, 161 check_cluster_config_wrapper result = {
157 {"help", no_argument, 0,'H'}, 162 .errorcode = OK,
158 {0,0,0,0} 163 .config = check_cluster_config_init(),
159 }; 164 };
160 165
161 /* no options were supplied */ 166 /* no options were supplied */
162 if(argc<2) 167 if (argc < 2) {
163 return ERROR; 168 result.errorcode = ERROR;
164 169 return result;
165 while(1){ 170 }
166 171
167 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);
168 177
169 if(c==-1 || c==EOF || c==1) 178 if (option_index == -1 || option_index == EOF || option_index == 1) {
170 break; 179 break;
180 }
171 181
172 switch(c){ 182 switch (option_index) {
173
174 case 'h': /* host cluster */ 183 case 'h': /* host cluster */
175 check_type=CHECK_HOSTS; 184 result.config.check_type = CHECK_HOSTS;
176 break; 185 break;
177
178 case 's': /* service cluster */ 186 case 's': /* service cluster */
179 check_type=CHECK_SERVICES; 187 result.config.check_type = CHECK_SERVICES;
180 break; 188 break;
181
182 case 'w': /* warning threshold */ 189 case 'w': /* warning threshold */
183 warn_threshold = strdup(optarg); 190 warn_threshold = strdup(optarg);
184 break; 191 break;
185
186 case 'c': /* warning threshold */ 192 case 'c': /* warning threshold */
187 crit_threshold = strdup(optarg); 193 crit_threshold = strdup(optarg);
188 break; 194 break;
189
190 case 'd': /* data values */ 195 case 'd': /* data values */
191 data_vals=(char *)strdup(optarg); 196 result.config.data_vals = strdup(optarg);
192 /* validate data */ 197 /* validate data */
193 for (ptr=data_vals;ptr!=NULL;ptr+=2){ 198 for (char *ptr = result.config.data_vals; ptr != NULL; ptr += 2) {
194 if (ptr[0]<'0' || ptr[0]>'3') 199 if (ptr[0] < '0' || ptr[0] > '3') {
195 return ERROR; 200 result.errorcode = ERROR;
196 if (ptr[1]=='\0') 201 return result;
202 }
203 if (ptr[1] == '\0') {
197 break; 204 break;
198 if (ptr[1]!=',') 205 }
199 return ERROR; 206 if (ptr[1] != ',') {
207 result.errorcode = ERROR;
208 return result;
209 }
200 } 210 }
201 break; 211 break;
202
203 case 'l': /* text label */ 212 case 'l': /* text label */
204 label=(char *)strdup(optarg); 213 result.config.label = strdup(optarg);
205 break; 214 break;
206
207 case 'v': /* verbose */ 215 case 'v': /* verbose */
208 verbose++; 216 verbose++;
209 break; 217 break;
210
211 case 'V': /* version */ 218 case 'V': /* version */
212 print_revision (progname, NP_VERSION); 219 print_revision(progname, NP_VERSION);
213 exit (STATE_UNKNOWN); 220 exit(STATE_UNKNOWN);
214 break; 221 break;
215
216 case 'H': /* help */ 222 case 'H': /* help */
217 print_help(); 223 print_help();
218 exit(STATE_UNKNOWN); 224 exit(STATE_UNKNOWN);
219 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 }
220 233
234 result.config.output_format_is_set = true;
235 result.config.output_format = parser.output_format;
236 break;
237 }
221 default: 238 default:
222 return ERROR; 239 result.errorcode = ERROR;
240 return result;
223 break; 241 break;
224 } 242 }
225 } 243 }
226 244
227 if(data_vals==NULL) 245 if (result.config.data_vals == NULL) {
228 return ERROR; 246 result.errorcode = ERROR;
247 return result;
248 }
229 249
230 return OK; 250 set_thresholds(&result.config.thresholds, warn_threshold, crit_threshold);
251 return result;
231} 252}
232 253
233void 254void print_help(void) {
234print_help(void)
235{
236 print_revision(progname, NP_VERSION); 255 print_revision(progname, NP_VERSION);
237 printf ("Copyright (c) 2000-2004 Ethan Galstad (nagios@nagios.org)\n"); 256 printf("Copyright (c) 2000-2004 Ethan Galstad (nagios@nagios.org)\n");
238 printf(COPYRIGHT, copyright, email); 257 printf(COPYRIGHT, copyright, email);
239 258
240 printf(_("Host/Service Cluster Plugin for Monitoring")); 259 printf(_("Host/Service Cluster Plugin for Monitoring"));
@@ -245,45 +264,43 @@ print_help(void)
245 printf("\n"); 264 printf("\n");
246 printf("%s\n", _("Options:")); 265 printf("%s\n", _("Options:"));
247 printf(UT_EXTRA_OPTS); 266 printf(UT_EXTRA_OPTS);
248 printf (" %s\n", "-s, --service"); 267 printf(" %s\n", "-s, --service");
249 printf (" %s\n", _("Check service cluster status")); 268 printf(" %s\n", _("Check service cluster status"));
250 printf (" %s\n", "-h, --host"); 269 printf(" %s\n", "-h, --host");
251 printf (" %s\n", _("Check host cluster status")); 270 printf(" %s\n", _("Check host cluster status"));
252 printf (" %s\n", "-l, --label=STRING"); 271 printf(" %s\n", "-l, --label=STRING");
253 printf (" %s\n", _("Optional prepended text output (i.e. \"Host cluster\")")); 272 printf(" %s\n", _("Optional prepended text output (i.e. \"Host cluster\")"));
254 printf (" %s\n", "-w, --warning=THRESHOLD"); 273 printf(" %s\n", "-w, --warning=THRESHOLD");
255 printf (" %s\n", _("Specifies the range of hosts or services in cluster that must be in a")); 274 printf(" %s\n", _("Specifies the range of hosts or services in cluster that must be in a"));
256 printf (" %s\n", _("non-OK state in order to return a WARNING status level")); 275 printf(" %s\n", _("non-OK state in order to return a WARNING status level"));
257 printf (" %s\n", "-c, --critical=THRESHOLD"); 276 printf(" %s\n", "-c, --critical=THRESHOLD");
258 printf (" %s\n", _("Specifies the range of hosts or services in cluster that must be in a")); 277 printf(" %s\n", _("Specifies the range of hosts or services in cluster that must be in a"));
259 printf (" %s\n", _("non-OK state in order to return a CRITICAL status level")); 278 printf(" %s\n", _("non-OK state in order to return a CRITICAL status level"));
260 printf (" %s\n", "-d, --data=LIST"); 279 printf(" %s\n", "-d, --data=LIST");
261 printf (" %s\n", _("The status codes of the hosts or services in the cluster, separated by")); 280 printf(" %s\n", _("The status codes of the hosts or services in the cluster, separated by"));
262 printf (" %s\n", _("commas")); 281 printf(" %s\n", _("commas"));
263 282
264 printf(UT_VERBOSE); 283 printf(UT_VERBOSE);
265 284
285 printf(UT_OUTPUT_FORMAT);
286
266 printf("\n"); 287 printf("\n");
267 printf("%s\n", _("Notes:")); 288 printf("%s\n", _("Notes:"));
268 printf(UT_THRESHOLDS_NOTES); 289 printf(UT_THRESHOLDS_NOTES);
269 290
270 printf ("\n"); 291 printf("\n");
271 printf ("%s\n", _("Examples:")); 292 printf("%s\n", _("Examples:"));
272 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:");
273 printf (" %s\n", _("Will alert critical if there are 3 or more service data points in a non-OK") ); 294 printf(" %s\n",
274 printf (" %s\n", _("state.") ); 295 _("Will alert critical if there are 3 or more service data points in a non-OK"));
296 printf(" %s\n", _("state."));
275 297
276 printf(UT_SUPPORT); 298 printf(UT_SUPPORT);
277} 299}
278 300
279 301void print_usage(void) {
280void
281print_usage(void)
282{
283 302
284 printf("%s\n", _("Usage:")); 303 printf("%s\n", _("Usage:"));
285 printf(" %s (-s | -h) -d val1[,val2,...,valn] [-l label]\n", progname); 304 printf(" %s (-s | -h) -d val1[,val2,...,valn] [-l label]\n", progname);
286 printf("[-w threshold] [-c threshold] [-v] [--help]\n"); 305 printf("[-w threshold] [-c threshold] [-v] [--help]\n");
287
288} 306}
289