diff options
Diffstat (limited to 'lib/output.c')
-rw-r--r-- | lib/output.c | 122 |
1 files changed, 107 insertions, 15 deletions
diff --git a/lib/output.c b/lib/output.c index 61fbf832..34ff7dab 100644 --- a/lib/output.c +++ b/lib/output.c | |||
@@ -13,9 +13,11 @@ | |||
13 | 13 | ||
14 | // == Global variables | 14 | // == Global variables |
15 | static mp_output_format output_format = MP_FORMAT_DEFAULT; | 15 | static mp_output_format output_format = MP_FORMAT_DEFAULT; |
16 | static mp_output_detail_level level_of_detail = MP_DETAIL_ALL; | ||
16 | 17 | ||
17 | // == Prototypes == | 18 | // == Prototypes == |
18 | 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); | ||
19 | static inline cJSON *json_serialize_subcheck(mp_subcheck subcheck); | 21 | static inline cJSON *json_serialize_subcheck(mp_subcheck subcheck); |
20 | 22 | ||
21 | // == Implementation == | 23 | // == Implementation == |
@@ -57,7 +59,9 @@ static inline char *fmt_subcheck_perfdata(mp_subcheck check) { | |||
57 | * It sets useful defaults | 59 | * It sets useful defaults |
58 | */ | 60 | */ |
59 | mp_check mp_check_init(void) { | 61 | mp_check mp_check_init(void) { |
60 | mp_check check = {0}; | 62 | mp_check check = { |
63 | .evaluation_function = &mp_eval_check_default, | ||
64 | }; | ||
61 | return check; | 65 | return check; |
62 | } | 66 | } |
63 | 67 | ||
@@ -120,7 +124,8 @@ void mp_add_perfdata_to_subcheck(mp_subcheck check[static 1], const mp_perfdata | |||
120 | */ | 124 | */ |
121 | 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) { |
122 | if (subcheck.output == NULL) { | 126 | if (subcheck.output == NULL) { |
123 | 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"); | ||
124 | } | 129 | } |
125 | 130 | ||
126 | mp_subcheck_list *tmp = NULL; | 131 | mp_subcheck_list *tmp = NULL; |
@@ -193,16 +198,33 @@ char *get_subcheck_summary(mp_check check) { | |||
193 | return result; | 198 | return result; |
194 | } | 199 | } |
195 | 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 | |||
196 | /* | 208 | /* |
197 | * 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 | ||
198 | */ | 211 | */ |
199 | mp_state_enum mp_compute_subcheck_state(const mp_subcheck check) { | 212 | mp_state_enum mp_eval_subcheck_default(mp_subcheck subcheck) { |
200 | if (check.state_set_explicitly) { | 213 | if (subcheck.evaluation_function != NULL) { |
201 | return check.state; | 214 | return subcheck.evaluation_function(subcheck); |
202 | } | 215 | } |
203 | 216 | ||
204 | mp_subcheck_list *scl = check.subchecks; | 217 | if (subcheck.state_set_explicitly) { |
205 | 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; | ||
206 | 228 | ||
207 | while (scl != NULL) { | 229 | while (scl != NULL) { |
208 | result = max_state_alt(result, mp_compute_subcheck_state(scl->subcheck)); | 230 | result = max_state_alt(result, mp_compute_subcheck_state(scl->subcheck)); |
@@ -212,10 +234,18 @@ mp_state_enum mp_compute_subcheck_state(const mp_subcheck check) { | |||
212 | return result; | 234 | return result; |
213 | } | 235 | } |
214 | 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 | |||
215 | /* | 245 | /* |
216 | * 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 |
217 | */ | 247 | */ |
218 | mp_state_enum mp_compute_check_state(const mp_check check) { | 248 | mp_state_enum mp_eval_check_default(const mp_check check) { |
219 | 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 |
220 | 250 | ||
221 | mp_subcheck_list *scl = check.subchecks; | 251 | mp_subcheck_list *scl = check.subchecks; |
@@ -247,7 +277,11 @@ char *mp_fmt_output(mp_check check) { | |||
247 | mp_subcheck_list *subchecks = check.subchecks; | 277 | mp_subcheck_list *subchecks = check.subchecks; |
248 | 278 | ||
249 | while (subchecks != NULL) { | 279 | while (subchecks != NULL) { |
250 | 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 | } | ||
251 | subchecks = subchecks->next; | 285 | subchecks = subchecks->next; |
252 | } | 286 | } |
253 | 287 | ||
@@ -258,7 +292,8 @@ char *mp_fmt_output(mp_check check) { | |||
258 | if (pd_string == NULL) { | 292 | if (pd_string == NULL) { |
259 | asprintf(&pd_string, "%s", fmt_subcheck_perfdata(subchecks->subcheck)); | 293 | asprintf(&pd_string, "%s", fmt_subcheck_perfdata(subchecks->subcheck)); |
260 | } else { | 294 | } else { |
261 | 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)); | ||
262 | } | 297 | } |
263 | 298 | ||
264 | subchecks = subchecks->next; | 299 | subchecks = subchecks->next; |
@@ -327,22 +362,55 @@ static char *generate_indentation_string(unsigned int indentation) { | |||
327 | /* | 362 | /* |
328 | * Helper function to generate the output string of mp_subcheck | 363 | * Helper function to generate the output string of mp_subcheck |
329 | */ | 364 | */ |
330 | 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) { | ||
331 | char *result = NULL; | 367 | char *result = NULL; |
332 | mp_subcheck_list *subchecks = NULL; | 368 | mp_subcheck_list *subchecks = NULL; |
333 | 369 | ||
334 | switch (output_format) { | 370 | switch (output_format) { |
335 | 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 | } | ||
336 | 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)), |
337 | check.output); | 403 | check.output); |
338 | 404 | ||
339 | subchecks = check.subchecks; | 405 | subchecks = check.subchecks; |
340 | 406 | ||
341 | while (subchecks != NULL) { | 407 | while (subchecks != NULL) { |
342 | 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)); | ||
343 | subchecks = subchecks->next; | 410 | subchecks = subchecks->next; |
344 | } | 411 | } |
345 | return result; | 412 | return result; |
413 | } | ||
346 | default: | 414 | default: |
347 | die(STATE_UNKNOWN, "Invalid format"); | 415 | die(STATE_UNKNOWN, "Invalid format"); |
348 | } | 416 | } |
@@ -539,3 +607,27 @@ parsed_output_format mp_parse_output_format(char *format_string) { | |||
539 | void mp_set_format(mp_output_format format) { output_format = format; } | 607 | void mp_set_format(mp_output_format format) { output_format = format; } |
540 | 608 | ||
541 | mp_output_format mp_get_format(void) { return output_format; } | 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 | } | ||