static Msg *riemann_value_list_to_protobuf (struct riemann_host const *host, /* {{{ */ data_set_t const *ds, value_list_t const *vl, int *statuses) { Msg *msg; size_t i; gauge_t *rates = NULL; /* Initialize the Msg structure. */ msg = malloc (sizeof (*msg)); if (msg == NULL) { ERROR ("write_riemann plugin: malloc failed."); return (NULL); } memset (msg, 0, sizeof (*msg)); msg__init (msg); /* Set up events. First, the list of pointers. */ msg->n_events = vl->values_len; msg->events = calloc (msg->n_events, sizeof (*msg->events)); if (msg->events == NULL) { ERROR ("write_riemann plugin: calloc failed."); riemann_msg_protobuf_free (msg); return (NULL); } if (host->store_rates) { rates = uc_get_rate (ds, vl); if (rates == NULL) { ERROR ("write_riemann plugin: uc_get_rate failed."); riemann_msg_protobuf_free (msg); return (NULL); } } for (i = 0; i < msg->n_events; i++) { msg->events[i] = riemann_value_to_protobuf (host, ds, vl, (int) i, rates, statuses[i]); if (msg->events[i] == NULL) { riemann_msg_protobuf_free (msg); sfree (rates); return (NULL); } } sfree (rates); return (msg); } /* }}} Msg *riemann_value_list_to_protobuf */
/* Update the num, sum, min, max, ... fields of the aggregation instance, if * the rate of the value list is available. Value lists with more than one data * source are not supported and will return an error. Returns zero on success * and non-zero otherwise. */ static int agg_instance_update (agg_instance_t *inst, /* {{{ */ data_set_t const *ds, value_list_t const *vl) { gauge_t *rate; if (ds->ds_num != 1) { ERROR ("aggregation plugin: The \"%s\" type (data set) has more than one " "data source. This is currently not supported by this plugin. " "Sorry.", ds->type); return (EINVAL); } rate = uc_get_rate (ds, vl); if (rate == NULL) { char ident[6 * DATA_MAX_NAME_LEN]; FORMAT_VL (ident, sizeof (ident), vl); ERROR ("aggregation plugin: Unable to read the current rate of \"%s\".", ident); return (ENOENT); } if (isnan (rate[0])) { sfree (rate); return (0); } pthread_mutex_lock (&inst->lock); inst->num++; inst->sum += rate[0]; inst->squares_sum += (rate[0] * rate[0]); if (isnan (inst->min) || (inst->min > rate[0])) inst->min = rate[0]; if (isnan (inst->max) || (inst->max < rate[0])) inst->max = rate[0]; pthread_mutex_unlock (&inst->lock); sfree (rate); return (0); } /* }}} int agg_instance_update */
static riemann_message_t * wrr_value_list_to_message(struct riemann_host const *host, /* {{{ */ data_set_t const *ds, value_list_t const *vl, int *statuses) { riemann_message_t *msg; size_t i; gauge_t *rates = NULL; /* Initialize the Msg structure. */ msg = riemann_message_new(); if (msg == NULL) { ERROR("write_riemann plugin: riemann_message_new failed."); return NULL; } if (host->store_rates) { rates = uc_get_rate(ds, vl); if (rates == NULL) { ERROR("write_riemann plugin: uc_get_rate failed."); riemann_message_free(msg); return NULL; } } for (i = 0; i < vl->values_len; i++) { riemann_event_t *event; event = wrr_value_to_event(host, ds, vl, (int)i, rates, statuses[i]); if (event == NULL) { riemann_message_free(msg); sfree(rates); return NULL; } riemann_message_append_events(msg, event, NULL); } sfree(rates); return msg; } /* }}} riemann_message_t *wrr_value_list_to_message */
int format_graphite (char *buffer, size_t buffer_size, data_set_t const *ds, value_list_t const *vl, char const *prefix, char const *postfix, char const escape_char, unsigned int flags) { int status = 0; int buffer_pos = 0; gauge_t *rates = NULL; if (flags & GRAPHITE_STORE_RATES) rates = uc_get_rate (ds, vl); for (size_t i = 0; i < ds->ds_num; i++) { char const *ds_name = NULL; char key[10*DATA_MAX_NAME_LEN]; char values[512]; size_t message_len; char message[1024]; if ((flags & GRAPHITE_ALWAYS_APPEND_DS) || (ds->ds_num > 1)) ds_name = ds->ds[i].name; /* Copy the identifier to `key' and escape it. */ status = gr_format_name (key, sizeof (key), vl, ds_name, prefix, postfix, escape_char, flags); if (status != 0) { ERROR ("format_graphite: error with gr_format_name"); sfree (rates); return (status); } escape_graphite_string (key, escape_char); /* Convert the values to an ASCII representation and put that into * `values'. */ status = gr_format_values (values, sizeof (values), i, ds, vl, rates); if (status != 0) { ERROR ("format_graphite: error with gr_format_values"); sfree (rates); return (status); } /* Compute the graphite command */ message_len = (size_t) ssnprintf (message, sizeof (message), "%s %s %u\r\n", key, values, (unsigned int) CDTIME_T_TO_TIME_T (vl->time)); if (message_len >= sizeof (message)) { ERROR ("format_graphite: message buffer too small: " "Need %zu bytes.", message_len + 1); sfree (rates); return (-ENOMEM); } /* Append it in case we got multiple data set */ if ((buffer_pos + message_len) >= buffer_size) { ERROR ("format_graphite: target buffer too small"); sfree (rates); return (-ENOMEM); } memcpy((void *) (buffer + buffer_pos), message, message_len); buffer_pos += message_len; } sfree (rates); return (status); } /* int format_graphite */
static char *values_to_sqlarray (const data_set_t *ds, const value_list_t *vl, char *string, size_t string_len, _Bool store_rates) { char *str_ptr; size_t str_len; gauge_t *rates = NULL; int i; str_ptr = string; str_len = string_len; for (i = 0; i < vl->values_len; ++i) { int status = 0; if ((ds->ds[i].type != DS_TYPE_GAUGE) && (ds->ds[i].type != DS_TYPE_COUNTER) && (ds->ds[i].type != DS_TYPE_DERIVE) && (ds->ds[i].type != DS_TYPE_ABSOLUTE)) { log_err ("c_psql_write: Unknown data source type: %i", ds->ds[i].type); sfree (rates); return NULL; } if (ds->ds[i].type == DS_TYPE_GAUGE) status = ssnprintf (str_ptr, str_len, ",%f", vl->values[i].gauge); else if (store_rates) { if (rates == NULL) rates = uc_get_rate (ds, vl); if (rates == NULL) { log_err ("c_psql_write: Failed to determine rate"); return NULL; } status = ssnprintf (str_ptr, str_len, ",%lf", rates[i]); } else if (ds->ds[i].type == DS_TYPE_COUNTER) status = ssnprintf (str_ptr, str_len, ",%llu", vl->values[i].counter); else if (ds->ds[i].type == DS_TYPE_DERIVE) status = ssnprintf (str_ptr, str_len, ",%"PRIi64, vl->values[i].derive); else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) status = ssnprintf (str_ptr, str_len, ",%"PRIu64, vl->values[i].absolute); if (status < 1) { str_len = 0; break; } else if ((size_t)status >= str_len) { str_len = 0; break; } else { str_ptr += status; str_len -= (size_t)status; } } sfree (rates); if (str_len <= 2) { log_err ("c_psql_write: Failed to stringify value list"); return NULL; } /* overwrite the first comma */ string[0] = '{'; str_ptr[0] = '}'; str_ptr[1] = '\0'; return string; } /* values_to_sqlarray */
static int values_to_json (char *buffer, size_t buffer_size, /* {{{ */ const data_set_t *ds, const value_list_t *vl, int store_rates) { size_t offset = 0; int i; gauge_t *rates = NULL; memset (buffer, 0, buffer_size); #define BUFFER_ADD(...) do { \ int status; \ status = ssnprintf (buffer + offset, buffer_size - offset, \ __VA_ARGS__); \ if (status < 1) \ { \ sfree(rates); \ return (-1); \ } \ else if (((size_t) status) >= (buffer_size - offset)) \ { \ sfree(rates); \ return (-ENOMEM); \ } \ else \ offset += ((size_t) status); \ } while (0) BUFFER_ADD ("["); for (i = 0; i < ds->ds_num; i++) { if (i > 0) BUFFER_ADD (","); if (ds->ds[i].type == DS_TYPE_GAUGE) { if(isfinite (vl->values[i].gauge)) BUFFER_ADD ("%g", vl->values[i].gauge); else BUFFER_ADD ("null"); } else if (store_rates) { if (rates == NULL) rates = uc_get_rate (ds, vl); if (rates == NULL) { WARNING ("utils_format_json: uc_get_rate failed."); sfree(rates); return (-1); } if(isfinite (rates[i])) BUFFER_ADD ("%g", rates[i]); else BUFFER_ADD ("null"); } else if (ds->ds[i].type == DS_TYPE_COUNTER) BUFFER_ADD ("%llu", vl->values[i].counter); else if (ds->ds[i].type == DS_TYPE_DERIVE) BUFFER_ADD ("%"PRIi64, vl->values[i].derive); else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) BUFFER_ADD ("%"PRIu64, vl->values[i].absolute); else { ERROR ("format_json: Unknown data source type: %i", ds->ds[i].type); sfree (rates); return (-1); } } /* for ds->ds_num */ BUFFER_ADD ("]"); #undef BUFFER_ADD DEBUG ("format_json: values_to_json: buffer = %s;", buffer); sfree(rates); return (0); } /* }}} int values_to_json */
static int value_list_to_string (char *buffer, int buffer_len, const data_set_t *ds, const value_list_t *vl) { int offset; int status; int i; gauge_t *rates = NULL; assert (0 == strcmp (ds->type, vl->type)); memset (buffer, '\0', buffer_len); status = ssnprintf (buffer, buffer_len, "%u", (unsigned int) vl->time); if ((status < 1) || (status >= buffer_len)) return (-1); offset = status; for (i = 0; i < ds->ds_num; i++) { if ((ds->ds[i].type != DS_TYPE_COUNTER) && (ds->ds[i].type != DS_TYPE_GAUGE)) return (-1); if (ds->ds[i].type == DS_TYPE_COUNTER) { if (store_rates == 0) { status = ssnprintf (buffer + offset, buffer_len - offset, ",%llu", vl->values[i].counter); } else /* if (store_rates == 1) */ { if (rates == NULL) rates = uc_get_rate (ds, vl); if (rates == NULL) { WARNING ("csv plugin: " "uc_get_rate failed."); return (-1); } status = ssnprintf (buffer + offset, buffer_len - offset, ",%lf", rates[i]); } } else /* if (ds->ds[i].type == DS_TYPE_GAUGE) */ { status = ssnprintf (buffer + offset, buffer_len - offset, ",%lf", vl->values[i].gauge); } if ((status < 1) || (status >= (buffer_len - offset))) { sfree (rates); return (-1); } offset += status; } /* for ds->ds_num */ sfree (rates); return (0); } /* int value_list_to_string */
/* * Functions */ static bson *wm_create_bson (const data_set_t *ds, /* {{{ */ const value_list_t *vl, _Bool store_rates) { bson *ret; gauge_t *rates; ret = bson_alloc (); /* matched by bson_dealloc() */ if (ret == NULL) { ERROR ("write_mongodb plugin: bson_create failed."); return (NULL); } if (store_rates) { rates = uc_get_rate (ds, vl); if (rates == NULL) { ERROR ("write_mongodb plugin: uc_get_rate() failed."); return (NULL); } } else { rates = NULL; } bson_init (ret); /* matched by bson_destroy() */ bson_append_date (ret, "time", (bson_date_t) CDTIME_T_TO_MS (vl->time)); bson_append_string (ret, "host", vl->host); bson_append_string (ret, "plugin", vl->plugin); bson_append_string (ret, "plugin_instance", vl->plugin_instance); bson_append_string (ret, "type", vl->type); bson_append_string (ret, "type_instance", vl->type_instance); bson_append_start_array (ret, "values"); /* {{{ */ for (int i = 0; i < ds->ds_num; i++) { char key[16]; ssnprintf (key, sizeof (key), "%i", i); if (ds->ds[i].type == DS_TYPE_GAUGE) bson_append_double(ret, key, vl->values[i].gauge); else if (store_rates) bson_append_double(ret, key, (double) rates[i]); else if (ds->ds[i].type == DS_TYPE_COUNTER) bson_append_long(ret, key, vl->values[i].counter); else if (ds->ds[i].type == DS_TYPE_DERIVE) bson_append_long(ret, key, vl->values[i].derive); else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) bson_append_long(ret, key, vl->values[i].absolute); else assert (23 == 42); } bson_append_finish_array (ret); /* }}} values */ bson_append_start_array (ret, "dstypes"); /* {{{ */ for (int i = 0; i < ds->ds_num; i++) { char key[16]; ssnprintf (key, sizeof (key), "%i", i); if (store_rates) bson_append_string (ret, key, "gauge"); else bson_append_string (ret, key, DS_TYPE_TO_STRING (ds->ds[i].type)); } bson_append_finish_array (ret); /* }}} dstypes */ bson_append_start_array (ret, "dsnames"); /* {{{ */ for (int i = 0; i < ds->ds_num; i++) { char key[16]; ssnprintf (key, sizeof (key), "%i", i); bson_append_string (ret, key, ds->ds[i].name); } bson_append_finish_array (ret); /* }}} dsnames */ bson_finish (ret); sfree (rates); return (ret); } /* }}} bson *wm_create_bson */
static int values_to_kairosdb(char *buffer, size_t buffer_size, /* {{{ */ const data_set_t *ds, const value_list_t *vl, int store_rates, size_t ds_idx) { size_t offset = 0; gauge_t *rates = NULL; memset(buffer, 0, buffer_size); #define BUFFER_ADD(...) \ do { \ int status; \ status = snprintf(buffer + offset, buffer_size - offset, __VA_ARGS__); \ if (status < 1) { \ sfree(rates); \ return -1; \ } else if (((size_t)status) >= (buffer_size - offset)) { \ sfree(rates); \ return -ENOMEM; \ } else \ offset += ((size_t)status); \ } while (0) if (ds->ds[ds_idx].type == DS_TYPE_GAUGE) { if (isfinite(vl->values[ds_idx].gauge)) { BUFFER_ADD("[["); BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time)); BUFFER_ADD(","); BUFFER_ADD(JSON_GAUGE_FORMAT, vl->values[ds_idx].gauge); } else { DEBUG("utils_format_kairosdb: invalid vl->values[ds_idx].gauge for " "%s|%s|%s|%s|%s", vl->plugin, vl->plugin_instance, vl->type, vl->type_instance, ds->ds[ds_idx].name); return -1; } } else if (store_rates) { if (rates == NULL) rates = uc_get_rate(ds, vl); if (rates == NULL) { WARNING("utils_format_kairosdb: uc_get_rate failed for %s|%s|%s|%s|%s", vl->plugin, vl->plugin_instance, vl->type, vl->type_instance, ds->ds[ds_idx].name); return -1; } if (isfinite(rates[ds_idx])) { BUFFER_ADD("[["); BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time)); BUFFER_ADD(","); BUFFER_ADD(JSON_GAUGE_FORMAT, rates[ds_idx]); } else { WARNING("utils_format_kairosdb: invalid rates[ds_idx] for %s|%s|%s|%s|%s", vl->plugin, vl->plugin_instance, vl->type, vl->type_instance, ds->ds[ds_idx].name); sfree(rates); return -1; } } else if (ds->ds[ds_idx].type == DS_TYPE_COUNTER) { BUFFER_ADD("[["); BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time)); BUFFER_ADD(","); BUFFER_ADD("%" PRIu64, (uint64_t)vl->values[ds_idx].counter); } else if (ds->ds[ds_idx].type == DS_TYPE_DERIVE) { BUFFER_ADD("[["); BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time)); BUFFER_ADD(","); BUFFER_ADD("%" PRIi64, vl->values[ds_idx].derive); } else if (ds->ds[ds_idx].type == DS_TYPE_ABSOLUTE) { BUFFER_ADD("[["); BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time)); BUFFER_ADD(","); BUFFER_ADD("%" PRIu64, vl->values[ds_idx].absolute); } else { ERROR("format_kairosdb: Unknown data source type: %i", ds->ds[ds_idx].type); sfree(rates); return -1; } BUFFER_ADD("]]"); #undef BUFFER_ADD DEBUG("format_kairosdb: values_to_kairosdb: buffer = %s;", buffer); sfree(rates); return 0; } /* }}} int values_to_kairosdb */
static int mv_match (const data_set_t *ds, const value_list_t *vl, /* {{{ */ notification_meta_t **meta, void **user_data) { mv_match_t *m; gauge_t *values; int status; int i; if ((user_data == NULL) || (*user_data == NULL)) return (-1); m = *user_data; values = uc_get_rate (ds, vl); if (values == NULL) { ERROR ("`value' match: Retrieving the current rate from the cache " "failed."); return (-1); } status = FC_MATCH_NO_MATCH; for (i = 0; i < ds->ds_num; i++) { int value_matches = 0; /* Check if this data source is relevant. */ if (m->data_sources != NULL) { size_t j; for (j = 0; j < m->data_sources_num; j++) if (strcasecmp (ds->ds[i].name, m->data_sources[j]) == 0) break; /* No match, ignore this data source. */ if (j >= m->data_sources_num) continue; } DEBUG ("`value' match: current = %g; min = %g; max = %g; invert = %s;", values[i], m->min, m->max, m->invert ? "true" : "false"); if ((!isnan (m->min) && (values[i] < m->min)) || (!isnan (m->max) && (values[i] > m->max))) value_matches = 0; else value_matches = 1; if (m->invert) { if (value_matches) value_matches = 0; else value_matches = 1; } if (value_matches != 0) { status = FC_MATCH_MATCHES; if (m->satisfy == SATISFY_ANY) break; } else if (value_matches == 0) { status = FC_MATCH_NO_MATCH; if (m->satisfy == SATISFY_ALL) break; } } /* for (i = 0; i < ds->ds_num; i++) */ free (values); return (status); } /* }}} int mv_match */
int format_values_extremon (char *ret, size_t ret_len, const data_set_t *ds, const value_list_t *vl, _Bool store_rates) { size_t offset = 0; int status=0; int i; gauge_t* rates = NULL; assert (0 == strcmp (ds->type, vl->type)); assert (vl->plugin != NULL); assert (vl->type != NULL); memset (ret, 0, ret_len); #define BUFFER_ADD(...) do { \ status = ssnprintf (ret + offset, ret_len - offset, \ __VA_ARGS__); \ if (status < 1) \ { \ sfree (rates); \ return (-1); \ } \ else if (((size_t) status) >= (ret_len - offset)) \ { \ sfree (rates); \ return (-1); \ } \ else \ offset += ((size_t) status); \ } while (0) for(i=0;i<ds->ds_num;i++) { if((vl->plugin_instance==NULL) || (strlen (vl->plugin_instance)= 0)) { if ((vl->type_instance==NULL) || (strlen(vl->type_instance)==0)) BUFFER_ADD("%s.%s.%s.",vl->host,vl->plugin,vl->type); else BUFFER_ADD("%s.%s.%s.%s.",vl->host,vl->plugin,vl->type, vl->type_instance); } else { if((vl->type_instance == NULL) || (strlen(vl->type_instance) == 0)) BUFFER_ADD("%s.%s.%s.%s.", vl->host,vl->plugin, vl->plugin_instance, vl->type); else BUFFER_ADD("%s.%s.%s.%s.%s.", vl->host,vl->plugin, vl->plugin_instance,vl->type, vl->type_instance); } if(ds->ds[i].type==DS_TYPE_GAUGE) BUFFER_ADD ("%s=%f\n", ds->ds[i].name,vl->values[i].gauge); else if(store_rates) { if(rates==NULL) rates=uc_get_rate (ds, vl); if(rates==NULL) { WARNING ("format_values_extremon : uc_get_rate failed."); return (-1); } BUFFER_ADD ("%s=%g\n", ds->ds[i].name,rates[i]); } else if(ds->ds[i].type==DS_TYPE_COUNTER) BUFFER_ADD ("%s=%llu\n", ds->ds[i].name,vl->values[i].counter); } #undef BUFFER_ADD sfree (rates); return (0); }