/* XXX: This function will acquire `cache_lock' but will not free it! */ static meta_data_t *uc_get_meta (const value_list_t *vl) /* {{{ */ { char name[6 * DATA_MAX_NAME_LEN]; cache_entry_t *ce = NULL; int status; status = FORMAT_VL (name, sizeof (name), vl); if (status != 0) { ERROR ("utils_cache: uc_get_meta: FORMAT_VL failed."); return (NULL); } pthread_mutex_lock (&cache_lock); status = c_avl_get (cache_tree, name, (void *) &ce); if (status != 0) { pthread_mutex_unlock (&cache_lock); return (NULL); } assert (ce != NULL); if (ce->meta == NULL) ce->meta = meta_data_create (); if (ce->meta == NULL) pthread_mutex_unlock (&cache_lock); return (ce->meta); } /* }}} meta_data_t *uc_get_meta */
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 ((*dest) == NULL) { /* Create a new meta_data_t */ if ((*dest = meta_data_create()) == NULL) { ERROR("Target `set': failed to create a meta data for `%s'.", ci->key); return (-ENOMEM); } } return (meta_data_add_string(*dest, key, string)); } /* }}} int ts_config_add_meta */
static void init_value_list (value_list_t *vl) { sstrncpy (vl->plugin, PLUGIN_NAME, sizeof (vl->plugin)); sstrncpy (vl->host, hostname_g, sizeof (vl->host)); vl->meta = meta_data_create(); }
meta_data_t *meta_data_clone(meta_data_t *orig) /* {{{ */ { meta_data_t *copy; if (orig == NULL) return (NULL); copy = meta_data_create(); if (copy == NULL) return (NULL); pthread_mutex_lock(&orig->lock); copy->head = md_entry_clone(orig->head); pthread_mutex_unlock(&orig->lock); return (copy); } /* }}} meta_data_t *meta_data_clone */
static int agg_instance_read (agg_instance_t *inst, cdtime_t t) /* {{{ */ { value_list_t vl = VALUE_LIST_INIT; char pi_prefix[DATA_MAX_NAME_LEN]; /* Pre-set all the fields in the value list that will not change per * aggregation type (sum, average, ...). The struct will be re-used and must * therefore be dispatched using the "secure" function. */ vl.time = t; vl.interval = 0; vl.meta = meta_data_create (); if (vl.meta == NULL) { ERROR ("aggregation plugin: meta_data_create failed."); return (-1); } meta_data_add_boolean (vl.meta, "aggregation:created", 1); if (AGG_MATCHES_ALL (inst->ident.host)) sstrncpy (vl.host, "global", sizeof (vl.host)); else sstrncpy (vl.host, inst->ident.host, sizeof (vl.host)); sstrncpy (vl.plugin, "aggregation", sizeof (vl.plugin)); if (AGG_MATCHES_ALL (inst->ident.plugin)) { if (AGG_MATCHES_ALL (inst->ident.plugin_instance)) sstrncpy (pi_prefix, "", sizeof (pi_prefix)); else sstrncpy (pi_prefix, inst->ident.plugin_instance, sizeof (pi_prefix)); } else { if (AGG_MATCHES_ALL (inst->ident.plugin_instance)) sstrncpy (pi_prefix, inst->ident.plugin, sizeof (pi_prefix)); else ssnprintf (pi_prefix, sizeof (pi_prefix), "%s-%s", inst->ident.plugin, inst->ident.plugin_instance); } sstrncpy (vl.type, inst->ident.type, sizeof (vl.type)); if (!AGG_MATCHES_ALL (inst->ident.type_instance)) sstrncpy (vl.type_instance, inst->ident.type_instance, sizeof (vl.type_instance)); #define READ_FUNC(func, rate) do { \ if (inst->state_ ## func != NULL) { \ agg_instance_read_func (inst, #func, rate, \ inst->state_ ## func, &vl, pi_prefix, t); \ } \ } while (0) pthread_mutex_lock (&inst->lock); READ_FUNC (num, (gauge_t) inst->num); /* All other aggregations are only defined when there have been any values * at all. */ if (inst->num > 0) { READ_FUNC (sum, inst->sum); READ_FUNC (average, (inst->sum / ((gauge_t) inst->num))); READ_FUNC (min, inst->min); READ_FUNC (max, inst->max); READ_FUNC (stddev, sqrt((((gauge_t) inst->num) * inst->squares_sum) - (inst->sum * inst->sum)) / ((gauge_t) inst->num)); } /* Reset internal state. */ inst->num = 0; inst->sum = 0.0; inst->squares_sum = 0.0; inst->min = NAN; inst->max = NAN; pthread_mutex_unlock (&inst->lock); meta_data_destroy (vl.meta); vl.meta = NULL; return (0); } /* }}} int agg_instance_read */
/* * Result private functions */ static int udb_result_submit (udb_result_t *r, /* {{{ */ udb_result_preparation_area_t *r_area, udb_query_t const *q, udb_query_preparation_area_t *q_area) { value_list_t vl = VALUE_LIST_INIT; size_t i; int status; assert (r != NULL); assert (r_area->ds != NULL); assert (((size_t) r_area->ds->ds_num) == r->values_num); assert (r->values_num > 0); vl.values = calloc (r->values_num, sizeof (*vl.values)); if (vl.values == NULL) { ERROR ("db query utils: calloc failed."); return (-1); } vl.values_len = r_area->ds->ds_num; for (i = 0; i < r->values_num; i++) { char *value_str = r_area->values_buffer[i]; if (0 != parse_value (value_str, &vl.values[i], r_area->ds->ds[i].type)) { ERROR ("db query utils: udb_result_submit: Parsing `%s' as %s failed.", value_str, DS_TYPE_TO_STRING (r_area->ds->ds[i].type)); errno = EINVAL; free (vl.values); return (-1); } } if (q_area->interval > 0) vl.interval = q_area->interval; sstrncpy (vl.host, q_area->host, sizeof (vl.host)); sstrncpy (vl.plugin, q_area->plugin, sizeof (vl.plugin)); sstrncpy (vl.type, r->type, sizeof (vl.type)); /* Set vl.plugin_instance */ if (q->plugin_instance_from != NULL) { sstrncpy (vl.plugin_instance, r_area->plugin_instance, sizeof (vl.plugin_instance)); } else { sstrncpy (vl.plugin_instance, q_area->db_name, sizeof (vl.plugin_instance)); } /* Set vl.type_instance {{{ */ if (r->instances_num == 0) { if (r->instance_prefix == NULL) vl.type_instance[0] = 0; else sstrncpy (vl.type_instance, r->instance_prefix, sizeof (vl.type_instance)); } else /* if ((r->instances_num > 0) */ { if (r->instance_prefix == NULL) { strjoin (vl.type_instance, sizeof (vl.type_instance), r_area->instances_buffer, r->instances_num, "-"); } else { char tmp[DATA_MAX_NAME_LEN]; strjoin (tmp, sizeof (tmp), r_area->instances_buffer, r->instances_num, "-"); tmp[sizeof (tmp) - 1] = 0; snprintf (vl.type_instance, sizeof (vl.type_instance), "%s-%s", r->instance_prefix, tmp); } } vl.type_instance[sizeof (vl.type_instance) - 1] = 0; /* }}} */ /* Annotate meta data. {{{ */ if (r->metadata_num > 0) { vl.meta = meta_data_create (); if (vl.meta == NULL) { ERROR ("db query utils:: meta_data_create failed."); return (-ENOMEM); } for (i = 0; i < r->metadata_num; i++) { status = meta_data_add_string (vl.meta, r->metadata[i], r_area->metadata_buffer[i]); if (status != 0) { ERROR ("db query utils:: meta_data_add_string failed."); meta_data_destroy (vl.meta); vl.meta = NULL; return (status); } } } /* }}} */ plugin_dispatch_values (&vl); if (r->metadata_num > 0) { meta_data_destroy (vl.meta); vl.meta = NULL; } sfree (vl.values); return (0); } /* }}} void udb_result_submit */
static int tr_meta_data_action_invoke(/* {{{ */ tr_meta_data_action_t *act_head, meta_data_t **dest) { int status; regmatch_t matches[8] = {[0] = {0}}; if (act_head == NULL) return (-EINVAL); if ((*dest) == NULL) /* nothing to do */ return (0); for (tr_meta_data_action_t *act = act_head; act != NULL; act = act->next) { char temp[DATA_MAX_NAME_LEN]; char *subst_status; int value_type; int meta_data_status; char *value; meta_data_t *result; value_type = meta_data_type(*dest, act->key); if (value_type == 0) /* not found */ continue; if (value_type != MD_TYPE_STRING) { WARNING("Target `replace': Attempting replace on metadata key `%s', " "which isn't a string.", act->key); continue; } meta_data_status = meta_data_get_string(*dest, act->key, &value); if (meta_data_status != 0) { ERROR("Target `replace': Unable to retrieve metadata value for `%s'.", act->key); return (meta_data_status); } DEBUG("target_replace plugin: tr_meta_data_action_invoke: `%s' " "old value = `%s'", act->key, value); status = regexec(&act->re, value, STATIC_ARRAY_SIZE(matches), matches, /* flags = */ 0); if (status == REG_NOMATCH) { sfree(value); continue; } else if (status != 0) { char errbuf[1024] = ""; regerror(status, &act->re, errbuf, sizeof(errbuf)); ERROR("Target `replace': Executing a regular expression failed: %s.", errbuf); sfree(value); continue; } if (act->replacement == NULL) { /* no replacement; delete the key */ DEBUG("target_replace plugin: tr_meta_data_action_invoke: " "deleting `%s'", act->key); meta_data_delete(*dest, act->key); sfree(value); continue; } subst_status = subst(temp, sizeof(temp), value, (size_t)matches[0].rm_so, (size_t)matches[0].rm_eo, act->replacement); if (subst_status == NULL) { ERROR("Target `replace': subst (value = %s, start = %zu, end = %zu, " "replacement = %s) failed.", value, (size_t)matches[0].rm_so, (size_t)matches[0].rm_eo, act->replacement); sfree(value); continue; } DEBUG("target_replace plugin: tr_meta_data_action_invoke: `%s' " "value `%s' -> `%s'", act->key, value, temp); if ((result = meta_data_create()) == NULL) { ERROR("Target `replace': failed to create metadata for `%s'.", act->key); sfree(value); return (-ENOMEM); } meta_data_status = meta_data_add_string(result, act->key, temp); if (meta_data_status != 0) { ERROR("Target `replace': Unable to set metadata value for `%s'.", act->key); meta_data_destroy(result); sfree(value); return (meta_data_status); } meta_data_clone_merge(dest, result); meta_data_destroy(result); sfree(value); } /* for (act = act_head; act != NULL; act = act->next) */ return (0); } /* }}} int tr_meta_data_action_invoke */
static int network_dispatch_values (value_list_t *vl, /* {{{ */ const char *username) { int status; // DEBUG("host: %s", vl->host); // DEBUG("plugin: %s", vl->plugin); // DEBUG("plugin_instance: %s", vl->plugin_instance); // DEBUG("type: %s", vl->type); // DEBUG("type_instance: %s", vl->type_instance); if ((vl->time <= 0) || (strlen (vl->host) <= 0) || (strlen (vl->plugin) <= 0) || (strlen (vl->type) <= 0)) return (-EINVAL); if (!check_receive_okay (vl)) { #if COLLECT_DEBUG char name[6*DATA_MAX_NAME_LEN]; FORMAT_VL (name, sizeof (name), vl); name[sizeof (name) - 1] = 0; DEBUG ("network plugin: network_dispatch_values: " "NOT dispatching %s.", name); #endif stats_values_not_dispatched++; return (0); } assert (vl->meta == NULL); vl->meta = meta_data_create (); if (vl->meta == NULL) { ERROR ("network plugin: meta_data_create failed."); return (-ENOMEM); } status = meta_data_add_boolean (vl->meta, "zeromq:received", 1); if (status != 0) { ERROR ("network plugin: meta_data_add_boolean failed."); meta_data_destroy (vl->meta); vl->meta = NULL; return (status); } if (username != NULL) { status = meta_data_add_string (vl->meta, "zeromq:username", username); if (status != 0) { ERROR ("network plugin: meta_data_add_string failed."); meta_data_destroy (vl->meta); vl->meta = NULL; return (status); } } // DEBUG("dispatching %d values", vl->values_len); plugin_dispatch_values (vl); stats_values_dispatched++; meta_data_destroy (vl->meta); vl->meta = NULL; return (0); } /* }}} int network_dispatch_values */