static cdtime_t parse_time (char const *tbuf) { double t; char *endptr = 0; errno = 0; t = strtod (tbuf, &endptr); if ((errno != 0) || (endptr == NULL) || (endptr[0] != 0)) return (cdtime ()); return (DOUBLE_TO_CDTIME_T (t)); }
cdtime_t latency_counter_get_percentile (latency_counter_t *lc, /* {{{ */ double percent) { double percent_upper; double percent_lower; double p; cdtime_t latency_lower; cdtime_t latency_interpolated; int sum; size_t i; if ((lc == NULL) || (lc->num == 0) || !((percent > 0.0) && (percent < 100.0))) return (0); /* Find index i so that at least "percent" events are within i+1 ms. */ percent_upper = 0.0; percent_lower = 0.0; sum = 0; for (i = 0; i < HISTOGRAM_NUM_BINS; i++) { percent_lower = percent_upper; sum += lc->histogram[i]; if (sum == 0) percent_upper = 0.0; else percent_upper = 100.0 * ((double) sum) / ((double) lc->num); if (percent_upper >= percent) break; } if (i >= HISTOGRAM_NUM_BINS) return (0); assert (percent_upper >= percent); assert (percent_lower < percent); if (i == 0) return (lc->bin_width); latency_lower = ((cdtime_t) i) * lc->bin_width; p = (percent - percent_lower) / (percent_upper - percent_lower); latency_interpolated = latency_lower + DOUBLE_TO_CDTIME_T (p * CDTIME_T_TO_DOUBLE (lc->bin_width)); DEBUG ("latency_counter_get_percentile: latency_interpolated = %.3f", CDTIME_T_TO_DOUBLE (latency_interpolated)); return (latency_interpolated); } /* }}} cdtime_t latency_counter_get_percentile */
static int latency_config_add_bucket(latency_config_t *conf, oconfig_item_t *ci, const char *plugin) { if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_NUMBER) || (ci->values[1].type != OCONFIG_TYPE_NUMBER)) { ERROR("%s plugin: \"%s\" requires exactly two numeric arguments.", plugin, ci->key); return EINVAL; } if (ci->values[1].value.number && ci->values[1].value.number <= ci->values[0].value.number) { ERROR("%s plugin: MIN must be less than MAX in \"%s\".", plugin, ci->key); return ERANGE; } if (ci->values[0].value.number < 0) { ERROR("%s plugin: MIN must be greater then or equal to zero in \"%s\".", plugin, ci->key); return ERANGE; } latency_bucket_t *tmp = realloc(conf->buckets, sizeof(*conf->buckets) * (conf->buckets_num + 1)); if (tmp == NULL) { ERROR("%s plugin: realloc failed.", plugin); return ENOMEM; } conf->buckets = tmp; conf->buckets[conf->buckets_num].lower_bound = DOUBLE_TO_CDTIME_T(ci->values[0].value.number); conf->buckets[conf->buckets_num].upper_bound = DOUBLE_TO_CDTIME_T(ci->values[1].value.number); conf->buckets_num++; return (0); } /* int latency_config_add_bucket */
static int set_option_time(notification_t *n, const char *value) { char *endptr = NULL; double tmp; errno = 0; tmp = strtod(value, &endptr); if ((errno != 0) /* Overflow */ || (endptr == value) /* Invalid string */ || (endptr == NULL) /* This should not happen */ || (*endptr != 0)) /* Trailing chars */ return -1; n->time = DOUBLE_TO_CDTIME_T(tmp); return 0; } /* int set_option_time */
static int set_option (value_list_t *vl, const char *key, const char *value) { if ((vl == NULL) || (key == NULL) || (value == NULL)) return (-1); if (strcasecmp ("interval", key) == 0) { double tmp; char *endptr; endptr = NULL; errno = 0; tmp = strtod (value, &endptr); if ((errno == 0) && (endptr != NULL) && (endptr != value) && (tmp > 0.0)) vl->interval = DOUBLE_TO_CDTIME_T (tmp); } else return (1); return (0); } /* int parse_option */
int handle_flush (FILE *fh, char *buffer) { int success = 0; int error = 0; double timeout = 0.0; char **plugins = NULL; size_t plugins_num = 0; char **identifiers = NULL; size_t identifiers_num = 0; #define PRINT_TO_SOCK(fh, ...) \ do { \ if (fprintf (fh, __VA_ARGS__) < 0) { \ char errbuf[1024]; \ WARNING ("handle_flush: failed to write to socket #%i: %s", \ fileno (fh), sstrerror (errno, errbuf, sizeof (errbuf))); \ strarray_free (plugins, plugins_num); \ strarray_free (identifiers, identifiers_num); \ return -1; \ } \ fflush(fh); \ } while (0) if ((fh == NULL) || (buffer == NULL)) return (-1); DEBUG ("utils_cmd_flush: handle_flush (fh = %p, buffer = %s);", (void *) fh, buffer); if (strncasecmp ("FLUSH", buffer, strlen ("FLUSH")) != 0) { PRINT_TO_SOCK (fh, "-1 Cannot parse command.\n"); return (-1); } buffer += strlen ("FLUSH"); while (*buffer != 0) { char *opt_key; char *opt_value; int status; opt_key = NULL; opt_value = NULL; status = parse_option (&buffer, &opt_key, &opt_value); if (status != 0) { PRINT_TO_SOCK (fh, "-1 Parsing options failed.\n"); strarray_free (plugins, plugins_num); strarray_free (identifiers, identifiers_num); return (-1); } if (strcasecmp ("plugin", opt_key) == 0) strarray_add (&plugins, &plugins_num, opt_value); else if (strcasecmp ("identifier", opt_key) == 0) strarray_add (&identifiers, &identifiers_num, opt_value); else if (strcasecmp ("timeout", opt_key) == 0) { char *endptr; errno = 0; endptr = NULL; timeout = strtod (opt_value, &endptr); if ((endptr == opt_value) || (errno != 0) || (!isfinite (timeout))) { PRINT_TO_SOCK (fh, "-1 Invalid value for option `timeout': " "%s\n", opt_value); strarray_free (plugins, plugins_num); strarray_free (identifiers, identifiers_num); return (-1); } else if (timeout < 0.0) { timeout = 0.0; } } else { PRINT_TO_SOCK (fh, "-1 Cannot parse option %s\n", opt_key); strarray_free (plugins, plugins_num); strarray_free (identifiers, identifiers_num); return (-1); } } /* while (*buffer != 0) */ for (size_t i = 0; (i == 0) || (i < plugins_num); i++) { char *plugin = NULL; if (plugins_num != 0) plugin = plugins[i]; for (size_t j = 0; (j == 0) || (j < identifiers_num); j++) { char *identifier = NULL; int status; if (identifiers_num != 0) identifier = identifiers[j]; status = plugin_flush (plugin, DOUBLE_TO_CDTIME_T (timeout), identifier); if (status == 0) success++; else error++; } } PRINT_TO_SOCK (fh, "0 Done: %i successful, %i errors\n", success, error); strarray_free (plugins, plugins_num); strarray_free (identifiers, identifiers_num); return (0); #undef PRINT_TO_SOCK } /* int handle_flush */