diff options
Diffstat (limited to 'lib/output.c')
-rw-r--r-- | lib/output.c | 134 |
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 | ||
15 | static mp_output_format output_format = MP_FORMAT_DEFAULT; | ||
16 | static mp_output_detail_level level_of_detail = MP_DETAIL_ALL; | ||
17 | |||
14 | // == Prototypes == | 18 | // == Prototypes == |
15 | static char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, unsigned int indentation); | 19 | static char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, |
20 | unsigned int indentation); | ||
16 | static inline cJSON *json_serialize_subcheck(mp_subcheck subcheck); | 21 | static 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 | */ |
56 | mp_check mp_check_init(void) { | 61 | mp_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 | */ |
119 | int mp_add_subcheck_to_subcheck(mp_subcheck check[static 1], mp_subcheck subcheck) { | 125 | int 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 | ||
201 | mp_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 | */ |
197 | mp_state_enum mp_compute_subcheck_state(const mp_subcheck check) { | 212 | mp_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 | ||
237 | mp_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 | */ |
216 | mp_state_enum mp_compute_check_state(const mp_check check) { | 248 | mp_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) { | |||
234 | char *mp_fmt_output(mp_check check) { | 266 | char *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 | */ |
328 | static inline char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, unsigned int indentation) { | 365 | static 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 | */ |
483 | void mp_exit(mp_check check) { | 553 | void 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 | |||
607 | void mp_set_format(mp_output_format format) { output_format = format; } | ||
608 | |||
609 | mp_output_format mp_get_format(void) { return output_format; } | ||
610 | |||
611 | void mp_set_level_of_detail(mp_output_detail_level level) { level_of_detail = level; } | ||
612 | |||
613 | mp_output_detail_level mp_get_level_of_detail(void) { return level_of_detail; } | ||
614 | |||
615 | mp_state_enum mp_eval_ok(mp_check overall) { | ||
616 | (void)overall; | ||
617 | return STATE_OK; | ||
618 | } | ||
619 | |||
620 | mp_state_enum mp_eval_warning(mp_check overall) { | ||
621 | (void)overall; | ||
622 | return STATE_WARNING; | ||
623 | } | ||
624 | |||
625 | mp_state_enum mp_eval_critical(mp_check overall) { | ||
626 | (void)overall; | ||
627 | return STATE_CRITICAL; | ||
628 | } | ||
629 | |||
630 | mp_state_enum mp_eval_unknown(mp_check overall) { | ||
631 | (void)overall; | ||
632 | return STATE_UNKNOWN; | ||
633 | } | ||