]> git.ipfire.org Git - thirdparty/collectd.git/commitdiff
value_list: Migrate functions related to `value_list_t` out of `common`.
authorFlorian Forster <octo@collectd.org>
Mon, 18 Dec 2023 08:30:25 +0000 (09:30 +0100)
committerFlorian Forster <octo@collectd.org>
Mon, 18 Dec 2023 22:29:47 +0000 (23:29 +0100)
src/utils/common/common.c
src/utils/common/common.h
src/utils/value_list/value_list.c
src/utils/value_list/value_list.h

index 7caa1f51ff1735981d868c4f83c72a1dbcdf9496..46c4d1179f1300fa7f7a42a42a0a956877fcace1 100644 (file)
@@ -948,248 +948,6 @@ int format_values(strbuf_t *buf, metric_t const *m, bool store_rates) {
   return 0;
 } /* }}} int format_values */
 
-int parse_identifier(char *str, char **ret_host, char **ret_plugin,
-                     char **ret_type, char **ret_data_source,
-                     char *default_host) {
-  char *fields[5];
-  size_t fields_num = 0;
-
-  do {
-    fields[fields_num] = str;
-    fields_num++;
-
-    char *ptr = strchr(str, '/');
-    if (ptr == NULL) {
-      break;
-    }
-
-    *ptr = 0;
-    str = ptr + 1;
-  } while (fields_num < STATIC_ARRAY_SIZE(fields));
-
-  switch (fields_num) {
-  case 4:
-    *ret_data_source = fields[3];
-    /* fall-through */
-  case 3:
-    *ret_type = fields[2];
-    *ret_plugin = fields[1];
-    *ret_host = fields[0];
-    break;
-  case 2:
-    if ((default_host == NULL) || (strlen(default_host) == 0)) {
-      return EINVAL;
-    }
-    *ret_type = fields[1];
-    *ret_plugin = fields[0];
-    *ret_host = default_host;
-    break;
-  default:
-    return EINVAL;
-  }
-
-  return 0;
-} /* int parse_identifier */
-
-int parse_identifier_vl(const char *str, value_list_t *vl,
-                        char **ret_data_source) {
-  if ((str == NULL) || (vl == NULL))
-    return EINVAL;
-
-  char str_copy[6 * DATA_MAX_NAME_LEN];
-  sstrncpy(str_copy, str, sizeof(str_copy));
-
-  char *default_host = NULL;
-  if (strlen(vl->host) != 0) {
-    default_host = vl->host;
-  }
-
-  char *host = NULL;
-  char *plugin = NULL;
-  char *type = NULL;
-  char *data_source = NULL;
-  int status = parse_identifier(str_copy, &host, &plugin, &type, &data_source,
-                                default_host);
-  if (status != 0) {
-    return status;
-  }
-
-  if (data_source != NULL) {
-    if (ret_data_source == NULL) {
-      return EINVAL;
-    }
-    *ret_data_source = strdup(data_source);
-  }
-
-  char *plugin_instance = strchr(plugin, '-');
-  if (plugin_instance != NULL) {
-    *plugin_instance = 0;
-    plugin_instance++;
-  }
-  char *type_instance = strchr(type, '-');
-  if (type_instance != NULL) {
-    *type_instance = 0;
-    type_instance++;
-  }
-
-  if (host != vl->host) {
-    sstrncpy(vl->host, host, sizeof(vl->host));
-  }
-  sstrncpy(vl->plugin, plugin, sizeof(vl->plugin));
-  if (plugin_instance != NULL) {
-    sstrncpy(vl->plugin_instance, plugin_instance, sizeof(vl->plugin_instance));
-  }
-  sstrncpy(vl->type, type, sizeof(vl->type));
-  if (type_instance != NULL) {
-    sstrncpy(vl->type_instance, type_instance, sizeof(vl->type_instance));
-  }
-
-  return 0;
-} /* }}} int parse_identifier_vl */
-
-metric_t *parse_legacy_identifier(char const *s) {
-  value_list_t vl = VALUE_LIST_INIT;
-
-  char *data_source = NULL;
-  int status = parse_identifier_vl(s, &vl, &data_source);
-  if (status != 0) {
-    errno = status;
-    return NULL;
-  }
-
-  data_set_t const *ds = plugin_get_ds(vl.type);
-  if (ds == NULL) {
-    errno = ENOENT;
-    return NULL;
-  }
-
-  if ((ds->ds_num != 1) && (data_source == NULL)) {
-    DEBUG("parse_legacy_identifier: data set \"%s\" has multiple data sources, "
-          "but \"%s\" does not specify a data source",
-          ds->type, s);
-    errno = EINVAL;
-    return NULL;
-  }
-
-  value_t values[ds->ds_num];
-  memset(values, 0, sizeof(values));
-  vl.values = values;
-  vl.values_len = ds->ds_num;
-
-  size_t ds_index = 0;
-  if (data_source != NULL) {
-    bool found = 0;
-    for (size_t i = 0; i < ds->ds_num; i++) {
-      if (strcasecmp(data_source, ds->ds[i].name) == 0) {
-        ds_index = i;
-        found = true;
-      }
-    }
-
-    if (!found) {
-      DEBUG("parse_legacy_identifier: data set \"%s\" does not have a \"%s\" "
-            "data source",
-            ds->type, data_source);
-      free(data_source);
-      errno = EINVAL;
-      return NULL;
-    }
-  }
-  free(data_source);
-  data_source = NULL;
-
-  metric_family_t *fam = plugin_value_list_to_metric_family(&vl, ds, ds_index);
-  if (fam == NULL) {
-    return NULL;
-  }
-
-  return fam->metric.ptr;
-}
-
-static int metric_family_name(strbuf_t *buf, value_list_t const *vl,
-                              data_source_t const *dsrc) {
-  int status = strbuf_print(buf, "collectd");
-
-  if (strcmp(vl->plugin, vl->type) != 0) {
-    status = status || strbuf_print(buf, "_");
-    status = status || strbuf_print(buf, vl->plugin);
-  }
-
-  status = status || strbuf_print(buf, "_");
-  status = status || strbuf_print(buf, vl->type);
-
-  if (strcmp("value", dsrc->name) != 0) {
-    status = status || strbuf_print(buf, "_");
-    status = status || strbuf_print(buf, dsrc->name);
-  }
-
-  if ((dsrc->type == DS_TYPE_COUNTER) || (dsrc->type == DS_TYPE_DERIVE)) {
-    status = status || strbuf_print(buf, "_total");
-  }
-
-  return status;
-}
-
-metric_family_t *plugin_value_list_to_metric_family(value_list_t const *vl,
-                                                    data_set_t const *ds,
-                                                    size_t index) {
-  if ((vl == NULL) || (ds == NULL)) {
-    errno = EINVAL;
-    return NULL;
-  }
-
-  metric_family_t *fam = calloc(1, sizeof(*fam));
-  if (fam == NULL) {
-    return NULL;
-  }
-
-  data_source_t const *dsrc = ds->ds + index;
-  strbuf_t name = STRBUF_CREATE;
-  int status = metric_family_name(&name, vl, dsrc);
-  if (status != 0) {
-    STRBUF_DESTROY(name);
-    metric_family_free(fam);
-    errno = status;
-    return NULL;
-  }
-  fam->name = name.ptr;
-  name = (strbuf_t){0};
-
-  fam->type =
-      (dsrc->type == DS_TYPE_GAUGE) ? METRIC_TYPE_GAUGE : METRIC_TYPE_COUNTER;
-
-  metric_t m = {
-      .family = fam,
-      .value = vl->values[index],
-      .time = vl->time,
-      .interval = vl->interval,
-  };
-
-  status = metric_label_set(&m, "instance",
-                            (strlen(vl->host) != 0) ? vl->host : hostname_g);
-  if (strlen(vl->plugin_instance) != 0) {
-    status = status || metric_label_set(&m, vl->plugin, vl->plugin_instance);
-  }
-  if (strlen(vl->type_instance) != 0) {
-    char const *name = "type";
-    if (strlen(vl->plugin_instance) == 0) {
-      name = vl->plugin;
-    }
-    status = status || metric_label_set(&m, name, vl->type_instance);
-  }
-
-  status = status || metric_family_metric_append(fam, m);
-  if (status != 0) {
-    metric_reset(&m);
-    metric_family_free(fam);
-    errno = status;
-    return NULL;
-  }
-
-  metric_reset(&m);
-  return fam;
-}
-
 int parse_value(const char *value_orig, value_t *ret_value, int ds_type) {
   char *value;
   char *endptr = NULL;
index cc702272d5d4240e43b09971dc3d56036ba6154c..6b9f8d79ddfbb7c9908a2a5b3a284d4a1ed5b79e 100644 (file)
@@ -330,34 +330,6 @@ int format_name(char *ret, int ret_len, const char *hostname,
               (vl)->type, (vl)->type_instance)
 int format_values(strbuf_t *buf, metric_t const *m, bool store_rates);
 
-int parse_identifier(char *str, char **ret_host, char **ret_plugin,
-                     char **ret_type, char **ret_data_source,
-                     char *default_host);
-
-/* parse_identifier_vl parses an identifier in the form
- * "host/plugin[-inst]/type[-inst]/data_source" and stores the fields in a
- * value_list_t. If vl->host is not empty, then it is used as the default value
- * if a host name is omitted, i.e. the "plugin/type" format is accepted. If
- * ret_data_source is not NULL, a four-part identifier is accepted and a
- * pointer to the data source name is (optionally) stored and needs to be freed
- * by the caller. If the provided format does not fit the provided arguments,
- * e.g. a two-part format but no default host provided, or a four-part format
- * but no ret_data_source pointer, then EINVAL is returned.
- */
-int parse_identifier_vl(const char *str, value_list_t *vl,
-                        char **ret_data_source);
-
-/* parse_legacy_identifier parses a legacy identifier in the form
- * "host/plugin/type" and converts it to a metric_t. */
-metric_t *parse_legacy_identifier(char const *s);
-
-/* plugin_value_list_to_metric_family converts a value in a value_list_t to a
- * metric_family_t. In case of error, errno is set and NULL is returned. The
- * returned pointer must be freed using metric_family_free(). */
-metric_family_t *plugin_value_list_to_metric_family(value_list_t const *vl,
-                                                    data_set_t const *ds,
-                                                    size_t index);
-
 int parse_value(const char *value, value_t *ret_value, int ds_type);
 int parse_values(char *buffer, value_list_t *vl, const data_set_t *ds);
 
index 6ba378fa6a91136c74ce2e4846e5776a94bcb146..ac49f81c7acdf1d6ffcf1b7a6f3d81cf5aff8fb7 100644 (file)
@@ -28,8 +28,8 @@
 
 #include "collectd.h"
 #include "daemon/plugin.h"
-#include "utils/value_list/value_list.h"
 #include "utils/common/common.h"
+#include "utils/value_list/value_list.h"
 
 #ifdef WIN32
 #define EXPORT __declspec(dllexport)
@@ -187,3 +187,244 @@ plugin_dispatch_multivalue(value_list_t const *template, /* {{{ */
   return failed;
 } /* }}} int plugin_dispatch_multivalue */
 
+static int metric_family_name(strbuf_t *buf, value_list_t const *vl,
+                              data_source_t const *dsrc) {
+  int status = strbuf_print(buf, "collectd");
+
+  if (strcmp(vl->plugin, vl->type) != 0) {
+    status = status || strbuf_print(buf, "_");
+    status = status || strbuf_print(buf, vl->plugin);
+  }
+
+  status = status || strbuf_print(buf, "_");
+  status = status || strbuf_print(buf, vl->type);
+
+  if (strcmp("value", dsrc->name) != 0) {
+    status = status || strbuf_print(buf, "_");
+    status = status || strbuf_print(buf, dsrc->name);
+  }
+
+  if ((dsrc->type == DS_TYPE_COUNTER) || (dsrc->type == DS_TYPE_DERIVE)) {
+    status = status || strbuf_print(buf, "_total");
+  }
+
+  return status;
+}
+
+int parse_identifier(char *str, char **ret_host, char **ret_plugin,
+                     char **ret_type, char **ret_data_source,
+                     char *default_host) {
+  char *fields[5];
+  size_t fields_num = 0;
+
+  do {
+    fields[fields_num] = str;
+    fields_num++;
+
+    char *ptr = strchr(str, '/');
+    if (ptr == NULL) {
+      break;
+    }
+
+    *ptr = 0;
+    str = ptr + 1;
+  } while (fields_num < STATIC_ARRAY_SIZE(fields));
+
+  switch (fields_num) {
+  case 4:
+    *ret_data_source = fields[3];
+    /* fall-through */
+  case 3:
+    *ret_type = fields[2];
+    *ret_plugin = fields[1];
+    *ret_host = fields[0];
+    break;
+  case 2:
+    if ((default_host == NULL) || (strlen(default_host) == 0)) {
+      return EINVAL;
+    }
+    *ret_type = fields[1];
+    *ret_plugin = fields[0];
+    *ret_host = default_host;
+    break;
+  default:
+    return EINVAL;
+  }
+
+  return 0;
+} /* int parse_identifier */
+
+int parse_identifier_vl(const char *str, value_list_t *vl,
+                        char **ret_data_source) {
+  if ((str == NULL) || (vl == NULL))
+    return EINVAL;
+
+  char str_copy[6 * DATA_MAX_NAME_LEN];
+  sstrncpy(str_copy, str, sizeof(str_copy));
+
+  char *default_host = NULL;
+  if (strlen(vl->host) != 0) {
+    default_host = vl->host;
+  }
+
+  char *host = NULL;
+  char *plugin = NULL;
+  char *type = NULL;
+  char *data_source = NULL;
+  int status = parse_identifier(str_copy, &host, &plugin, &type, &data_source,
+                                default_host);
+  if (status != 0) {
+    return status;
+  }
+
+  if (data_source != NULL) {
+    if (ret_data_source == NULL) {
+      return EINVAL;
+    }
+    *ret_data_source = strdup(data_source);
+  }
+
+  char *plugin_instance = strchr(plugin, '-');
+  if (plugin_instance != NULL) {
+    *plugin_instance = 0;
+    plugin_instance++;
+  }
+  char *type_instance = strchr(type, '-');
+  if (type_instance != NULL) {
+    *type_instance = 0;
+    type_instance++;
+  }
+
+  if (host != vl->host) {
+    sstrncpy(vl->host, host, sizeof(vl->host));
+  }
+  sstrncpy(vl->plugin, plugin, sizeof(vl->plugin));
+  if (plugin_instance != NULL) {
+    sstrncpy(vl->plugin_instance, plugin_instance, sizeof(vl->plugin_instance));
+  }
+  sstrncpy(vl->type, type, sizeof(vl->type));
+  if (type_instance != NULL) {
+    sstrncpy(vl->type_instance, type_instance, sizeof(vl->type_instance));
+  }
+
+  return 0;
+} /* }}} int parse_identifier_vl */
+
+metric_t *parse_legacy_identifier(char const *s) {
+  value_list_t vl = VALUE_LIST_INIT;
+
+  char *data_source = NULL;
+  int status = parse_identifier_vl(s, &vl, &data_source);
+  if (status != 0) {
+    errno = status;
+    return NULL;
+  }
+
+  data_set_t const *ds = plugin_get_ds(vl.type);
+  if (ds == NULL) {
+    errno = ENOENT;
+    return NULL;
+  }
+
+  if ((ds->ds_num != 1) && (data_source == NULL)) {
+    DEBUG("parse_legacy_identifier: data set \"%s\" has multiple data sources, "
+          "but \"%s\" does not specify a data source",
+          ds->type, s);
+    errno = EINVAL;
+    return NULL;
+  }
+
+  value_t values[ds->ds_num];
+  memset(values, 0, sizeof(values));
+  vl.values = values;
+  vl.values_len = ds->ds_num;
+
+  size_t ds_index = 0;
+  if (data_source != NULL) {
+    bool found = 0;
+    for (size_t i = 0; i < ds->ds_num; i++) {
+      if (strcasecmp(data_source, ds->ds[i].name) == 0) {
+        ds_index = i;
+        found = true;
+      }
+    }
+
+    if (!found) {
+      DEBUG("parse_legacy_identifier: data set \"%s\" does not have a \"%s\" "
+            "data source",
+            ds->type, data_source);
+      free(data_source);
+      errno = EINVAL;
+      return NULL;
+    }
+  }
+  free(data_source);
+  data_source = NULL;
+
+  metric_family_t *fam = plugin_value_list_to_metric_family(&vl, ds, ds_index);
+  if (fam == NULL) {
+    return NULL;
+  }
+
+  return fam->metric.ptr;
+}
+
+EXPORT metric_family_t *
+plugin_value_list_to_metric_family(value_list_t const *vl, data_set_t const *ds,
+                                   size_t index) {
+  if ((vl == NULL) || (ds == NULL)) {
+    errno = EINVAL;
+    return NULL;
+  }
+
+  metric_family_t *fam = calloc(1, sizeof(*fam));
+  if (fam == NULL) {
+    return NULL;
+  }
+
+  data_source_t const *dsrc = ds->ds + index;
+  strbuf_t name = STRBUF_CREATE;
+  int status = metric_family_name(&name, vl, dsrc);
+  if (status != 0) {
+    STRBUF_DESTROY(name);
+    metric_family_free(fam);
+    errno = status;
+    return NULL;
+  }
+  fam->name = name.ptr;
+  name = (strbuf_t){0};
+
+  fam->type =
+      (dsrc->type == DS_TYPE_GAUGE) ? METRIC_TYPE_GAUGE : METRIC_TYPE_COUNTER;
+
+  metric_t m = {
+      .family = fam,
+      .value = vl->values[index],
+      .time = vl->time,
+      .interval = vl->interval,
+  };
+
+  status = metric_label_set(&m, "instance",
+                            (strlen(vl->host) != 0) ? vl->host : hostname_g);
+  if (strlen(vl->plugin_instance) != 0) {
+    status = status || metric_label_set(&m, vl->plugin, vl->plugin_instance);
+  }
+  if (strlen(vl->type_instance) != 0) {
+    char const *name = "type";
+    if (strlen(vl->plugin_instance) == 0) {
+      name = vl->plugin;
+    }
+    status = status || metric_label_set(&m, name, vl->type_instance);
+  }
+
+  status = status || metric_family_metric_append(fam, m);
+  if (status != 0) {
+    metric_reset(&m);
+    metric_family_free(fam);
+    errno = status;
+    return NULL;
+  }
+
+  metric_reset(&m);
+  return fam;
+}
index e15a4fd39e2b3dd8f6a8966dcb867bbcc4612735..13d69dc7734b97af37b71db913592d55a23e94ec 100644 (file)
@@ -29,6 +29,9 @@
 #ifndef UTILS_VALUE_LIST_H
 #define UTILS_VALUE_LIST_H 1
 
+#include "daemon/data_set.h"
+#include "daemon/plugin.h"
+
 struct value_list_s {
   value_t *values;
   size_t values_len;
@@ -97,4 +100,32 @@ __attribute__((sentinel)) int plugin_dispatch_multivalue(value_list_t const *vl,
                                                          bool store_percentage,
                                                          int store_type, ...);
 
+int parse_identifier(char *str, char **ret_host, char **ret_plugin,
+                     char **ret_type, char **ret_data_source,
+                     char *default_host);
+
+/* parse_identifier_vl parses an identifier in the form
+ * "host/plugin[-inst]/type[-inst]/data_source" and stores the fields in a
+ * value_list_t. If vl->host is not empty, then it is used as the default value
+ * if a host name is omitted, i.e. the "plugin/type" format is accepted. If
+ * ret_data_source is not NULL, a four-part identifier is accepted and a
+ * pointer to the data source name is (optionally) stored and needs to be freed
+ * by the caller. If the provided format does not fit the provided arguments,
+ * e.g. a two-part format but no default host provided, or a four-part format
+ * but no ret_data_source pointer, then EINVAL is returned.
+ */
+int parse_identifier_vl(const char *str, value_list_t *vl,
+                        char **ret_data_source);
+
+/* parse_legacy_identifier parses a legacy identifier in the form
+ * "host/plugin/type" and converts it to a metric_t. */
+metric_t *parse_legacy_identifier(char const *s);
+
+/* plugin_value_list_to_metric_family converts a value in a value_list_t to a
+ * metric_family_t. In case of error, errno is set and NULL is returned. The
+ * returned pointer must be freed using metric_family_free(). */
+metric_family_t *plugin_value_list_to_metric_family(value_list_t const *vl,
+                                                    data_set_t const *ds,
+                                                    size_t index);
+
 #endif