X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fdaemon%2Futils_match.c;h=2e487b5933fc0b32525ea000fabca09e45b65772;hb=936c450a86c841eea89888c8550c9118fae90c25;hp=914b6e278c746c1dd04e44a603894377f3991c0c;hpb=f7e7130af45d2320d5bf1a4c7cf6f553f213f1fc;p=collectd.git diff --git a/src/daemon/utils_match.c b/src/daemon/utils_match.c index 914b6e27..2e487b59 100644 --- a/src/daemon/utils_match.c +++ b/src/daemon/utils_match.c @@ -33,112 +33,98 @@ #include -#define UTILS_MATCH_FLAGS_FREE_USER_DATA 0x01 #define UTILS_MATCH_FLAGS_EXCLUDE_REGEX 0x02 -struct cu_match_s -{ +struct cu_match_s { regex_t regex; regex_t excluderegex; int flags; - int (*callback) (const char *str, char * const *matches, size_t matches_num, - void *user_data); + int (*callback)(const char *str, char *const *matches, size_t matches_num, + void *user_data); void *user_data; + void (*free)(void *user_data); }; /* * Private functions */ -static char *match_substr (const char *str, int begin, int end) -{ +static char *match_substr(const char *str, int begin, int end) { char *ret; size_t ret_len; if ((begin < 0) || (end < 0) || (begin >= end)) return (NULL); - if ((size_t) end > (strlen (str) + 1)) - { - ERROR ("utils_match: match_substr: `end' points after end of string."); + if ((size_t)end > (strlen(str) + 1)) { + ERROR("utils_match: match_substr: `end' points after end of string."); return (NULL); } ret_len = end - begin; - ret = malloc (ret_len + 1); - if (ret == NULL) - { - ERROR ("utils_match: match_substr: malloc failed."); + ret = malloc(ret_len + 1); + if (ret == NULL) { + ERROR("utils_match: match_substr: malloc failed."); return (NULL); } - sstrncpy (ret, str + begin, ret_len + 1); + sstrncpy(ret, str + begin, ret_len + 1); return (ret); } /* char *match_substr */ -static int default_callback (const char __attribute__((unused)) *str, - char * const *matches, size_t matches_num, void *user_data) -{ - cu_match_value_t *data = (cu_match_value_t *) user_data; +static int default_callback(const char __attribute__((unused)) * str, + char *const *matches, size_t matches_num, + void *user_data) { + cu_match_value_t *data = (cu_match_value_t *)user_data; - if (data->ds_type & UTILS_MATCH_DS_TYPE_GAUGE) - { + if (data->ds_type & UTILS_MATCH_DS_TYPE_GAUGE) { gauge_t value; char *endptr = NULL; - if (data->ds_type & UTILS_MATCH_CF_GAUGE_INC) - { - data->value.gauge = isnan (data->value.gauge) ? 1 : data->value.gauge + 1; + if (data->ds_type & UTILS_MATCH_CF_GAUGE_INC) { + data->value.gauge = isnan(data->value.gauge) ? 1 : data->value.gauge + 1; data->values_num++; - return(0); + return (0); } if (matches_num < 2) return (-1); - value = (gauge_t) strtod (matches[1], &endptr); + value = (gauge_t)strtod(matches[1], &endptr); if (matches[1] == endptr) return (-1); - if ((data->values_num == 0) - || (data->ds_type & UTILS_MATCH_CF_GAUGE_LAST)) - { - data->value.gauge = value; + if (data->ds_type & UTILS_MATCH_CF_GAUGE_DIST) { + latency_counter_add(data->latency, DOUBLE_TO_CDTIME_T(value)); + data->values_num++; + return (0); } - else if (data->ds_type & UTILS_MATCH_CF_GAUGE_AVERAGE) - { - double f = ((double) data->values_num) - / ((double) (data->values_num + 1)); + + if ((data->values_num == 0) || + (data->ds_type & UTILS_MATCH_CF_GAUGE_LAST) || + (data->ds_type & UTILS_MATCH_CF_GAUGE_PERSIST)) { + data->value.gauge = value; + } else if (data->ds_type & UTILS_MATCH_CF_GAUGE_AVERAGE) { + double f = ((double)data->values_num) / ((double)(data->values_num + 1)); data->value.gauge = (data->value.gauge * f) + (value * (1.0 - f)); - } - else if (data->ds_type & UTILS_MATCH_CF_GAUGE_MIN) - { + } else if (data->ds_type & UTILS_MATCH_CF_GAUGE_MIN) { if (data->value.gauge > value) - data->value.gauge = value; - } - else if (data->ds_type & UTILS_MATCH_CF_GAUGE_MAX) - { + data->value.gauge = value; + } else if (data->ds_type & UTILS_MATCH_CF_GAUGE_MAX) { if (data->value.gauge < value) - data->value.gauge = value; - } - else if (data->ds_type & UTILS_MATCH_CF_GAUGE_ADD) - { + data->value.gauge = value; + } else if (data->ds_type & UTILS_MATCH_CF_GAUGE_ADD) { data->value.gauge += value; - } - else - { - ERROR ("utils_match: default_callback: obj->ds_type is invalid!"); + } else { + ERROR("utils_match: default_callback: obj->ds_type is invalid!"); return (-1); } data->values_num++; - } - else if (data->ds_type & UTILS_MATCH_DS_TYPE_COUNTER) - { + } else if (data->ds_type & UTILS_MATCH_DS_TYPE_COUNTER) { counter_t value; char *endptr = NULL; - if (data->ds_type & UTILS_MATCH_CF_COUNTER_INC) - { + if (data->ds_type & UTILS_MATCH_CF_COUNTER_INC) { data->value.counter++; data->values_num++; return (0); @@ -147,7 +133,7 @@ static int default_callback (const char __attribute__((unused)) *str, if (matches_num < 2) return (-1); - value = (counter_t) strtoull (matches[1], &endptr, 0); + value = (counter_t)strtoull(matches[1], &endptr, 0); if (matches[1] == endptr) return (-1); @@ -155,21 +141,17 @@ static int default_callback (const char __attribute__((unused)) *str, data->value.counter = value; else if (data->ds_type & UTILS_MATCH_CF_COUNTER_ADD) data->value.counter += value; - else - { - ERROR ("utils_match: default_callback: obj->ds_type is invalid!"); + else { + ERROR("utils_match: default_callback: obj->ds_type is invalid!"); return (-1); } data->values_num++; - } - else if (data->ds_type & UTILS_MATCH_DS_TYPE_DERIVE) - { + } else if (data->ds_type & UTILS_MATCH_DS_TYPE_DERIVE) { derive_t value; char *endptr = NULL; - if (data->ds_type & UTILS_MATCH_CF_DERIVE_INC) - { + if (data->ds_type & UTILS_MATCH_CF_DERIVE_INC) { data->value.derive++; data->values_num++; return (0); @@ -178,7 +160,7 @@ static int default_callback (const char __attribute__((unused)) *str, if (matches_num < 2) return (-1); - value = (derive_t) strtoll (matches[1], &endptr, 0); + value = (derive_t)strtoll(matches[1], &endptr, 0); if (matches[1] == endptr) return (-1); @@ -186,152 +168,158 @@ static int default_callback (const char __attribute__((unused)) *str, data->value.derive = value; else if (data->ds_type & UTILS_MATCH_CF_DERIVE_ADD) data->value.derive += value; - else - { - ERROR ("utils_match: default_callback: obj->ds_type is invalid!"); + else { + ERROR("utils_match: default_callback: obj->ds_type is invalid!"); return (-1); } data->values_num++; - } - else if (data->ds_type & UTILS_MATCH_DS_TYPE_ABSOLUTE) - { + } else if (data->ds_type & UTILS_MATCH_DS_TYPE_ABSOLUTE) { absolute_t value; char *endptr = NULL; if (matches_num < 2) return (-1); - value = (absolute_t) strtoull (matches[1], &endptr, 0); + value = (absolute_t)strtoull(matches[1], &endptr, 0); if (matches[1] == endptr) return (-1); if (data->ds_type & UTILS_MATCH_CF_ABSOLUTE_SET) data->value.absolute = value; - else - { - ERROR ("utils_match: default_callback: obj->ds_type is invalid!"); + else { + ERROR("utils_match: default_callback: obj->ds_type is invalid!"); return (-1); } data->values_num++; - } - else - { - ERROR ("utils_match: default_callback: obj->ds_type is invalid!"); + } else { + ERROR("utils_match: default_callback: obj->ds_type is invalid!"); return (-1); } return (0); } /* int default_callback */ +static void match_simple_free(void *data) { + cu_match_value_t *user_data = (cu_match_value_t *)data; + if (user_data->latency) + latency_counter_destroy(user_data->latency); + + free(data); +} /* void match_simple_free */ + /* * Public functions */ -cu_match_t *match_create_callback (const char *regex, const char *excluderegex, - int (*callback) (const char *str, - char * const *matches, size_t matches_num, void *user_data), - void *user_data) -{ +cu_match_t * +match_create_callback(const char *regex, const char *excluderegex, + int (*callback)(const char *str, char *const *matches, + size_t matches_num, void *user_data), + void *user_data, + void (*free_user_data)(void *user_data)) { cu_match_t *obj; int status; - DEBUG ("utils_match: match_create_callback: regex = %s, excluderegex = %s", - regex, excluderegex); + DEBUG("utils_match: match_create_callback: regex = %s, excluderegex = %s", + regex, excluderegex); - obj = calloc (1, sizeof (*obj)); + obj = calloc(1, sizeof(*obj)); if (obj == NULL) return (NULL); - status = regcomp (&obj->regex, regex, REG_EXTENDED | REG_NEWLINE); - if (status != 0) - { - ERROR ("Compiling the regular expression \"%s\" failed.", regex); - sfree (obj); + status = regcomp(&obj->regex, regex, REG_EXTENDED | REG_NEWLINE); + if (status != 0) { + ERROR("Compiling the regular expression \"%s\" failed.", regex); + sfree(obj); return (NULL); } if (excluderegex && strcmp(excluderegex, "") != 0) { - status = regcomp (&obj->excluderegex, excluderegex, REG_EXTENDED); - if (status != 0) - { - ERROR ("Compiling the excluding regular expression \"%s\" failed.", - excluderegex); - sfree (obj); - return (NULL); + status = regcomp(&obj->excluderegex, excluderegex, REG_EXTENDED); + if (status != 0) { + ERROR("Compiling the excluding regular expression \"%s\" failed.", + excluderegex); + sfree(obj); + return (NULL); } obj->flags |= UTILS_MATCH_FLAGS_EXCLUDE_REGEX; } obj->callback = callback; obj->user_data = user_data; + obj->free = free_user_data; return (obj); } /* cu_match_t *match_create_callback */ -cu_match_t *match_create_simple (const char *regex, - const char *excluderegex, int match_ds_type) -{ +cu_match_t *match_create_simple(const char *regex, const char *excluderegex, + int match_ds_type) { cu_match_value_t *user_data; cu_match_t *obj; - user_data = calloc (1, sizeof (*user_data)); + user_data = calloc(1, sizeof(*user_data)); if (user_data == NULL) return (NULL); user_data->ds_type = match_ds_type; - obj = match_create_callback (regex, excluderegex, - default_callback, user_data); - if (obj == NULL) - { - sfree (user_data); - return (NULL); + if ((match_ds_type & UTILS_MATCH_DS_TYPE_GAUGE) && + (match_ds_type & UTILS_MATCH_CF_GAUGE_DIST)) { + user_data->latency = latency_counter_create(); + if (user_data->latency == NULL) { + ERROR("match_create_simple(): latency_counter_create() failed."); + free(user_data); + return (NULL); + } } - obj->flags |= UTILS_MATCH_FLAGS_FREE_USER_DATA; + obj = match_create_callback(regex, excluderegex, default_callback, user_data, + match_simple_free); + if (obj == NULL) { + if (user_data->latency) + latency_counter_destroy(user_data->latency); + sfree(user_data); + return (NULL); + } return (obj); } /* cu_match_t *match_create_simple */ -void match_value_reset (cu_match_value_t *mv) -{ +void match_value_reset(cu_match_value_t *mv) { if (mv == NULL) return; - if (mv->ds_type & UTILS_MATCH_DS_TYPE_GAUGE) - { + /* Reset GAUGE metrics only and except GAUGE_PERSIST. */ + if ((mv->ds_type & UTILS_MATCH_DS_TYPE_GAUGE) && + !(mv->ds_type & UTILS_MATCH_CF_GAUGE_PERSIST)) { mv->value.gauge = NAN; mv->values_num = 0; } } /* }}} void match_value_reset */ -void match_destroy (cu_match_t *obj) -{ +void match_destroy(cu_match_t *obj) { if (obj == NULL) return; - if (obj->flags & UTILS_MATCH_FLAGS_FREE_USER_DATA) - { - sfree (obj->user_data); - } + if ((obj->user_data != NULL) && (obj->free != NULL)) + (*obj->free)(obj->user_data); - sfree (obj); + sfree(obj); } /* void match_destroy */ -int match_apply (cu_match_t *obj, const char *str) -{ +int match_apply(cu_match_t *obj, const char *str) { int status; regmatch_t re_match[32]; - char *matches[32] = { 0 }; + char *matches[32] = {0}; size_t matches_num; if ((obj == NULL) || (str == NULL)) return (-1); if (obj->flags & UTILS_MATCH_FLAGS_EXCLUDE_REGEX) { - status = regexec (&obj->excluderegex, str, - STATIC_ARRAY_SIZE (re_match), re_match, - /* eflags = */ 0); + status = + regexec(&obj->excluderegex, str, STATIC_ARRAY_SIZE(re_match), re_match, + /* eflags = */ 0); /* Regex did match, so exclude this line */ if (status == 0) { DEBUG("ExludeRegex matched, don't count that line\n"); @@ -339,52 +327,43 @@ int match_apply (cu_match_t *obj, const char *str) } } - status = regexec (&obj->regex, str, - STATIC_ARRAY_SIZE (re_match), re_match, - /* eflags = */ 0); + status = regexec(&obj->regex, str, STATIC_ARRAY_SIZE(re_match), re_match, + /* eflags = */ 0); /* Regex did not match */ if (status != 0) return (0); - for (matches_num = 0; matches_num < STATIC_ARRAY_SIZE (matches); matches_num++) - { - if ((re_match[matches_num].rm_so < 0) - || (re_match[matches_num].rm_eo < 0)) + for (matches_num = 0; matches_num < STATIC_ARRAY_SIZE(matches); + matches_num++) { + if ((re_match[matches_num].rm_so < 0) || (re_match[matches_num].rm_eo < 0)) break; - matches[matches_num] = match_substr (str, - re_match[matches_num].rm_so, re_match[matches_num].rm_eo); - if (matches[matches_num] == NULL) - { + matches[matches_num] = match_substr(str, re_match[matches_num].rm_so, + re_match[matches_num].rm_eo); + if (matches[matches_num] == NULL) { status = -1; break; } } - if (status != 0) - { - ERROR ("utils_match: match_apply: match_substr failed."); - } - else - { - status = obj->callback (str, matches, matches_num, obj->user_data); - if (status != 0) - { - ERROR ("utils_match: match_apply: callback failed."); + if (status != 0) { + ERROR("utils_match: match_apply: match_substr failed."); + } else { + status = obj->callback(str, matches, matches_num, obj->user_data); + if (status != 0) { + ERROR("utils_match: match_apply: callback failed."); } } - for (size_t i = 0; i < matches_num; i++) - { - sfree (matches[i]); + for (size_t i = 0; i < matches_num; i++) { + sfree(matches[i]); } return (status); } /* int match_apply */ -void *match_get_user_data (cu_match_t *obj) -{ +void *match_get_user_data(cu_match_t *obj) { if (obj == NULL) return (NULL); return (obj->user_data);