From 322cd6f829e55a91edbfc42201775afb552b5660 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sat, 17 May 2025 11:26:27 +0200 Subject: Lib: Add perfdata for char and unsigned char --- lib/perfdata.c | 8 ++++++++ lib/perfdata.h | 4 ++++ 2 files changed, 12 insertions(+) (limited to 'lib') diff --git a/lib/perfdata.c b/lib/perfdata.c index f425ffcf..b87de7e0 100644 --- a/lib/perfdata.c +++ b/lib/perfdata.c @@ -257,6 +257,10 @@ mp_perfdata mp_set_pd_value_double(mp_perfdata pd, double value) { return pd; } +mp_perfdata mp_set_pd_value_char(mp_perfdata pd, char value) { return mp_set_pd_value_long_long(pd, (long long)value); } + +mp_perfdata mp_set_pd_value_u_char(mp_perfdata pd, unsigned char value) { return mp_set_pd_value_u_long_long(pd, (unsigned long long)value); } + mp_perfdata mp_set_pd_value_int(mp_perfdata pd, int value) { return mp_set_pd_value_long_long(pd, (long long)value); } mp_perfdata mp_set_pd_value_u_int(mp_perfdata pd, unsigned int value) { return mp_set_pd_value_u_long_long(pd, (unsigned long long)value); } @@ -288,6 +292,10 @@ mp_perfdata_value mp_create_pd_value_double(double value) { mp_perfdata_value mp_create_pd_value_float(float value) { return mp_create_pd_value_double((double)value); } +mp_perfdata_value mp_create_pd_value_char(char value) { return mp_create_pd_value_long_long((long long)value); } + +mp_perfdata_value mp_create_pd_value_u_char(unsigned char value) { return mp_create_pd_value_u_long_long((unsigned long long)value); } + mp_perfdata_value mp_create_pd_value_int(int value) { return mp_create_pd_value_long_long((long long)value); } mp_perfdata_value mp_create_pd_value_u_int(unsigned int value) { return mp_create_pd_value_u_long_long((unsigned long long)value); } diff --git a/lib/perfdata.h b/lib/perfdata.h index cb552678..7fd908a9 100644 --- a/lib/perfdata.h +++ b/lib/perfdata.h @@ -155,6 +155,8 @@ mp_perfdata mp_set_pd_value_u_long_long(mp_perfdata, unsigned long long); _Generic((V), \ float: mp_create_pd_value_float, \ double: mp_create_pd_value_double, \ + char: mp_create_pd_value_char, \ + unsigned char: mp_create_pd_value_u_char, \ int: mp_create_pd_value_int, \ unsigned int: mp_create_pd_value_u_int, \ long: mp_create_pd_value_long, \ @@ -164,6 +166,8 @@ mp_perfdata mp_set_pd_value_u_long_long(mp_perfdata, unsigned long long); mp_perfdata_value mp_create_pd_value_float(float); mp_perfdata_value mp_create_pd_value_double(double); +mp_perfdata_value mp_create_pd_value_char(char); +mp_perfdata_value mp_create_pd_value_u_char(unsigned char); mp_perfdata_value mp_create_pd_value_int(int); mp_perfdata_value mp_create_pd_value_u_int(unsigned int); mp_perfdata_value mp_create_pd_value_long(long); -- cgit v1.2.3-74-g34f1 From b71cb430cb79e89b5d8bf56990919b6c753cd271 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 19 Jun 2025 01:15:11 +0200 Subject: Implement flexible state override functions --- lib/output.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++------------- lib/output.h | 31 ++++++++++++++++++----- 2 files changed, 90 insertions(+), 24 deletions(-) (limited to 'lib') diff --git a/lib/output.c b/lib/output.c index c408a2f5..b398c2ad 100644 --- a/lib/output.c +++ b/lib/output.c @@ -16,7 +16,8 @@ static mp_output_format output_format = MP_FORMAT_DEFAULT; static mp_output_detail_level level_of_detail = MP_DETAIL_ALL; // == Prototypes == -static char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, unsigned int indentation); +static char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, + unsigned int indentation); static inline cJSON *json_serialize_subcheck(mp_subcheck subcheck); // == Implementation == @@ -58,7 +59,9 @@ static inline char *fmt_subcheck_perfdata(mp_subcheck check) { * It sets useful defaults */ mp_check mp_check_init(void) { - mp_check check = {0}; + mp_check check = { + .evaluation_function = &mp_eval_check_default, + }; return check; } @@ -121,7 +124,8 @@ void mp_add_perfdata_to_subcheck(mp_subcheck check[static 1], const mp_perfdata */ int mp_add_subcheck_to_subcheck(mp_subcheck check[static 1], mp_subcheck subcheck) { if (subcheck.output == NULL) { - die(STATE_UNKNOWN, "%s - %s #%d: %s", __FILE__, __func__, __LINE__, "Sub check output is NULL"); + die(STATE_UNKNOWN, "%s - %s #%d: %s", __FILE__, __func__, __LINE__, + "Sub check output is NULL"); } mp_subcheck_list *tmp = NULL; @@ -194,18 +198,30 @@ char *get_subcheck_summary(mp_check check) { return result; } +mp_state_enum mp_compute_subcheck_state(const mp_subcheck subcheck) { + if (subcheck.evaluation_function == NULL) { + return mp_eval_subcheck_default(subcheck); + } + return subcheck.evaluation_function(subcheck); +} + /* - * Generate the result state of a mp_subcheck object based on it's own state and it's subchecks states + * Generate the result state of a mp_subcheck object based on its own state and its subchecks + * states */ -mp_state_enum mp_compute_subcheck_state(const mp_subcheck check) { - if (check.state_set_explicitly) { - return check.state; +mp_state_enum mp_eval_subcheck_default(mp_subcheck subcheck) { + if (subcheck.evaluation_function != NULL) { + return subcheck.evaluation_function(subcheck); } - mp_subcheck_list *scl = check.subchecks; + if (subcheck.state_set_explicitly) { + return subcheck.state; + } + + mp_subcheck_list *scl = subcheck.subchecks; if (scl == NULL) { - return check.default_state; + return subcheck.default_state; } mp_state_enum result = STATE_OK; @@ -218,10 +234,18 @@ mp_state_enum mp_compute_subcheck_state(const mp_subcheck check) { return result; } +mp_state_enum mp_compute_check_state(const mp_check check) { + // just a safety check + if (check.evaluation_function == NULL) { + return mp_eval_check_default(check); + } + return check.evaluation_function(check); +} + /* * Generate the result state of a mp_check object based on it's own state and it's subchecks states */ -mp_state_enum mp_compute_check_state(const mp_check check) { +mp_state_enum mp_eval_check_default(const mp_check check) { assert(check.subchecks != NULL); // a mp_check without subchecks is invalid, die here mp_subcheck_list *scl = check.subchecks; @@ -253,8 +277,10 @@ char *mp_fmt_output(mp_check check) { mp_subcheck_list *subchecks = check.subchecks; while (subchecks != NULL) { - if (level_of_detail == MP_DETAIL_ALL || mp_compute_subcheck_state(subchecks->subcheck) != STATE_OK) { - asprintf(&result, "%s\n%s", result, fmt_subcheck_output(MP_FORMAT_MULTI_LINE, subchecks->subcheck, 1)); + if (level_of_detail == MP_DETAIL_ALL || + mp_compute_subcheck_state(subchecks->subcheck) != STATE_OK) { + asprintf(&result, "%s\n%s", result, + fmt_subcheck_output(MP_FORMAT_MULTI_LINE, subchecks->subcheck, 1)); } subchecks = subchecks->next; } @@ -266,7 +292,8 @@ char *mp_fmt_output(mp_check check) { if (pd_string == NULL) { asprintf(&pd_string, "%s", fmt_subcheck_perfdata(subchecks->subcheck)); } else { - asprintf(&pd_string, "%s %s", pd_string, fmt_subcheck_perfdata(subchecks->subcheck)); + asprintf(&pd_string, "%s %s", pd_string, + fmt_subcheck_perfdata(subchecks->subcheck)); } subchecks = subchecks->next; @@ -335,19 +362,21 @@ static char *generate_indentation_string(unsigned int indentation) { /* * Helper function to generate the output string of mp_subcheck */ -static inline char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, unsigned int indentation) { +static inline char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, + unsigned int indentation) { char *result = NULL; mp_subcheck_list *subchecks = NULL; switch (output_format) { case MP_FORMAT_MULTI_LINE: - asprintf(&result, "%s\\_[%s] - %s", generate_indentation_string(indentation), state_text(mp_compute_subcheck_state(check)), - check.output); + asprintf(&result, "%s\\_[%s] - %s", generate_indentation_string(indentation), + state_text(mp_compute_subcheck_state(check)), check.output); subchecks = check.subchecks; while (subchecks != NULL) { - asprintf(&result, "%s\n%s", result, fmt_subcheck_output(output_format, subchecks->subcheck, indentation + 1)); + asprintf(&result, "%s\n%s", result, + fmt_subcheck_output(output_format, subchecks->subcheck, indentation + 1)); subchecks = subchecks->next; } return result; @@ -551,3 +580,23 @@ mp_output_format mp_get_format(void) { return output_format; } void mp_set_level_of_detail(mp_output_detail_level level) { level_of_detail = level; } mp_output_detail_level mp_get_level_of_detail(void) { return level_of_detail; } + +mp_state_enum mp_eval_ok(mp_check overall) { + (void)overall; + return STATE_OK; +} + +mp_state_enum mp_eval_warning(mp_check overall) { + (void)overall; + return STATE_WARNING; +} + +mp_state_enum mp_eval_critical(mp_check overall) { + (void)overall; + return STATE_CRITICAL; +} + +mp_state_enum mp_eval_unknown(mp_check overall) { + (void)overall; + return STATE_UNKNOWN; +} diff --git a/lib/output.h b/lib/output.h index 3bd91f90..c63c8e3f 100644 --- a/lib/output.h +++ b/lib/output.h @@ -7,15 +7,21 @@ /* * A partial check result */ -typedef struct { +typedef struct mp_subcheck mp_subcheck; +struct mp_subcheck { mp_state_enum state; // OK, Warning, Critical ... set explicitly mp_state_enum default_state; // OK, Warning, Critical .. if not set explicitly - bool state_set_explicitly; // was the state set explicitly (or should it be derived from subchecks) + bool state_set_explicitly; // was the state set explicitly (or should it be derived from + // subchecks) - char *output; // Text output for humans ("Filesystem xyz is fine", "Could not create TCP connection to..") - pd_list *perfdata; // Performance data for this check + char *output; // Text output for humans ("Filesystem xyz is fine", "Could not create TCP + // connection to..") + pd_list *perfdata; // Performance data for this check struct subcheck_list *subchecks; // subchecks deeper in the hierarchy -} mp_subcheck; + + // the evaluation_functions computes the state of subcheck + mp_state_enum (*evaluation_function)(mp_subcheck); +}; /* * A list of subchecks, used in subchecks and the main check @@ -57,10 +63,14 @@ mp_output_detail_level mp_get_level_of_detail(void); * The final result is always derived from the children and the "worst" state * in the first layer of subchecks */ -typedef struct { +typedef struct mp_check mp_check; +struct mp_check { char *summary; // Overall summary, if not set a summary will be automatically generated mp_subcheck_list *subchecks; -} mp_check; + + // the evaluation_functions computes the state of check + mp_state_enum (*evaluation_function)(mp_check); +}; mp_check mp_check_init(void); mp_subcheck mp_subcheck_init(void); @@ -78,6 +88,13 @@ void mp_add_summary(mp_check check[static 1], char *summary); mp_state_enum mp_compute_check_state(mp_check); mp_state_enum mp_compute_subcheck_state(mp_subcheck); +mp_state_enum mp_eval_ok(mp_check overall); +mp_state_enum mp_eval_warning(mp_check overall); +mp_state_enum mp_eval_critical(mp_check overall); +mp_state_enum mp_eval_unknown(mp_check overall); +mp_state_enum mp_eval_check_default(mp_check check); +mp_state_enum mp_eval_subcheck_default(mp_subcheck subcheck); + typedef struct { bool parsing_success; mp_output_format output_format; -- cgit v1.2.3-74-g34f1