From: Florian Forster Date: Mon, 18 Dec 2023 07:59:10 +0000 (+0100) Subject: Move functions related to `value_list_t` to a separate package. X-Git-Tag: 6.0.0-rc0~33^2~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1659f75b5a4fa24ec998b7afb6ea179cf40ec211;p=thirdparty%2Fcollectd.git Move functions related to `value_list_t` to a separate package. --- diff --git a/Makefile.am b/Makefile.am index 29779a82b..d3fd99096 100644 --- a/Makefile.am +++ b/Makefile.am @@ -259,7 +259,9 @@ collectd_SOURCES = \ src/daemon/utils_threshold.c \ src/daemon/utils_threshold.h \ src/daemon/utils_time.c \ - src/daemon/utils_time.h + src/daemon/utils_time.h \ + src/utils/value_list/value_list.c \ + src/utils/value_list/value_list.h collectd_CFLAGS = $(AM_CFLAGS) collectd_CPPFLAGS = $(AM_CPPFLAGS) diff --git a/src/daemon/plugin.c b/src/daemon/plugin.c index 90905b950..a8773b5b2 100644 --- a/src/daemon/plugin.c +++ b/src/daemon/plugin.c @@ -673,56 +673,6 @@ static void stop_read_threads(void) { read_threads_num = 0; } /* void stop_read_threads */ -static void plugin_value_list_free(value_list_t *vl) /* {{{ */ -{ - if (vl == NULL) - return; - - meta_data_destroy(vl->meta); - sfree(vl->values); - sfree(vl); -} /* }}} void plugin_value_list_free */ - -static value_list_t * -plugin_value_list_clone(value_list_t const *vl_orig) /* {{{ */ -{ - value_list_t *vl; - - if (vl_orig == NULL) - return NULL; - - vl = malloc(sizeof(*vl)); - if (vl == NULL) - return NULL; - memcpy(vl, vl_orig, sizeof(*vl)); - - if (vl->host[0] == 0) - sstrncpy(vl->host, hostname_g, sizeof(vl->host)); - - vl->values = calloc(vl_orig->values_len, sizeof(*vl->values)); - if (vl->values == NULL) { - plugin_value_list_free(vl); - return NULL; - } - memcpy(vl->values, vl_orig->values, - vl_orig->values_len * sizeof(*vl->values)); - - vl->meta = meta_data_clone(vl->meta); - if ((vl_orig->meta != NULL) && (vl->meta == NULL)) { - plugin_value_list_free(vl); - return NULL; - } - - if (vl->time == 0) - vl->time = cdtime(); - - /* Fill in the interval from the thread context, if it is zero. */ - if (vl->interval == 0) - vl->interval = plugin_get_interval(); - - return vl; -} /* }}} value_list_t *plugin_value_list_clone */ - static void write_queue_ref_single(write_queue_elem_t *elem, long dir) { elem->ref_count += dir; @@ -2250,104 +2200,6 @@ EXPORT int plugin_dispatch_metric_family(metric_family_t const *fam) { return status; } -EXPORT int plugin_dispatch_values(value_list_t const *vl) { - data_set_t const *ds = plugin_get_ds(vl->type); - if (ds == NULL) { - return EINVAL; - } - - for (size_t i = 0; i < vl->values_len; i++) { - metric_family_t *fam = plugin_value_list_to_metric_family(vl, ds, i); - if (fam == NULL) { - int status = errno; - ERROR("plugin_dispatch_values: plugin_value_list_to_metric_family " - "failed: %s", - STRERROR(status)); - return status; - } - - int status = plugin_dispatch_metric_family(fam); - metric_family_free(fam); - if (status != 0) { - return status; - } - } - - return 0; -} - -__attribute__((sentinel)) int -plugin_dispatch_multivalue(value_list_t const *template, /* {{{ */ - bool store_percentage, int store_type, ...) { - value_list_t *vl; - int failed = 0; - gauge_t sum = 0.0; - va_list ap; - - assert(template->values_len == 1); - - /* Calculate sum for Gauge to calculate percent if needed */ - if (DS_TYPE_GAUGE == store_type) { - va_start(ap, store_type); - while (42) { - char const *name; - gauge_t value; - - name = va_arg(ap, char const *); - if (name == NULL) - break; - - value = va_arg(ap, gauge_t); - if (!isnan(value)) - sum += value; - } - va_end(ap); - } - - vl = plugin_value_list_clone(template); - /* plugin_value_list_clone makes sure vl->time is set to non-zero. */ - if (store_percentage) - sstrncpy(vl->type, "percent", sizeof(vl->type)); - - va_start(ap, store_type); - while (42) { - char const *name; - int status; - - /* Set the type instance. */ - name = va_arg(ap, char const *); - if (name == NULL) - break; - sstrncpy(vl->type_instance, name, sizeof(vl->type_instance)); - - /* Set the value. */ - switch (store_type) { - case DS_TYPE_GAUGE: - vl->values[0].gauge = va_arg(ap, gauge_t); - if (store_percentage) - vl->values[0].gauge *= sum ? (100.0 / sum) : NAN; - break; - case DS_TYPE_COUNTER: - vl->values[0].counter = va_arg(ap, counter_t); - break; - case DS_TYPE_DERIVE: - vl->values[0].derive = va_arg(ap, derive_t); - break; - default: - ERROR("plugin_dispatch_multivalue: given store_type is incorrect."); - failed++; - } - - status = plugin_dispatch_values(vl); - if (status != 0) - failed++; - } - va_end(ap); - - plugin_value_list_free(vl); - return failed; -} /* }}} int plugin_dispatch_multivalue */ - EXPORT int plugin_dispatch_notification(const notification_t *notif) { llentry_t *le; /* Possible TODO: Add flap detection here */ diff --git a/src/daemon/plugin.h b/src/daemon/plugin.h index 4eb701676..4f92cb9af 100644 --- a/src/daemon/plugin.h +++ b/src/daemon/plugin.h @@ -34,6 +34,7 @@ #include "configfile.h" #include "metric.h" #include "utils/metadata/meta_data.h" +#include "utils/value_list/value_list.h" /* for legacy plugins */ #include "utils_time.h" #include @@ -44,10 +45,10 @@ #define DS_TYPE_DERIVE VALUE_TYPE_DERIVE #define DS_TYPE_TO_STRING(t) \ - (t == DS_TYPE_COUNTER) \ - ? "counter" \ - : (t == DS_TYPE_GAUGE) ? "gauge" \ - : (t == DS_TYPE_DERIVE) ? "derive" : "unknown" + (t == DS_TYPE_COUNTER) ? "counter" \ + : (t == DS_TYPE_GAUGE) ? "gauge" \ + : (t == DS_TYPE_DERIVE) ? "derive" \ + : "unknown" #ifndef LOG_ERR #define LOG_ERR 3 @@ -85,23 +86,6 @@ struct identifier_s { }; typedef struct identifier_s identifier_t; -struct value_list_s { - value_t *values; - size_t values_len; - cdtime_t time; - cdtime_t interval; - char host[DATA_MAX_NAME_LEN]; - char plugin[DATA_MAX_NAME_LEN]; - char plugin_instance[DATA_MAX_NAME_LEN]; - char type[DATA_MAX_NAME_LEN]; - char type_instance[DATA_MAX_NAME_LEN]; - meta_data_t *meta; -}; -typedef struct value_list_s value_list_t; - -#define VALUE_LIST_INIT \ - { .values = NULL, .meta = NULL } - struct data_source_s { char name[DATA_MAX_NAME_LEN]; int type; @@ -325,21 +309,6 @@ int plugin_unregister_notification(const char *name); */ void plugin_log_available_writers(void); -/* - * NAME - * plugin_dispatch_values - * - * DESCRIPTION - * This function is called by reading processes with the values they've - * aquired. The function fetches the data-set definition (that has been - * registered using `plugin_register_data_set') and calls _all_ registered - * write-functions. - * - * ARGUMENTS - * `vl' Value list of the values that have been read by a `read' - * function. - */ -int plugin_dispatch_values(value_list_t const *vl); /* * NAME * plugin_dispatch_metric_list @@ -357,41 +326,6 @@ int plugin_dispatch_values(value_list_t const *vl); */ int plugin_dispatch_metric_family(metric_family_t const *fam); -/* - * NAME - * plugin_dispatch_multivalue - * - * SYNOPSIS - * plugin_dispatch_multivalue (vl, true, DS_TYPE_GAUGE, - * "free", 42.0, - * "used", 58.0, - * NULL); - * - * DESCRIPTION - * Takes a list of type instances and values and dispatches that in a batch, - * making sure that all values have the same time stamp. If "store_percentage" - * is set to true, the "type" is set to "percent" and a percentage is - * calculated and dispatched, rather than the absolute values. Values that are - * NaN are dispatched as NaN and will not influence the total. - * - * The variadic arguments is a list of type_instance / type pairs, that are - * interpreted as type "char const *" and type, encoded by their corresponding - * "store_type": - * - * - "gauge_t" when "DS_TYPE_GAUGE" - * - "derive_t" when "DS_TYPE_DERIVE" - * - "counter_t" when "DS_TYPE_COUNTER" - * - * The last argument must be - * a NULL pointer to signal end-of-list. - * - * RETURNS - * The number of values it failed to dispatch (zero on success). - */ -__attribute__((sentinel)) int plugin_dispatch_multivalue(value_list_t const *vl, - bool store_percentage, - int store_type, ...); - int plugin_dispatch_missing(metric_family_t const *fam); void plugin_dispatch_cache_event(enum cache_event_type_e event_type, unsigned long callbacks_mask, const char *name, diff --git a/src/utils/value_list/value_list.c b/src/utils/value_list/value_list.c new file mode 100644 index 000000000..6ba378fa6 --- /dev/null +++ b/src/utils/value_list/value_list.c @@ -0,0 +1,189 @@ +/** + * collectd - src/utils/value_list/value_list.c + * Copyright (C) 2005-2023 Florian octo Forster + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Florian octo Forster + * Sebastian Harl + * Manoj Srivastava + **/ + +#include "collectd.h" +#include "daemon/plugin.h" +#include "utils/value_list/value_list.h" +#include "utils/common/common.h" + +#ifdef WIN32 +#define EXPORT __declspec(dllexport) +#include +#include +#else +#define EXPORT +#endif + +EXPORT int plugin_dispatch_values(value_list_t const *vl) { + data_set_t const *ds = plugin_get_ds(vl->type); + if (ds == NULL) { + return EINVAL; + } + + for (size_t i = 0; i < vl->values_len; i++) { + metric_family_t *fam = plugin_value_list_to_metric_family(vl, ds, i); + if (fam == NULL) { + int status = errno; + ERROR("plugin_dispatch_values: plugin_value_list_to_metric_family " + "failed: %s", + STRERROR(status)); + return status; + } + + int status = plugin_dispatch_metric_family(fam); + metric_family_free(fam); + if (status != 0) { + return status; + } + } + + return 0; +} + +static void plugin_value_list_free(value_list_t *vl) /* {{{ */ +{ + if (vl == NULL) + return; + + meta_data_destroy(vl->meta); + sfree(vl->values); + sfree(vl); +} /* }}} void plugin_value_list_free */ + +static value_list_t * +plugin_value_list_clone(value_list_t const *vl_orig) /* {{{ */ +{ + value_list_t *vl; + + if (vl_orig == NULL) + return NULL; + + vl = malloc(sizeof(*vl)); + if (vl == NULL) + return NULL; + memcpy(vl, vl_orig, sizeof(*vl)); + + if (vl->host[0] == 0) + sstrncpy(vl->host, hostname_g, sizeof(vl->host)); + + vl->values = calloc(vl_orig->values_len, sizeof(*vl->values)); + if (vl->values == NULL) { + plugin_value_list_free(vl); + return NULL; + } + memcpy(vl->values, vl_orig->values, + vl_orig->values_len * sizeof(*vl->values)); + + vl->meta = meta_data_clone(vl->meta); + if ((vl_orig->meta != NULL) && (vl->meta == NULL)) { + plugin_value_list_free(vl); + return NULL; + } + + if (vl->time == 0) + vl->time = cdtime(); + + /* Fill in the interval from the thread context, if it is zero. */ + if (vl->interval == 0) + vl->interval = plugin_get_interval(); + + return vl; +} /* }}} value_list_t *plugin_value_list_clone */ + +__attribute__((sentinel)) int +plugin_dispatch_multivalue(value_list_t const *template, /* {{{ */ + bool store_percentage, int store_type, ...) { + value_list_t *vl; + int failed = 0; + gauge_t sum = 0.0; + va_list ap; + + assert(template->values_len == 1); + + /* Calculate sum for Gauge to calculate percent if needed */ + if (DS_TYPE_GAUGE == store_type) { + va_start(ap, store_type); + while (42) { + char const *name; + gauge_t value; + + name = va_arg(ap, char const *); + if (name == NULL) + break; + + value = va_arg(ap, gauge_t); + if (!isnan(value)) + sum += value; + } + va_end(ap); + } + + vl = plugin_value_list_clone(template); + /* plugin_value_list_clone makes sure vl->time is set to non-zero. */ + if (store_percentage) + sstrncpy(vl->type, "percent", sizeof(vl->type)); + + va_start(ap, store_type); + while (42) { + char const *name; + int status; + + /* Set the type instance. */ + name = va_arg(ap, char const *); + if (name == NULL) + break; + sstrncpy(vl->type_instance, name, sizeof(vl->type_instance)); + + /* Set the value. */ + switch (store_type) { + case DS_TYPE_GAUGE: + vl->values[0].gauge = va_arg(ap, gauge_t); + if (store_percentage) + vl->values[0].gauge *= sum ? (100.0 / sum) : NAN; + break; + case DS_TYPE_COUNTER: + vl->values[0].counter = va_arg(ap, counter_t); + break; + case DS_TYPE_DERIVE: + vl->values[0].derive = va_arg(ap, derive_t); + break; + default: + ERROR("plugin_dispatch_multivalue: given store_type is incorrect."); + failed++; + } + + status = plugin_dispatch_values(vl); + if (status != 0) + failed++; + } + va_end(ap); + + plugin_value_list_free(vl); + return failed; +} /* }}} int plugin_dispatch_multivalue */ + diff --git a/src/utils/value_list/value_list.h b/src/utils/value_list/value_list.h new file mode 100644 index 000000000..e15a4fd39 --- /dev/null +++ b/src/utils/value_list/value_list.h @@ -0,0 +1,100 @@ +/** + * collectd - src/utils/value_list/value_list.h + * Copyright (C) 2005-2023 Florian octo Forster + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Florian octo Forster + * Sebastian Harl + * Manoj Srivastava + **/ + +#ifndef UTILS_VALUE_LIST_H +#define UTILS_VALUE_LIST_H 1 + +struct value_list_s { + value_t *values; + size_t values_len; + cdtime_t time; + cdtime_t interval; + char host[DATA_MAX_NAME_LEN]; + char plugin[DATA_MAX_NAME_LEN]; + char plugin_instance[DATA_MAX_NAME_LEN]; + char type[DATA_MAX_NAME_LEN]; + char type_instance[DATA_MAX_NAME_LEN]; + meta_data_t *meta; +}; +typedef struct value_list_s value_list_t; + +#define VALUE_LIST_INIT \ + { .values = NULL, .meta = NULL } + +/* + * NAME + * plugin_dispatch_values + * + * DESCRIPTION + * This function is called by reading processes with the values they've + * aquired. The function fetches the data-set definition (that has been + * registered using `plugin_register_data_set') and calls _all_ registered + * write-functions. + * + * ARGUMENTS + * `vl' Value list of the values that have been read by a `read' + * function. + */ +int plugin_dispatch_values(value_list_t const *vl); + +/* + * NAME + * plugin_dispatch_multivalue + * + * SYNOPSIS + * plugin_dispatch_multivalue (vl, true, DS_TYPE_GAUGE, + * "free", 42.0, + * "used", 58.0, + * NULL); + * + * DESCRIPTION + * Takes a list of type instances and values and dispatches that in a batch, + * making sure that all values have the same time stamp. If "store_percentage" + * is set to true, the "type" is set to "percent" and a percentage is + * calculated and dispatched, rather than the absolute values. Values that are + * NaN are dispatched as NaN and will not influence the total. + * + * The variadic arguments is a list of type_instance / type pairs, that are + * interpreted as type "char const *" and type, encoded by their corresponding + * "store_type": + * + * - "gauge_t" when "DS_TYPE_GAUGE" + * - "derive_t" when "DS_TYPE_DERIVE" + * - "counter_t" when "DS_TYPE_COUNTER" + * + * The last argument must be + * a NULL pointer to signal end-of-list. + * + * RETURNS + * The number of values it failed to dispatch (zero on success). + */ +__attribute__((sentinel)) int plugin_dispatch_multivalue(value_list_t const *vl, + bool store_percentage, + int store_type, ...); + +#endif