summaryrefslogtreecommitdiffstats
path: root/lib/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/output.c')
-rw-r--r--lib/output.c134
1 files changed, 116 insertions, 18 deletions
diff --git a/lib/output.c b/lib/output.c
index 17919afc..34ff7dab 100644
--- a/lib/output.c
+++ b/lib/output.c
@@ -11,8 +11,13 @@
11#include "perfdata.h" 11#include "perfdata.h"
12#include "states.h" 12#include "states.h"
13 13
14// == Global variables
15static mp_output_format output_format = MP_FORMAT_DEFAULT;
16static mp_output_detail_level level_of_detail = MP_DETAIL_ALL;
17
14// == Prototypes == 18// == Prototypes ==
15static char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, unsigned int indentation); 19static char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check,
20 unsigned int indentation);
16static inline cJSON *json_serialize_subcheck(mp_subcheck subcheck); 21static inline cJSON *json_serialize_subcheck(mp_subcheck subcheck);
17 22
18// == Implementation == 23// == Implementation ==
@@ -54,8 +59,9 @@ static inline char *fmt_subcheck_perfdata(mp_subcheck check) {
54 * It sets useful defaults 59 * It sets useful defaults
55 */ 60 */
56mp_check mp_check_init(void) { 61mp_check mp_check_init(void) {
57 mp_check check = {0}; 62 mp_check check = {
58 check.format = MP_FORMAT_DEFAULT; 63 .evaluation_function = &mp_eval_check_default,
64 };
59 return check; 65 return check;
60} 66}
61 67
@@ -118,7 +124,8 @@ void mp_add_perfdata_to_subcheck(mp_subcheck check[static 1], const mp_perfdata
118 */ 124 */
119int mp_add_subcheck_to_subcheck(mp_subcheck check[static 1], mp_subcheck subcheck) { 125int mp_add_subcheck_to_subcheck(mp_subcheck check[static 1], mp_subcheck subcheck) {
120 if (subcheck.output == NULL) { 126 if (subcheck.output == NULL) {
121 die(STATE_UNKNOWN, "%s - %s #%d: %s", __FILE__, __func__, __LINE__, "Sub check output is NULL"); 127 die(STATE_UNKNOWN, "%s - %s #%d: %s", __FILE__, __func__, __LINE__,
128 "Sub check output is NULL");
122 } 129 }
123 130
124 mp_subcheck_list *tmp = NULL; 131 mp_subcheck_list *tmp = NULL;
@@ -191,16 +198,33 @@ char *get_subcheck_summary(mp_check check) {
191 return result; 198 return result;
192} 199}
193 200
201mp_state_enum mp_compute_subcheck_state(const mp_subcheck subcheck) {
202 if (subcheck.evaluation_function == NULL) {
203 return mp_eval_subcheck_default(subcheck);
204 }
205 return subcheck.evaluation_function(subcheck);
206}
207
194/* 208/*
195 * Generate the result state of a mp_subcheck object based on it's own state and it's subchecks states 209 * Generate the result state of a mp_subcheck object based on its own state and its subchecks
210 * states
196 */ 211 */
197mp_state_enum mp_compute_subcheck_state(const mp_subcheck check) { 212mp_state_enum mp_eval_subcheck_default(mp_subcheck subcheck) {
198 if (check.state_set_explicitly) { 213 if (subcheck.evaluation_function != NULL) {
199 return check.state; 214 return subcheck.evaluation_function(subcheck);
200 } 215 }
201 216
202 mp_subcheck_list *scl = check.subchecks; 217 if (subcheck.state_set_explicitly) {
203 mp_state_enum result = check.default_state; 218 return subcheck.state;
219 }
220
221 mp_subcheck_list *scl = subcheck.subchecks;
222
223 if (scl == NULL) {
224 return subcheck.default_state;
225 }
226
227 mp_state_enum result = STATE_OK;
204 228
205 while (scl != NULL) { 229 while (scl != NULL) {
206 result = max_state_alt(result, mp_compute_subcheck_state(scl->subcheck)); 230 result = max_state_alt(result, mp_compute_subcheck_state(scl->subcheck));
@@ -210,10 +234,18 @@ mp_state_enum mp_compute_subcheck_state(const mp_subcheck check) {
210 return result; 234 return result;
211} 235}
212 236
237mp_state_enum mp_compute_check_state(const mp_check check) {
238 // just a safety check
239 if (check.evaluation_function == NULL) {
240 return mp_eval_check_default(check);
241 }
242 return check.evaluation_function(check);
243}
244
213/* 245/*
214 * Generate the result state of a mp_check object based on it's own state and it's subchecks states 246 * Generate the result state of a mp_check object based on it's own state and it's subchecks states
215 */ 247 */
216mp_state_enum mp_compute_check_state(const mp_check check) { 248mp_state_enum mp_eval_check_default(const mp_check check) {
217 assert(check.subchecks != NULL); // a mp_check without subchecks is invalid, die here 249 assert(check.subchecks != NULL); // a mp_check without subchecks is invalid, die here
218 250
219 mp_subcheck_list *scl = check.subchecks; 251 mp_subcheck_list *scl = check.subchecks;
@@ -234,7 +266,7 @@ mp_state_enum mp_compute_check_state(const mp_check check) {
234char *mp_fmt_output(mp_check check) { 266char *mp_fmt_output(mp_check check) {
235 char *result = NULL; 267 char *result = NULL;
236 268
237 switch (check.format) { 269 switch (output_format) {
238 case MP_FORMAT_MULTI_LINE: { 270 case MP_FORMAT_MULTI_LINE: {
239 if (check.summary == NULL) { 271 if (check.summary == NULL) {
240 check.summary = get_subcheck_summary(check); 272 check.summary = get_subcheck_summary(check);
@@ -245,7 +277,11 @@ char *mp_fmt_output(mp_check check) {
245 mp_subcheck_list *subchecks = check.subchecks; 277 mp_subcheck_list *subchecks = check.subchecks;
246 278
247 while (subchecks != NULL) { 279 while (subchecks != NULL) {
248 asprintf(&result, "%s\n%s", result, fmt_subcheck_output(MP_FORMAT_MULTI_LINE, subchecks->subcheck, 1)); 280 if (level_of_detail == MP_DETAIL_ALL ||
281 mp_compute_subcheck_state(subchecks->subcheck) != STATE_OK) {
282 asprintf(&result, "%s\n%s", result,
283 fmt_subcheck_output(MP_FORMAT_MULTI_LINE, subchecks->subcheck, 1));
284 }
249 subchecks = subchecks->next; 285 subchecks = subchecks->next;
250 } 286 }
251 287
@@ -256,7 +292,8 @@ char *mp_fmt_output(mp_check check) {
256 if (pd_string == NULL) { 292 if (pd_string == NULL) {
257 asprintf(&pd_string, "%s", fmt_subcheck_perfdata(subchecks->subcheck)); 293 asprintf(&pd_string, "%s", fmt_subcheck_perfdata(subchecks->subcheck));
258 } else { 294 } else {
259 asprintf(&pd_string, "%s %s", pd_string, fmt_subcheck_perfdata(subchecks->subcheck)); 295 asprintf(&pd_string, "%s %s", pd_string,
296 fmt_subcheck_perfdata(subchecks->subcheck));
260 } 297 }
261 298
262 subchecks = subchecks->next; 299 subchecks = subchecks->next;
@@ -325,22 +362,55 @@ static char *generate_indentation_string(unsigned int indentation) {
325/* 362/*
326 * Helper function to generate the output string of mp_subcheck 363 * Helper function to generate the output string of mp_subcheck
327 */ 364 */
328static inline char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, unsigned int indentation) { 365static inline char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check,
366 unsigned int indentation) {
329 char *result = NULL; 367 char *result = NULL;
330 mp_subcheck_list *subchecks = NULL; 368 mp_subcheck_list *subchecks = NULL;
331 369
332 switch (output_format) { 370 switch (output_format) {
333 case MP_FORMAT_MULTI_LINE: 371 case MP_FORMAT_MULTI_LINE: {
372 char *tmp_string = NULL;
373 if ((tmp_string = strchr(check.output, '\n')) != NULL) {
374 // This is a multiline string, put the correct indentation in before proceeding
375 char *intermediate_string = "";
376 bool have_residual_chars = false;
377
378 while (tmp_string != NULL) {
379 *tmp_string = '\0';
380 asprintf(&intermediate_string, "%s%s\n%s", intermediate_string,check.output, generate_indentation_string(indentation+1)); // one more indentation to make it look better
381
382 if (*(tmp_string + 1) != '\0') {
383 check.output = tmp_string + 1;
384 have_residual_chars = true;
385 } else {
386 // Null after the \n, so this is the end
387 have_residual_chars = false;
388 break;
389 }
390
391 tmp_string = strchr(check.output, '\n');
392 }
393
394 // add the rest (if any)
395 if (have_residual_chars) {
396 char *tmp = check.output;
397 xasprintf(&check.output, "%s\n%s%s", intermediate_string, generate_indentation_string(indentation+1), tmp);
398 } else {
399 check.output = intermediate_string;
400 }
401 }
334 asprintf(&result, "%s\\_[%s] - %s", generate_indentation_string(indentation), state_text(mp_compute_subcheck_state(check)), 402 asprintf(&result, "%s\\_[%s] - %s", generate_indentation_string(indentation), state_text(mp_compute_subcheck_state(check)),
335 check.output); 403 check.output);
336 404
337 subchecks = check.subchecks; 405 subchecks = check.subchecks;
338 406
339 while (subchecks != NULL) { 407 while (subchecks != NULL) {
340 asprintf(&result, "%s\n%s", result, fmt_subcheck_output(output_format, subchecks->subcheck, indentation + 1)); 408 asprintf(&result, "%s\n%s", result,
409 fmt_subcheck_output(output_format, subchecks->subcheck, indentation + 1));
341 subchecks = subchecks->next; 410 subchecks = subchecks->next;
342 } 411 }
343 return result; 412 return result;
413 }
344 default: 414 default:
345 die(STATE_UNKNOWN, "Invalid format"); 415 die(STATE_UNKNOWN, "Invalid format");
346 } 416 }
@@ -482,7 +552,7 @@ void mp_print_output(mp_check check) { puts(mp_fmt_output(check)); }
482 */ 552 */
483void mp_exit(mp_check check) { 553void mp_exit(mp_check check) {
484 mp_print_output(check); 554 mp_print_output(check);
485 if (check.format == MP_FORMAT_TEST_JSON) { 555 if (output_format == MP_FORMAT_TEST_JSON) {
486 exit(0); 556 exit(0);
487 } 557 }
488 558
@@ -533,3 +603,31 @@ parsed_output_format mp_parse_output_format(char *format_string) {
533 603
534 return result; 604 return result;
535} 605}
606
607void mp_set_format(mp_output_format format) { output_format = format; }
608
609mp_output_format mp_get_format(void) { return output_format; }
610
611void mp_set_level_of_detail(mp_output_detail_level level) { level_of_detail = level; }
612
613mp_output_detail_level mp_get_level_of_detail(void) { return level_of_detail; }
614
615mp_state_enum mp_eval_ok(mp_check overall) {
616 (void)overall;
617 return STATE_OK;
618}
619
620mp_state_enum mp_eval_warning(mp_check overall) {
621 (void)overall;
622 return STATE_WARNING;
623}
624
625mp_state_enum mp_eval_critical(mp_check overall) {
626 (void)overall;
627 return STATE_CRITICAL;
628}
629
630mp_state_enum mp_eval_unknown(mp_check overall) {
631 (void)overall;
632 return STATE_UNKNOWN;
633}