summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 9a8d9ab)
raw | patch | inline | side by side (parent: 9a8d9ab)
author | Yves Mettier <ymettier@free.fr> | |
Wed, 1 Jul 2015 15:10:30 +0000 (16:10 +0100) | ||
committer | Yves Mettier <ymettier@free.fr> | |
Wed, 1 Jul 2015 15:10:30 +0000 (16:10 +0100) |
src/collectd.conf.pod | patch | blob | history | |
src/daemon/meta_data.c | patch | blob | history | |
src/daemon/meta_data.h | patch | blob | history | |
src/target_set.c | patch | blob | history |
diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod
index b2aab2139e1ce45633e2004609955c7e5b5a13f6..352115da5b06b4c2152f5a81cd2b0a3d450e2b4a 100644 (file)
--- a/src/collectd.conf.pod
+++ b/src/collectd.conf.pod
=item B<TypeInstance> I<String>
+=item B<MetaDataSet> I<String> I<String>
+
Set the appropriate field to the given string. The strings for plugin instance
and type instance may be empty, the strings for host and plugin may not be
empty. It's currently not possible to set the type of a value this way.
diff --git a/src/daemon/meta_data.c b/src/daemon/meta_data.c
index 6ee8446b37639dc38e479db4f6dcd48807cde725..8ddd47801ed7c9d6f9d80712ccf69443c0b49a21 100644 (file)
--- a/src/daemon/meta_data.c
+++ b/src/daemon/meta_data.c
return (e);
} /* }}} meta_entry_t *md_entry_alloc */
-static meta_entry_t *md_entry_clone (const meta_entry_t *orig) /* {{{ */
+/* XXX: The lock on md must be held while calling this function! */
+static meta_entry_t *md_entry_clone_contents (const meta_entry_t *orig) /* {{{ */
{
meta_entry_t *copy;
- if (orig == NULL)
- return (NULL);
+ /* WARNINGS :
+ * - we do not check that orig != NULL here. You should have done it before.
+ * - we do not set copy->next. DO NOT FORGET TO SET copy->next IN YOUR FUNCTION
+ */
copy = md_entry_alloc (orig->key);
copy->type = orig->type;
else
copy->value = orig->value;
+ return (copy);
+} /* }}} meta_entry_t *md_entry_clone_contents */
+
+static meta_entry_t *md_entry_clone (const meta_entry_t *orig) /* {{{ */
+{
+ meta_entry_t *copy;
+
+ if (orig == NULL)
+ return (NULL);
+
+ copy = md_entry_clone_contents(orig);
+
copy->next = md_entry_clone (orig->next);
return (copy);
} /* }}} meta_entry_t *md_entry_clone */
return (0);
} /* }}} int md_entry_insert */
+/* XXX: The lock on md must be held while calling this function! */
+static int md_entry_insert_clone (meta_data_t *md, meta_entry_t *orig) /* {{{ */
+{
+ meta_entry_t *e;
+ meta_entry_t *this;
+ meta_entry_t *prev;
+
+ /* WARNINGS :
+ * - we do not check that md and e != NULL here. You should have done it before.
+ * - we do not use the lock. You should have set it before.
+ */
+
+ e = md_entry_clone_contents(orig);
+
+ prev = NULL;
+ this = md->head;
+ while (this != NULL)
+ {
+ if (strcasecmp (e->key, this->key) == 0)
+ break;
+
+ prev = this;
+ this = this->next;
+ }
+
+ if (this == NULL)
+ {
+ /* This key does not exist yet. */
+ if (md->head == NULL)
+ md->head = e;
+ else
+ {
+ assert (prev != NULL);
+ prev->next = e;
+ }
+
+ e->next = NULL;
+ }
+ else /* (this != NULL) */
+ {
+ if (prev == NULL)
+ md->head = e;
+ else
+ prev->next = e;
+
+ e->next = this->next;
+ }
+
+ if (this != NULL)
+ {
+ this->next = NULL;
+ md_entry_free (this);
+ }
+
+ return (0);
+} /* }}} int md_entry_insert_clone */
+
/* XXX: The lock on md must be held while calling this function! */
static meta_entry_t *md_entry_lookup (meta_data_t *md, /* {{{ */
const char *key)
return (copy);
} /* }}} meta_data_t *meta_data_clone */
+int meta_data_clone_merge (meta_data_t **dest, meta_data_t *orig) /* {{{ */
+{
+ meta_entry_t *e;
+
+ if (orig == NULL)
+ return (0);
+
+ if(NULL == *dest) {
+ *dest = meta_data_clone(orig);
+ return(0);
+ }
+
+ pthread_mutex_lock (&orig->lock);
+ for(e=orig->head; NULL != e; e = e->next) {
+ md_entry_insert_clone((*dest), e);
+ }
+ pthread_mutex_unlock (&orig->lock);
+
+ return (0);
+} /* }}} int meta_data_clone_merge */
+
void meta_data_destroy (meta_data_t *md) /* {{{ */
{
if (md == NULL)
diff --git a/src/daemon/meta_data.h b/src/daemon/meta_data.h
index fa48df326ebf90dc45ef4d237dcd7e889eefa124..9e448e55db1085ae24dbb330f1618171344bef2a 100644 (file)
--- a/src/daemon/meta_data.h
+++ b/src/daemon/meta_data.h
meta_data_t *meta_data_create (void);
meta_data_t *meta_data_clone (meta_data_t *orig);
+int meta_data_clone_merge (meta_data_t **dest, meta_data_t *orig);
void meta_data_destroy (meta_data_t *md);
int meta_data_exists (meta_data_t *md, const char *key);
diff --git a/src/target_set.c b/src/target_set.c
index daeaf8be62f7c2d9779b66f2643dd0e447ac6bd5..5e9d0877c6c1f9a77f4e6eecaba70b5af132fd62 100644 (file)
--- a/src/target_set.c
+++ b/src/target_set.c
char *plugin_instance;
/* char *type; */
char *type_instance;
+ meta_data_t *meta;
};
typedef struct ts_data_s ts_data_t;
+int ts_util_get_key_and_string_wo_strdup (const oconfig_item_t *ci, char **ret_key, char **ret_string) /* {{{ */
+{
+ if ((ci->values_num != 2)
+ || (ci->values[0].type != OCONFIG_TYPE_STRING)
+ || (ci->values[1].type != OCONFIG_TYPE_STRING))
+ {
+ ERROR ("ts_util_get_key_and_string_wo_strdup: The %s option requires "
+ "exactly two string argument.", ci->key);
+ return (-1);
+ }
+
+ *ret_key = ci->values[0].value.string;
+ *ret_string = ci->values[1].value.string;
+
+ return (0);
+} /* }}} int ts_util_get_key_and_string_wo_strdup */
+
static int ts_config_add_string (char **dest, /* {{{ */
const oconfig_item_t *ci, int may_be_empty)
{
return (0);
} /* }}} int ts_config_add_string */
+static int ts_config_add_meta (meta_data_t **dest, /* {{{ */
+ const oconfig_item_t *ci, int may_be_empty)
+{
+ char *key = NULL;
+ char *string = NULL;
+ int status;
+
+ status = ts_util_get_key_and_string_wo_strdup (ci, &key, &string);
+ if (status != 0)
+ return (status);
+
+ if (strlen (key) == 0)
+ {
+ ERROR ("Target `set': The `%s' option does not accept empty string as first argument.",
+ ci->key);
+ return (-1);
+ }
+
+ if (!may_be_empty && (strlen (string) == 0))
+ {
+ ERROR ("Target `set': The `%s' option does not accept empty string as second argument.",
+ ci->key);
+ return (-1);
+ }
+
+ if(NULL == (*dest)) {
+ // Create a new meta_data_t
+ if( NULL == (*dest = meta_data_create())) {
+ ERROR ("Target `set': failed to create a meta data for `%s'.", ci->key);
+ return (-1);
+ }
+ }
+
+ return(meta_data_add_string (*dest, key, string));
+} /* }}} int ts_config_add_meta */
+
static int ts_destroy (void **user_data) /* {{{ */
{
ts_data_t *data;
free (data->plugin_instance);
/* free (data->type); */
free (data->type_instance);
+ meta_data_destroy(data->meta);
free (data);
return (0);
data->plugin_instance = NULL;
/* data->type = NULL; */
data->type_instance = NULL;
+ data->meta = NULL;
status = 0;
for (i = 0; i < ci->children_num; i++)
status = ts_config_add_string (&data->type, child,
/* may be empty = */ 0);
#endif
- else if (strcasecmp ("TypeInstance", child->key) == 0)
- status = ts_config_add_string (&data->type_instance, child,
+ else if (strcasecmp ("MetaDataSet", child->key) == 0)
+ status = ts_config_add_meta (&data->meta, child,
/* may be empty = */ 1);
else
{
&& (data->plugin == NULL)
&& (data->plugin_instance == NULL)
/* && (data->type == NULL) */
- && (data->type_instance == NULL))
+ && (data->type_instance == NULL)
+ && (data->meta == NULL))
{
ERROR ("Target `set': You need to set at least one of `Host', "
- "`Plugin', `PluginInstance' or `TypeInstance'.");
+ "`Plugin', `PluginInstance', `TypeInstance', "
+ "`MetaDataSet' or `MetaDataEval'.");
status = -1;
}
return (-EINVAL);
}
+ if(NULL != data->meta) {
+ meta_data_clone_merge(&(vl->meta), data->meta);
+ }
+
#define SET_FIELD(f) if (data->f != NULL) { sstrncpy (vl->f, data->f, sizeof (vl->f)); }
SET_FIELD (host);
SET_FIELD (plugin);