From: Florian Forster Date: Mon, 28 Nov 2016 21:16:04 +0000 (+0100) Subject: Merge branch 'collectd-5.6' X-Git-Tag: collectd-5.7.0~10 X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=facbb03bdd0c591344b1a81dd0437064cfcc24e5;p=collectd.git Merge branch 'collectd-5.6' --- facbb03bdd0c591344b1a81dd0437064cfcc24e5 diff --cc src/utils_cmd_flush.h index 9dbff20c,031fcac9..57b90853 --- a/src/utils_cmd_flush.h +++ b/src/utils_cmd_flush.h @@@ -29,15 -29,7 +29,15 @@@ #include -int handle_flush(FILE *fh, char *buffer); +#include "utils_cmds.h" + - cmd_status_t cmd_parse_flush (size_t argc, char **argv, - cmd_flush_t *ret_flush, const cmd_options_t *opts, - cmd_error_handler_t *err); ++cmd_status_t cmd_parse_flush(size_t argc, char **argv, cmd_flush_t *ret_flush, ++ const cmd_options_t *opts, ++ cmd_error_handler_t *err); + - cmd_status_t cmd_handle_flush (FILE *fh, char *buffer); ++cmd_status_t cmd_handle_flush(FILE *fh, char *buffer); + - void cmd_destroy_flush (cmd_flush_t *flush); ++void cmd_destroy_flush(cmd_flush_t *flush); #endif /* UTILS_CMD_FLUSH_H */ diff --cc src/utils_cmd_getthreshold.c index e6086f27,ac2578da..60363da5 --- a/src/utils_cmd_getthreshold.c +++ b/src/utils_cmd_getthreshold.c @@@ -97,17 -92,14 +92,15 @@@ int handle_getthreshold(FILE *fh, char /* parse_identifier() modifies its first argument, * returning pointers into it */ - identifier_copy = sstrdup (identifier); - - status = parse_identifier (identifier_copy, &host, - &plugin, &plugin_instance, - &type, &type_instance, - /* default_host = */ NULL); - if (status != 0) - { - DEBUG ("handle_getthreshold: Cannot parse identifier `%s'.", identifier); - print_to_socket (fh, "-1 Cannot parse identifier `%s'.\n", identifier); - sfree (identifier_copy); + identifier_copy = sstrdup(identifier); + + status = parse_identifier(identifier_copy, &host, &plugin, &plugin_instance, - &type, &type_instance); ++ &type, &type_instance, ++ /* default_host = */ NULL); + if (status != 0) { + DEBUG("handle_getthreshold: Cannot parse identifier `%s'.", identifier); + print_to_socket(fh, "-1 Cannot parse identifier `%s'.\n", identifier); + sfree(identifier_copy); return (-1); } diff --cc src/utils_cmd_getval.c index f29680a1,3df13b17..c23650b3 --- a/src/utils_cmd_getval.c +++ b/src/utils_cmd_getval.c @@@ -30,152 -30,124 +30,139 @@@ #include "plugin.h" #include "utils_cache.h" - #include "utils_parse_option.h" #include "utils_cmd_getval.h" + #include "utils_parse_option.h" - cmd_status_t cmd_parse_getval (size_t argc, char **argv, - cmd_getval_t *ret_getval, const cmd_options_t *opts, - cmd_error_handler_t *err) - { ++cmd_status_t cmd_parse_getval(size_t argc, char **argv, ++ cmd_getval_t *ret_getval, ++ const cmd_options_t *opts, ++ cmd_error_handler_t *err) { + char *identifier_copy; + int status; + - if ((ret_getval == NULL) || (opts == NULL)) - { ++ if ((ret_getval == NULL) || (opts == NULL)) { + errno = EINVAL; - cmd_error (CMD_ERROR, err, "Invalid arguments to cmd_parse_getval."); ++ cmd_error(CMD_ERROR, err, "Invalid arguments to cmd_parse_getval."); + return (CMD_ERROR); + } + - if (argc != 1) - { ++ if (argc != 1) { + if (argc == 0) - cmd_error (CMD_PARSE_ERROR, err, "Missing identifier."); ++ cmd_error(CMD_PARSE_ERROR, err, "Missing identifier."); + else - cmd_error (CMD_PARSE_ERROR, err, - "Garbage after identifier: `%s'.", argv[1]); ++ cmd_error(CMD_PARSE_ERROR, err, "Garbage after identifier: `%s'.", ++ argv[1]); + return (CMD_PARSE_ERROR); + } + + /* parse_identifier() modifies its first argument, + * returning pointers into it */ - identifier_copy = sstrdup (argv[0]); - - status = parse_identifier (argv[0], &ret_getval->identifier.host, - &ret_getval->identifier.plugin, &ret_getval->identifier.plugin_instance, - &ret_getval->identifier.type, &ret_getval->identifier.type_instance, - opts->identifier_default_host); - if (status != 0) - { - DEBUG ("cmd_parse_getval: Cannot parse identifier `%s'.", identifier_copy); - cmd_error (CMD_PARSE_ERROR, err, - "Cannot parse identifier `%s'.", identifier_copy); - sfree (identifier_copy); ++ identifier_copy = sstrdup(argv[0]); ++ ++ status = parse_identifier( ++ argv[0], &ret_getval->identifier.host, &ret_getval->identifier.plugin, ++ &ret_getval->identifier.plugin_instance, &ret_getval->identifier.type, ++ &ret_getval->identifier.type_instance, opts->identifier_default_host); ++ if (status != 0) { ++ DEBUG("cmd_parse_getval: Cannot parse identifier `%s'.", identifier_copy); ++ cmd_error(CMD_PARSE_ERROR, err, "Cannot parse identifier `%s'.", ++ identifier_copy); ++ sfree(identifier_copy); + return (CMD_PARSE_ERROR); + } + + ret_getval->raw_identifier = identifier_copy; + return (CMD_OK); +} /* cmd_status_t cmd_parse_getval */ + - #define print_to_socket(fh, ...) \ - do { \ - if (fprintf (fh, __VA_ARGS__) < 0) { \ - char errbuf[1024]; \ - WARNING ("cmd_handle_getval: failed to write to socket #%i: %s", \ - fileno (fh), sstrerror (errno, errbuf, sizeof (errbuf))); \ - return -1; \ - } \ - fflush(fh); \ + #define print_to_socket(fh, ...) \ + do { \ + if (fprintf(fh, __VA_ARGS__) < 0) { \ + char errbuf[1024]; \ - WARNING("handle_getval: failed to write to socket #%i: %s", fileno(fh), \ - sstrerror(errno, errbuf, sizeof(errbuf))); \ ++ WARNING("cmd_handle_getval: failed to write to socket #%i: %s", \ ++ fileno(fh), sstrerror(errno, errbuf, sizeof(errbuf))); \ + return -1; \ + } \ + fflush(fh); \ } while (0) - cmd_status_t cmd_handle_getval (FILE *fh, char *buffer) - { - cmd_error_handler_t err = { cmd_error_fh, fh }; -int handle_getval(FILE *fh, char *buffer) { - char *command; - char *identifier; - char *identifier_copy; ++cmd_status_t cmd_handle_getval(FILE *fh, char *buffer) { ++ cmd_error_handler_t err = {cmd_error_fh, fh}; + cmd_status_t status; + cmd_t cmd; - char *hostname; - char *plugin; - char *plugin_instance; - char *type; - char *type_instance; gauge_t *values; size_t values_num; const data_set_t *ds; - int status; -- if ((fh == NULL) || (buffer == NULL)) return (-1); - DEBUG ("utils_cmd_getval: cmd_handle_getval (fh = %p, buffer = %s);", - (void *) fh, buffer); - DEBUG("utils_cmd_getval: handle_getval (fh = %p, buffer = %s);", (void *)fh, - buffer); ++ DEBUG("utils_cmd_getval: cmd_handle_getval (fh = %p, buffer = %s);", ++ (void *)fh, buffer); - if ((status = cmd_parse (buffer, &cmd, NULL, &err)) != CMD_OK) - command = NULL; - status = parse_string(&buffer, &command); - if (status != 0) { - print_to_socket(fh, "-1 Cannot parse command.\n"); - return (-1); - } - assert(command != NULL); - - if (strcasecmp("GETVAL", command) != 0) { - print_to_socket(fh, "-1 Unexpected command: `%s'.\n", command); - return (-1); ++ if ((status = cmd_parse(buffer, &cmd, NULL, &err)) != CMD_OK) + return (status); - if (cmd.type != CMD_GETVAL) - { - cmd_error (CMD_UNKNOWN_COMMAND, &err, - "Unexpected command: `%s'.", CMD_TO_STRING (cmd.type)); - cmd_destroy (&cmd); ++ if (cmd.type != CMD_GETVAL) { ++ cmd_error(CMD_UNKNOWN_COMMAND, &err, "Unexpected command: `%s'.", ++ CMD_TO_STRING(cmd.type)); ++ cmd_destroy(&cmd); + return (CMD_UNKNOWN_COMMAND); } - ds = plugin_get_ds (cmd.cmd.getval.identifier.type); - if (ds == NULL) - { - DEBUG ("cmd_handle_getval: plugin_get_ds (%s) == NULL;", - cmd.cmd.getval.identifier.type); - cmd_error (CMD_ERROR, &err, "Type `%s' is unknown.\n", - cmd.cmd.getval.identifier.type); - cmd_destroy (&cmd); - identifier = NULL; - status = parse_string(&buffer, &identifier); - if (status != 0) { - print_to_socket(fh, "-1 Cannot parse identifier.\n"); - return (-1); - } - assert(identifier != NULL); - - if (*buffer != 0) { - print_to_socket(fh, "-1 Garbage after end of command: %s\n", buffer); - return (-1); - } - - /* parse_identifier() modifies its first argument, - * returning pointers into it */ - identifier_copy = sstrdup(identifier); - - status = parse_identifier(identifier_copy, &hostname, &plugin, - &plugin_instance, &type, &type_instance); - if (status != 0) { - DEBUG("handle_getval: Cannot parse identifier `%s'.", identifier); - print_to_socket(fh, "-1 Cannot parse identifier `%s'.\n", identifier); - sfree(identifier_copy); - return (-1); - } - - ds = plugin_get_ds(type); ++ ds = plugin_get_ds(cmd.cmd.getval.identifier.type); + if (ds == NULL) { - DEBUG("handle_getval: plugin_get_ds (%s) == NULL;", type); - print_to_socket(fh, "-1 Type `%s' is unknown.\n", type); - sfree(identifier_copy); ++ DEBUG("cmd_handle_getval: plugin_get_ds (%s) == NULL;", ++ cmd.cmd.getval.identifier.type); ++ cmd_error(CMD_ERROR, &err, "Type `%s' is unknown.\n", ++ cmd.cmd.getval.identifier.type); ++ cmd_destroy(&cmd); return (-1); } values = NULL; values_num = 0; - status = uc_get_rate_by_name (cmd.cmd.getval.raw_identifier, &values, &values_num); - if (status != 0) - { - cmd_error (CMD_ERROR, &err, "No such value."); - cmd_destroy (&cmd); - status = uc_get_rate_by_name(identifier, &values, &values_num); ++ status = ++ uc_get_rate_by_name(cmd.cmd.getval.raw_identifier, &values, &values_num); + if (status != 0) { - print_to_socket(fh, "-1 No such value\n"); - sfree(identifier_copy); - return (-1); ++ cmd_error(CMD_ERROR, &err, "No such value."); ++ cmd_destroy(&cmd); + return (CMD_ERROR); } - if (ds->ds_num != values_num) - { - ERROR ("ds[%s]->ds_num = %zu, " - "but uc_get_rate_by_name returned %zu values.", - ds->type, ds->ds_num, values_num); - cmd_error (CMD_ERROR, &err, "Error reading value from cache."); - sfree (values); - cmd_destroy (&cmd); + if (ds->ds_num != values_num) { + ERROR("ds[%s]->ds_num = %zu, " + "but uc_get_rate_by_name returned %zu values.", + ds->type, ds->ds_num, values_num); - print_to_socket(fh, "-1 Error reading value from cache.\n"); ++ cmd_error(CMD_ERROR, &err, "Error reading value from cache."); + sfree(values); - sfree(identifier_copy); - return (-1); ++ cmd_destroy(&cmd); + return (CMD_ERROR); } - print_to_socket (fh, "%zu Value%s found\n", values_num, - (values_num == 1) ? "" : "s"); - for (size_t i = 0; i < values_num; i++) - { - print_to_socket (fh, "%s=", ds->ds[i].name); - if (isnan (values[i])) - { - print_to_socket (fh, "NaN\n"); - } - else - { - print_to_socket (fh, "%12e\n", values[i]); + print_to_socket(fh, "%zu Value%s found\n", values_num, + (values_num == 1) ? "" : "s"); + for (size_t i = 0; i < values_num; i++) { + print_to_socket(fh, "%s=", ds->ds[i].name); + if (isnan(values[i])) { + print_to_socket(fh, "NaN\n"); + } else { + print_to_socket(fh, "%12e\n", values[i]); } } - sfree (values); - cmd_destroy (&cmd); + sfree(values); - sfree(identifier_copy); ++ cmd_destroy(&cmd); + + return (CMD_OK); +} /* cmd_status_t cmd_handle_getval */ + - void cmd_destroy_getval (cmd_getval_t *getval) - { ++void cmd_destroy_getval(cmd_getval_t *getval) { + if (getval == NULL) + return; - sfree (getval->raw_identifier); - return (0); -} /* int handle_getval */ ++ sfree(getval->raw_identifier); +} /* void cmd_destroy_getval */ /* vim: set sw=2 sts=2 ts=8 : */ diff --cc src/utils_cmd_getval.h index b0c64be1,011c63eb..8d488b31 --- a/src/utils_cmd_getval.h +++ b/src/utils_cmd_getval.h @@@ -29,15 -29,7 +29,16 @@@ #include -int handle_getval(FILE *fh, char *buffer); +#include "utils_cmds.h" + - cmd_status_t cmd_parse_getval (size_t argc, char **argv, - cmd_getval_t *ret_getval, const cmd_options_t *opts, - cmd_error_handler_t *err); ++cmd_status_t cmd_parse_getval(size_t argc, char **argv, ++ cmd_getval_t *ret_getval, ++ const cmd_options_t *opts, ++ cmd_error_handler_t *err); + - cmd_status_t cmd_handle_getval (FILE *fh, char *buffer); ++cmd_status_t cmd_handle_getval(FILE *fh, char *buffer); + - void cmd_destroy_getval (cmd_getval_t *getval); ++void cmd_destroy_getval(cmd_getval_t *getval); #endif /* UTILS_CMD_GETVAL_H */ diff --cc src/utils_cmd_listval.c index 27b88cbf,638f7fac..f8638893 --- a/src/utils_cmd_listval.c +++ b/src/utils_cmd_listval.c @@@ -29,88 -29,73 +29,84 @@@ #include "common.h" #include "plugin.h" - #include "utils_cmd_listval.h" #include "utils_cache.h" + #include "utils_cmd_listval.h" #include "utils_parse_option.h" - cmd_status_t cmd_parse_listval (size_t argc, char **argv, - cmd_listval_t *ret_listval __attribute__((unused)), - const cmd_options_t *opts __attribute__((unused)), - cmd_error_handler_t *err) - { - if (argc != 0) - { - cmd_error (CMD_PARSE_ERROR, err, - "Garbage after end of command: `%s'.", argv[0]); ++cmd_status_t cmd_parse_listval(size_t argc, char **argv, ++ cmd_listval_t *ret_listval ++ __attribute__((unused)), ++ const cmd_options_t *opts ++ __attribute__((unused)), ++ cmd_error_handler_t *err) { ++ if (argc != 0) { ++ cmd_error(CMD_PARSE_ERROR, err, "Garbage after end of command: `%s'.", ++ argv[0]); + return (CMD_PARSE_ERROR); + } + + return (CMD_OK); +} /* cmd_status_t cmd_parse_listval */ + - #define free_everything_and_return(status) do { \ - for (size_t j = 0; j < number; j++) { \ - sfree(names[j]); \ - names[j] = NULL; \ - } \ - sfree(names); \ - sfree(times); \ - return (status); \ + #define free_everything_and_return(status) \ + do { \ + for (size_t j = 0; j < number; j++) { \ + sfree(names[j]); \ + names[j] = NULL; \ + } \ + sfree(names); \ + sfree(times); \ + return (status); \ } while (0) - #define print_to_socket(fh, ...) \ - do { \ - if (fprintf (fh, __VA_ARGS__) < 0) { \ - char errbuf[1024]; \ - WARNING ("handle_listval: failed to write to socket #%i: %s", \ - fileno (fh), sstrerror (errno, errbuf, sizeof (errbuf))); \ - free_everything_and_return (CMD_ERROR); \ - } \ - fflush(fh); \ + #define print_to_socket(fh, ...) \ + do { \ + if (fprintf(fh, __VA_ARGS__) < 0) { \ + char errbuf[1024]; \ + WARNING("handle_listval: failed to write to socket #%i: %s", fileno(fh), \ + sstrerror(errno, errbuf, sizeof(errbuf))); \ - free_everything_and_return(-1); \ ++ free_everything_and_return(CMD_ERROR); \ + } \ + fflush(fh); \ } while (0) - cmd_status_t cmd_handle_listval (FILE *fh, char *buffer) - { - cmd_error_handler_t err = { cmd_error_fh, fh }; -int handle_listval(FILE *fh, char *buffer) { - char *command; ++cmd_status_t cmd_handle_listval(FILE *fh, char *buffer) { ++ cmd_error_handler_t err = {cmd_error_fh, fh}; + cmd_status_t status; + cmd_t cmd; + char **names = NULL; cdtime_t *times = NULL; size_t number = 0; - int status; - DEBUG ("utils_cmd_listval: handle_listval (fh = %p, buffer = %s);", - (void *) fh, buffer); + DEBUG("utils_cmd_listval: handle_listval (fh = %p, buffer = %s);", (void *)fh, + buffer); - if ((status = cmd_parse (buffer, &cmd, NULL, &err)) != CMD_OK) - command = NULL; - status = parse_string(&buffer, &command); - if (status != 0) { - print_to_socket(fh, "-1 Cannot parse command.\n"); - free_everything_and_return(-1); - } - assert(command != NULL); - - if (strcasecmp("LISTVAL", command) != 0) { - print_to_socket(fh, "-1 Unexpected command: `%s'.\n", command); - free_everything_and_return(-1); - } - - if (*buffer != 0) { - print_to_socket(fh, "-1 Garbage after end of command: %s\n", buffer); - free_everything_and_return(-1); ++ if ((status = cmd_parse(buffer, &cmd, NULL, &err)) != CMD_OK) + return (status); - if (cmd.type != CMD_LISTVAL) - { - cmd_error (CMD_UNKNOWN_COMMAND, &err, - "Unexpected command: `%s'.", CMD_TO_STRING (cmd.type)); - free_everything_and_return (CMD_UNKNOWN_COMMAND); ++ if (cmd.type != CMD_LISTVAL) { ++ cmd_error(CMD_UNKNOWN_COMMAND, &err, "Unexpected command: `%s'.", ++ CMD_TO_STRING(cmd.type)); ++ free_everything_and_return(CMD_UNKNOWN_COMMAND); } - status = uc_get_names (&names, ×, &number); - if (status != 0) - { - DEBUG ("command listval: uc_get_names failed with status %i", status); - cmd_error (CMD_ERROR, &err, "uc_get_names failed."); - free_everything_and_return (CMD_ERROR); + status = uc_get_names(&names, ×, &number); + if (status != 0) { + DEBUG("command listval: uc_get_names failed with status %i", status); - print_to_socket(fh, "-1 uc_get_names failed.\n"); - free_everything_and_return(-1); ++ cmd_error(CMD_ERROR, &err, "uc_get_names failed."); ++ free_everything_and_return(CMD_ERROR); } - print_to_socket (fh, "%i Value%s found\n", - (int) number, (number == 1) ? "" : "s"); + print_to_socket(fh, "%i Value%s found\n", (int)number, + (number == 1) ? "" : "s"); for (size_t i = 0; i < number; i++) - print_to_socket (fh, "%.3f %s\n", CDTIME_T_TO_DOUBLE (times[i]), - names[i]); + print_to_socket(fh, "%.3f %s\n", CDTIME_T_TO_DOUBLE(times[i]), names[i]); - free_everything_and_return (CMD_OK); - free_everything_and_return(0); -} /* int handle_listval */ ++ free_everything_and_return(CMD_OK); +} /* cmd_status_t cmd_handle_listval */ + - void cmd_destroy_listval (cmd_listval_t *listval __attribute__((unused))) - { ++void cmd_destroy_listval(cmd_listval_t *listval __attribute__((unused))) { + /* nothing to do */ +} /* void cmd_destroy_listval */ /* vim: set sw=2 sts=2 ts=8 : */ diff --cc src/utils_cmd_listval.h index 895878c0,f4250faa..8a4e8c8b --- a/src/utils_cmd_listval.h +++ b/src/utils_cmd_listval.h @@@ -29,15 -29,7 +29,16 @@@ #include -int handle_listval(FILE *fh, char *buffer); +#include "utils_cmds.h" + - cmd_status_t cmd_parse_listval (size_t argc, char **argv, - cmd_listval_t *ret_listval, const cmd_options_t *opts, - cmd_error_handler_t *err); ++cmd_status_t cmd_parse_listval(size_t argc, char **argv, ++ cmd_listval_t *ret_listval, ++ const cmd_options_t *opts, ++ cmd_error_handler_t *err); + - cmd_status_t cmd_handle_listval (FILE *fh, char *buffer); ++cmd_status_t cmd_handle_listval(FILE *fh, char *buffer); + - void cmd_destroy_listval (cmd_listval_t *listval); ++void cmd_destroy_listval(cmd_listval_t *listval); #endif /* UTILS_CMD_LISTVAL_H */ diff --cc src/utils_cmd_putval.c index 691f1f80,66b502ab..e0455335 --- a/src/utils_cmd_putval.c +++ b/src/utils_cmd_putval.c @@@ -31,283 -29,207 +31,256 @@@ #include "common.h" #include "plugin.h" - #include "utils_cmds.h" #include "utils_cmd_putval.h" - #include "utils_parse_option.h" +#include "utils_cmd_putval.h" ++#include "utils_cmds.h" + #include "utils_parse_option.h" -#define print_to_socket(fh, ...) \ - do { \ - if (fprintf(fh, __VA_ARGS__) < 0) { \ - char errbuf[1024]; \ - WARNING("handle_putval: failed to write to socket #%i: %s", fileno(fh), \ - sstrerror(errno, errbuf, sizeof(errbuf))); \ - sfree(vl.values); \ - return -1; \ - } \ - fflush(fh); \ - } while (0) +/* + * private helper functions + */ - static int set_option (value_list_t *vl, const char *key, const char *value) - { - if ((vl == NULL) || (key == NULL) || (value == NULL)) - return (-1); + 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; + if (strcasecmp("interval", key) == 0) { + double tmp; + char *endptr; - endptr = NULL; - errno = 0; - tmp = strtod (value, &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); + if ((errno == 0) && (endptr != NULL) && (endptr != value) && (tmp > 0.0)) + vl->interval = DOUBLE_TO_CDTIME_T(tmp); + } else + return (1); - return (0); + return (0); -} /* int parse_option */ +} /* int set_option */ + +/* + * public API + */ + - cmd_status_t cmd_parse_putval (size_t argc, char **argv, - cmd_putval_t *ret_putval, const cmd_options_t *opts, - cmd_error_handler_t *err) - { - cmd_status_t result; - - char *identifier; - char *hostname; - char *plugin; - char *plugin_instance; - char *type; - char *type_instance; - int status; - - char *identifier_copy; - - const data_set_t *ds; - value_list_t vl = VALUE_LIST_INIT; - - if ((ret_putval == NULL) || (opts == NULL)) - { - errno = EINVAL; - cmd_error (CMD_ERROR, err, "Invalid arguments to cmd_parse_putval."); - return (CMD_ERROR); - } - - if (argc < 2) - { - cmd_error (CMD_PARSE_ERROR, err, - "Missing identifier and/or value-list."); - return (CMD_PARSE_ERROR); - } - - identifier = argv[0]; - - /* parse_identifier() modifies its first argument, returning pointers into - * it; retain the old value for later. */ - identifier_copy = sstrdup (identifier); - - status = parse_identifier (identifier, &hostname, - &plugin, &plugin_instance, - &type, &type_instance, - opts->identifier_default_host); - if (status != 0) - { - DEBUG ("cmd_handle_putval: Cannot parse identifier `%s'.", - identifier_copy); - cmd_error (CMD_PARSE_ERROR, err, "Cannot parse identifier `%s'.", - identifier_copy); - sfree (identifier_copy); - return (CMD_PARSE_ERROR); - } - - if ((strlen (hostname) >= sizeof (vl.host)) - || (strlen (plugin) >= sizeof (vl.plugin)) - || ((plugin_instance != NULL) - && (strlen (plugin_instance) >= sizeof (vl.plugin_instance))) - || ((type_instance != NULL) - && (strlen (type_instance) >= sizeof (vl.type_instance)))) - { - cmd_error (CMD_PARSE_ERROR, err, "Identifier too long."); - sfree (identifier_copy); - return (CMD_PARSE_ERROR); - } - - sstrncpy (vl.host, hostname, sizeof (vl.host)); - sstrncpy (vl.plugin, plugin, sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); - if (plugin_instance != NULL) - sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); - if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); - - ds = plugin_get_ds (type); - if (ds == NULL) - { - cmd_error (CMD_PARSE_ERROR, err, "1 Type `%s' isn't defined.", type); - sfree (identifier_copy); - return (CMD_PARSE_ERROR); - } - - hostname = NULL; - plugin = NULL; plugin_instance = NULL; - type = NULL; type_instance = NULL; - - vl.values_len = ds->ds_num; - vl.values = malloc (vl.values_len * sizeof (*vl.values)); - if (vl.values == NULL) - { - cmd_error (CMD_ERROR, err, "malloc failed."); - sfree (identifier_copy); - return (CMD_ERROR); - } - - ret_putval->raw_identifier = identifier_copy; - if (ret_putval->raw_identifier == NULL) - { - cmd_error (CMD_ERROR, err, "malloc failed."); - cmd_destroy_putval (ret_putval); - sfree (vl.values); - return (CMD_ERROR); - } - - /* All the remaining fields are part of the option list. */ - result = CMD_OK; - for (size_t i = 1; i < argc; ++i) - { - value_list_t *tmp; - - char *key = NULL; - char *value = NULL; - - status = cmd_parse_option (argv[i], &key, &value, err); - if (status == CMD_OK) - { - assert (key != NULL); - assert (value != NULL); - set_option (&vl, key, value); - continue; - } - else if (status != CMD_NO_OPTION) - { - /* parse_option failed, buffer has been modified. - * => we need to abort */ - result = status; - break; - } - /* else: cmd_parse_option did not find an option; treat this as a - * value list. */ - - status = parse_values (argv[i], &vl, ds); - if (status != 0) - { - cmd_error (CMD_PARSE_ERROR, err, "Parsing the values string failed."); - result = CMD_PARSE_ERROR; - break; - } - - tmp = (value_list_t *) realloc (ret_putval->vl, - (ret_putval->vl_num + 1) * sizeof(*ret_putval->vl)); - if (tmp == NULL) - { - cmd_error (CMD_ERROR, err, "realloc failed."); - cmd_destroy_putval (ret_putval); - result = CMD_ERROR; - break; - } - - ret_putval->vl = tmp; - ret_putval->vl_num++; - memcpy (&ret_putval->vl[ret_putval->vl_num - 1], &vl, sizeof (vl)); - } /* while (*buffer != 0) */ - /* Done parsing the options. */ - - if (result != CMD_OK) - { - if (ret_putval->vl_num == 0) - sfree (vl.values); - cmd_destroy_putval (ret_putval); - } - - return (result); ++cmd_status_t cmd_parse_putval(size_t argc, char **argv, ++ cmd_putval_t *ret_putval, ++ const cmd_options_t *opts, ++ cmd_error_handler_t *err) { ++ cmd_status_t result; + -int handle_putval(FILE *fh, char *buffer) { - char *command; + char *identifier; + char *hostname; + char *plugin; + char *plugin_instance; + char *type; + char *type_instance; + int status; - int values_submitted; + + char *identifier_copy; + + const data_set_t *ds; + value_list_t vl = VALUE_LIST_INIT; - vl.values = NULL; + - DEBUG("utils_cmd_putval: handle_putval (fh = %p, buffer = %s);", (void *)fh, - buffer); - - command = NULL; - status = parse_string(&buffer, &command); - if (status != 0) { - print_to_socket(fh, "-1 Cannot parse command.\n"); - return (-1); ++ if ((ret_putval == NULL) || (opts == NULL)) { ++ errno = EINVAL; ++ cmd_error(CMD_ERROR, err, "Invalid arguments to cmd_parse_putval."); ++ return (CMD_ERROR); + } - assert(command != NULL); + - if (strcasecmp("PUTVAL", command) != 0) { - print_to_socket(fh, "-1 Unexpected command: `%s'.\n", command); - return (-1); ++ if (argc < 2) { ++ cmd_error(CMD_PARSE_ERROR, err, "Missing identifier and/or value-list."); ++ return (CMD_PARSE_ERROR); + } + - identifier = NULL; - status = parse_string(&buffer, &identifier); - if (status != 0) { - print_to_socket(fh, "-1 Cannot parse identifier.\n"); - return (-1); - } - assert(identifier != NULL); ++ identifier = argv[0]; + - /* parse_identifier() modifies its first argument, - * returning pointers into it */ ++ /* parse_identifier() modifies its first argument, returning pointers into ++ * it; retain the old value for later. */ + identifier_copy = sstrdup(identifier); + - status = parse_identifier(identifier_copy, &hostname, &plugin, - &plugin_instance, &type, &type_instance); ++ status = ++ parse_identifier(identifier, &hostname, &plugin, &plugin_instance, &type, ++ &type_instance, opts->identifier_default_host); + if (status != 0) { - DEBUG("handle_putval: Cannot parse identifier `%s'.", identifier); - print_to_socket(fh, "-1 Cannot parse identifier `%s'.\n", identifier); ++ DEBUG("cmd_handle_putval: Cannot parse identifier `%s'.", identifier_copy); ++ cmd_error(CMD_PARSE_ERROR, err, "Cannot parse identifier `%s'.", ++ identifier_copy); + sfree(identifier_copy); - return (-1); ++ return (CMD_PARSE_ERROR); + } + + if ((strlen(hostname) >= sizeof(vl.host)) || + (strlen(plugin) >= sizeof(vl.plugin)) || + ((plugin_instance != NULL) && + (strlen(plugin_instance) >= sizeof(vl.plugin_instance))) || + ((type_instance != NULL) && + (strlen(type_instance) >= sizeof(vl.type_instance)))) { - print_to_socket(fh, "-1 Identifier too long.\n"); ++ cmd_error(CMD_PARSE_ERROR, err, "Identifier too long."); + sfree(identifier_copy); - return (-1); ++ return (CMD_PARSE_ERROR); + } + + sstrncpy(vl.host, hostname, sizeof(vl.host)); + sstrncpy(vl.plugin, plugin, sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); + if (plugin_instance != NULL) + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + if (type_instance != NULL) + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + + ds = plugin_get_ds(type); + if (ds == NULL) { - print_to_socket(fh, "-1 Type `%s' isn't defined.\n", type); ++ cmd_error(CMD_PARSE_ERROR, err, "1 Type `%s' isn't defined.", type); + sfree(identifier_copy); - return (-1); ++ return (CMD_PARSE_ERROR); + } + - /* Free identifier_copy */ + hostname = NULL; + plugin = NULL; + plugin_instance = NULL; + type = NULL; + type_instance = NULL; - sfree(identifier_copy); + + vl.values_len = ds->ds_num; + vl.values = malloc(vl.values_len * sizeof(*vl.values)); + if (vl.values == NULL) { - print_to_socket(fh, "-1 malloc failed.\n"); - return (-1); ++ cmd_error(CMD_ERROR, err, "malloc failed."); ++ sfree(identifier_copy); ++ return (CMD_ERROR); ++ } ++ ++ ret_putval->raw_identifier = identifier_copy; ++ if (ret_putval->raw_identifier == NULL) { ++ cmd_error(CMD_ERROR, err, "malloc failed."); ++ cmd_destroy_putval(ret_putval); ++ sfree(vl.values); ++ return (CMD_ERROR); + } + - /* All the remaining fields are part of the optionlist. */ - values_submitted = 0; - while (*buffer != 0) { - char *string = NULL; ++ /* All the remaining fields are part of the option list. */ ++ result = CMD_OK; ++ for (size_t i = 1; i < argc; ++i) { ++ value_list_t *tmp; ++ ++ char *key = NULL; + char *value = NULL; + - status = parse_option(&buffer, &string, &value); - if (status < 0) { - /* parse_option failed, buffer has been modified. - * => we need to abort */ - print_to_socket(fh, "-1 Misformatted option.\n"); - sfree(vl.values); - return (-1); - } else if (status == 0) { - assert(string != NULL); ++ status = cmd_parse_option(argv[i], &key, &value, err); ++ if (status == CMD_OK) { ++ assert(key != NULL); + assert(value != NULL); - set_option(&vl, string, value); ++ set_option(&vl, key, value); + continue; ++ } else if (status != CMD_NO_OPTION) { ++ /* parse_option failed, buffer has been modified. ++ * => we need to abort */ ++ result = status; ++ break; + } - /* else: parse_option but buffer has not been modified. This is - * the default if no `=' is found.. */ ++ /* else: cmd_parse_option did not find an option; treat this as a ++ * value list. */ + - status = parse_string(&buffer, &string); ++ status = parse_values(argv[i], &vl, ds); + if (status != 0) { - print_to_socket(fh, "-1 Misformatted value.\n"); - sfree(vl.values); - return (-1); ++ cmd_error(CMD_PARSE_ERROR, err, "Parsing the values string failed."); ++ result = CMD_PARSE_ERROR; ++ break; + } - assert(string != NULL); + - status = parse_values(string, &vl, ds); - if (status != 0) { - print_to_socket(fh, "-1 Parsing the values string failed.\n"); - sfree(vl.values); - return (-1); ++ tmp = (value_list_t *)realloc(ret_putval->vl, (ret_putval->vl_num + 1) * ++ sizeof(*ret_putval->vl)); ++ if (tmp == NULL) { ++ cmd_error(CMD_ERROR, err, "realloc failed."); ++ cmd_destroy_putval(ret_putval); ++ result = CMD_ERROR; ++ break; + } + - plugin_dispatch_values(&vl); - values_submitted++; ++ ret_putval->vl = tmp; ++ ret_putval->vl_num++; ++ memcpy(&ret_putval->vl[ret_putval->vl_num - 1], &vl, sizeof(vl)); + } /* while (*buffer != 0) */ + /* Done parsing the options. */ + ++ if (result != CMD_OK) { ++ if (ret_putval->vl_num == 0) ++ sfree(vl.values); ++ cmd_destroy_putval(ret_putval); ++ } ++ ++ return (result); +} /* cmd_status_t cmd_parse_putval */ + - void cmd_destroy_putval (cmd_putval_t *putval) - { - if (putval == NULL) - return; - - sfree (putval->raw_identifier); - - for (size_t i = 0; i < putval->vl_num; ++i) - { - if (i == 0) /* values is shared between all entries */ - sfree (putval->vl[i].values); - meta_data_destroy (putval->vl[i].meta); - putval->vl[i].meta = NULL; - } - sfree (putval->vl); - putval->vl = NULL; - putval->vl_num = 0; ++void cmd_destroy_putval(cmd_putval_t *putval) { ++ if (putval == NULL) ++ return; ++ ++ sfree(putval->raw_identifier); ++ ++ for (size_t i = 0; i < putval->vl_num; ++i) { ++ if (i == 0) /* values is shared between all entries */ ++ sfree(putval->vl[i].values); ++ meta_data_destroy(putval->vl[i].meta); ++ putval->vl[i].meta = NULL; ++ } ++ sfree(putval->vl); ++ putval->vl = NULL; ++ putval->vl_num = 0; +} /* void cmd_destroy_putval */ + - cmd_status_t cmd_handle_putval (FILE *fh, char *buffer) - { - cmd_error_handler_t err = { cmd_error_fh, fh }; - cmd_t cmd; ++cmd_status_t cmd_handle_putval(FILE *fh, char *buffer) { ++ cmd_error_handler_t err = {cmd_error_fh, fh}; ++ cmd_t cmd; + - int status; ++ int status; + - DEBUG ("utils_cmd_putval: cmd_handle_putval (fh = %p, buffer = %s);", - (void *) fh, buffer); ++ DEBUG("utils_cmd_putval: cmd_handle_putval (fh = %p, buffer = %s);", ++ (void *)fh, buffer); + - if ((status = cmd_parse (buffer, &cmd, NULL, &err)) != CMD_OK) - return (status); - if (cmd.type != CMD_PUTVAL) - { - cmd_error (CMD_UNKNOWN_COMMAND, &err, "Unexpected command: `%s'.", - CMD_TO_STRING (cmd.type)); - cmd_destroy (&cmd); - return (CMD_UNKNOWN_COMMAND); - } ++ if ((status = cmd_parse(buffer, &cmd, NULL, &err)) != CMD_OK) ++ return (status); ++ if (cmd.type != CMD_PUTVAL) { ++ cmd_error(CMD_UNKNOWN_COMMAND, &err, "Unexpected command: `%s'.", ++ CMD_TO_STRING(cmd.type)); ++ cmd_destroy(&cmd); ++ return (CMD_UNKNOWN_COMMAND); ++ } + - for (size_t i = 0; i < cmd.cmd.putval.vl_num; ++i) - plugin_dispatch_values (&cmd.cmd.putval.vl[i]); ++ for (size_t i = 0; i < cmd.cmd.putval.vl_num; ++i) ++ plugin_dispatch_values(&cmd.cmd.putval.vl[i]); + - if (fh != stdout) - cmd_error (CMD_OK, &err, "Success: %i %s been dispatched.", - (int)cmd.cmd.putval.vl_num, - (cmd.cmd.putval.vl_num == 1) ? "value has" : "values have"); + if (fh != stdout) - print_to_socket(fh, "0 Success: %i %s been dispatched.\n", values_submitted, - (values_submitted == 1) ? "value has" : "values have"); ++ cmd_error(CMD_OK, &err, "Success: %i %s been dispatched.", ++ (int)cmd.cmd.putval.vl_num, ++ (cmd.cmd.putval.vl_num == 1) ? "value has" : "values have"); - cmd_destroy (&cmd); - return (CMD_OK); - sfree(vl.values); - return (0); -} /* int handle_putval */ ++ cmd_destroy(&cmd); ++ return (CMD_OK); +} /* int cmd_handle_putval */ - int cmd_create_putval (char *ret, size_t ret_len, /* {{{ */ - const data_set_t *ds, const value_list_t *vl) - { - char buffer_ident[6 * DATA_MAX_NAME_LEN]; - char buffer_values[1024]; - int status; - - status = FORMAT_VL (buffer_ident, sizeof (buffer_ident), vl); - if (status != 0) - return (status); - escape_string (buffer_ident, sizeof (buffer_ident)); - - status = format_values (buffer_values, sizeof (buffer_values), - ds, vl, /* store rates = */ 0); - if (status != 0) - return (status); - escape_string (buffer_values, sizeof (buffer_values)); - - ssnprintf (ret, ret_len, - "PUTVAL %s interval=%.3f %s", - buffer_ident, - (vl->interval > 0) - ? CDTIME_T_TO_DOUBLE (vl->interval) - : CDTIME_T_TO_DOUBLE (plugin_get_interval ()), - buffer_values); - - return (0); -int create_putval(char *ret, size_t ret_len, /* {{{ */ - const data_set_t *ds, const value_list_t *vl) { ++int cmd_create_putval(char *ret, size_t ret_len, /* {{{ */ ++ const data_set_t *ds, const value_list_t *vl) { + char buffer_ident[6 * DATA_MAX_NAME_LEN]; + char buffer_values[1024]; + int status; + + status = FORMAT_VL(buffer_ident, sizeof(buffer_ident), vl); + if (status != 0) + return (status); + escape_string(buffer_ident, sizeof(buffer_ident)); + + status = format_values(buffer_values, sizeof(buffer_values), ds, vl, + /* store rates = */ 0); + if (status != 0) + return (status); + escape_string(buffer_values, sizeof(buffer_values)); + + ssnprintf(ret, ret_len, "PUTVAL %s interval=%.3f %s", buffer_ident, + (vl->interval > 0) ? CDTIME_T_TO_DOUBLE(vl->interval) + : CDTIME_T_TO_DOUBLE(plugin_get_interval()), + buffer_values); + + return (0); -} /* }}} int create_putval */ +} /* }}} int cmd_create_putval */ diff --cc src/utils_cmd_putval.h index bb0b227f,9f60ca0e..75cd190c --- a/src/utils_cmd_putval.h +++ b/src/utils_cmd_putval.h @@@ -30,17 -30,10 +30,18 @@@ #include #include "plugin.h" +#include "utils_cmds.h" - cmd_status_t cmd_parse_putval (size_t argc, char **argv, - cmd_putval_t *ret_putval, const cmd_options_t *opts, - cmd_error_handler_t *err); -int handle_putval(FILE *fh, char *buffer); ++cmd_status_t cmd_parse_putval(size_t argc, char **argv, ++ cmd_putval_t *ret_putval, ++ const cmd_options_t *opts, ++ cmd_error_handler_t *err); - cmd_status_t cmd_handle_putval (FILE *fh, char *buffer); -int create_putval(char *ret, size_t ret_len, const data_set_t *ds, - const value_list_t *vl); ++cmd_status_t cmd_handle_putval(FILE *fh, char *buffer); + - void cmd_destroy_putval (cmd_putval_t *putval); ++void cmd_destroy_putval(cmd_putval_t *putval); + - int cmd_create_putval (char *ret, size_t ret_len, - const data_set_t *ds, const value_list_t *vl); ++int cmd_create_putval(char *ret, size_t ret_len, const data_set_t *ds, ++ const value_list_t *vl); #endif /* UTILS_CMD_PUTVAL_H */ diff --cc src/utils_format_graphite.c index 85f5917c,2fe93959..4f509f4a --- a/src/utils_format_graphite.c +++ b/src/utils_format_graphite.c @@@ -79,190 -73,154 +73,169 @@@ static int gr_format_values(char *ret, #undef BUFFER_ADD - return (0); + return (0); } - static void gr_copy_escape_part (char *dst, const char *src, size_t dst_len, - char escape_char, _Bool preserve_separator) - { - memset (dst, 0, dst_len); - - if (src == NULL) - return; - - for (size_t i = 0; i < dst_len; i++) - { - if (src[i] == 0) - { - dst[i] = 0; - break; - } - - if ((!preserve_separator && (src[i] == '.')) - || isspace ((int) src[i]) - || iscntrl ((int) src[i])) - dst[i] = escape_char; - else - dst[i] = src[i]; + static void gr_copy_escape_part(char *dst, const char *src, size_t dst_len, - char escape_char) { ++ char escape_char, _Bool preserve_separator) { + memset(dst, 0, dst_len); + + if (src == NULL) + return; + + for (size_t i = 0; i < dst_len; i++) { + if (src[i] == 0) { + dst[i] = 0; + break; } + - if ((src[i] == '.') || isspace((int)src[i]) || iscntrl((int)src[i])) ++ if ((!preserve_separator && (src[i] == '.')) || isspace((int)src[i]) || ++ iscntrl((int)src[i])) + dst[i] = escape_char; + else + dst[i] = src[i]; + } } - static int gr_format_name (char *ret, int ret_len, - value_list_t const *vl, - char const *ds_name, - char const *prefix, - char const *postfix, - char const escape_char, - unsigned int flags) - { - char n_host[DATA_MAX_NAME_LEN]; - char n_plugin[DATA_MAX_NAME_LEN]; - char n_plugin_instance[DATA_MAX_NAME_LEN]; - char n_type[DATA_MAX_NAME_LEN]; - char n_type_instance[DATA_MAX_NAME_LEN]; - - char tmp_plugin[2 * DATA_MAX_NAME_LEN + 1]; - char tmp_type[2 * DATA_MAX_NAME_LEN + 1]; - - if (prefix == NULL) - prefix = ""; - - if (postfix == NULL) - postfix = ""; - - _Bool preserve_separator = (flags & GRAPHITE_PRESERVE_SEPARATOR) ? 1 : 0; - - gr_copy_escape_part (n_host, vl->host, - sizeof (n_host), escape_char, preserve_separator); - gr_copy_escape_part (n_plugin, vl->plugin, - sizeof (n_plugin), escape_char, preserve_separator); - gr_copy_escape_part (n_plugin_instance, vl->plugin_instance, - sizeof (n_plugin_instance), escape_char, preserve_separator); - gr_copy_escape_part (n_type, vl->type, - sizeof (n_type), escape_char, preserve_separator); - gr_copy_escape_part (n_type_instance, vl->type_instance, - sizeof (n_type_instance), escape_char, preserve_separator); - - if (n_plugin_instance[0] != '\0') - ssnprintf (tmp_plugin, sizeof (tmp_plugin), "%s%c%s", - n_plugin, - (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-', - n_plugin_instance); + static int gr_format_name(char *ret, int ret_len, value_list_t const *vl, + char const *ds_name, char const *prefix, + char const *postfix, char const escape_char, + unsigned int flags) { + char n_host[DATA_MAX_NAME_LEN]; + char n_plugin[DATA_MAX_NAME_LEN]; + char n_plugin_instance[DATA_MAX_NAME_LEN]; + char n_type[DATA_MAX_NAME_LEN]; + char n_type_instance[DATA_MAX_NAME_LEN]; + + char tmp_plugin[2 * DATA_MAX_NAME_LEN + 1]; + char tmp_type[2 * DATA_MAX_NAME_LEN + 1]; + + if (prefix == NULL) + prefix = ""; + + if (postfix == NULL) + postfix = ""; + - gr_copy_escape_part(n_host, vl->host, sizeof(n_host), escape_char); - gr_copy_escape_part(n_plugin, vl->plugin, sizeof(n_plugin), escape_char); ++ _Bool preserve_separator = (flags & GRAPHITE_PRESERVE_SEPARATOR) ? 1 : 0; ++ ++ gr_copy_escape_part(n_host, vl->host, sizeof(n_host), escape_char, ++ preserve_separator); ++ gr_copy_escape_part(n_plugin, vl->plugin, sizeof(n_plugin), escape_char, ++ preserve_separator); + gr_copy_escape_part(n_plugin_instance, vl->plugin_instance, - sizeof(n_plugin_instance), escape_char); - gr_copy_escape_part(n_type, vl->type, sizeof(n_type), escape_char); ++ sizeof(n_plugin_instance), escape_char, ++ preserve_separator); ++ gr_copy_escape_part(n_type, vl->type, sizeof(n_type), escape_char, ++ preserve_separator); + gr_copy_escape_part(n_type_instance, vl->type_instance, - sizeof(n_type_instance), escape_char); ++ sizeof(n_type_instance), escape_char, preserve_separator); + + if (n_plugin_instance[0] != '\0') + ssnprintf(tmp_plugin, sizeof(tmp_plugin), "%s%c%s", n_plugin, + (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-', + n_plugin_instance); + else + sstrncpy(tmp_plugin, n_plugin, sizeof(tmp_plugin)); + - if (n_type_instance[0] != '\0') - ssnprintf(tmp_type, sizeof(tmp_type), "%s%c%s", n_type, - (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-', - n_type_instance); - else ++ if (n_type_instance[0] != '\0') { ++ if ((flags & GRAPHITE_DROP_DUPE_FIELDS) && strcmp(n_plugin, n_type) == 0) ++ sstrncpy(tmp_type, n_type_instance, sizeof(tmp_type)); + else - sstrncpy (tmp_plugin, n_plugin, sizeof (tmp_plugin)); - - if (n_type_instance[0] != '\0') - { - if ((flags & GRAPHITE_DROP_DUPE_FIELDS) && strcmp(n_plugin, n_type) == 0) - sstrncpy (tmp_type, n_type_instance, sizeof (tmp_type)); - else - ssnprintf (tmp_type, sizeof (tmp_type), "%s%c%s", - n_type, ++ ssnprintf(tmp_type, sizeof(tmp_type), "%s%c%s", n_type, + (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-', + n_type_instance); - } - else - sstrncpy (tmp_type, n_type, sizeof (tmp_type)); - - /* Assert always_append_ds -> ds_name */ - assert (!(flags & GRAPHITE_ALWAYS_APPEND_DS) || (ds_name != NULL)); - if (ds_name != NULL) - { - if ((flags & GRAPHITE_DROP_DUPE_FIELDS) && strcmp(tmp_plugin, tmp_type) == 0) - ssnprintf (ret, ret_len, "%s%s%s.%s.%s", - prefix, n_host, postfix, tmp_plugin, ds_name); - else - ssnprintf (ret, ret_len, "%s%s%s.%s.%s.%s", - prefix, n_host, postfix, tmp_plugin, tmp_type, ds_name); - } ++ } else + sstrncpy(tmp_type, n_type, sizeof(tmp_type)); + + /* Assert always_append_ds -> ds_name */ + assert(!(flags & GRAPHITE_ALWAYS_APPEND_DS) || (ds_name != NULL)); - if (ds_name != NULL) - ssnprintf(ret, ret_len, "%s%s%s.%s.%s.%s", prefix, n_host, postfix, - tmp_plugin, tmp_type, ds_name); - else ++ if (ds_name != NULL) { ++ if ((flags & GRAPHITE_DROP_DUPE_FIELDS) && ++ strcmp(tmp_plugin, tmp_type) == 0) ++ ssnprintf(ret, ret_len, "%s%s%s.%s.%s", prefix, n_host, postfix, ++ tmp_plugin, ds_name); + else - ssnprintf (ret, ret_len, "%s%s%s.%s.%s", - prefix, n_host, postfix, tmp_plugin, tmp_type); ++ ssnprintf(ret, ret_len, "%s%s%s.%s.%s.%s", prefix, n_host, postfix, ++ tmp_plugin, tmp_type, ds_name); ++ } else + ssnprintf(ret, ret_len, "%s%s%s.%s.%s", prefix, n_host, postfix, tmp_plugin, + tmp_type); - return (0); + return (0); } - static void escape_graphite_string (char *buffer, char escape_char) - { - assert (strchr(GRAPHITE_FORBIDDEN, escape_char) == NULL); + static void escape_graphite_string(char *buffer, char escape_char) { + assert(strchr(GRAPHITE_FORBIDDEN, escape_char) == NULL); - for (char *head = buffer + strcspn(buffer, GRAPHITE_FORBIDDEN); - *head != '\0'; - head += strcspn(head, GRAPHITE_FORBIDDEN)) - *head = escape_char; + for (char *head = buffer + strcspn(buffer, GRAPHITE_FORBIDDEN); *head != '\0'; + head += strcspn(head, GRAPHITE_FORBIDDEN)) + *head = escape_char; } - 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; - buffer[buffer_pos] = '\0'; + 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); } - sfree (rates); - return (status); + memcpy((void *)(buffer + buffer_pos), message, message_len); + buffer_pos += message_len; + buffer[buffer_pos] = '\0'; + } + sfree(rates); + return (status); } /* int format_graphite */ /* vim: set sw=2 sts=2 et fdm=marker : */ diff --cc src/utils_format_graphite.h index ebc50802,b82da9f8..de90c44c --- a/src/utils_format_graphite.h +++ b/src/utils_format_graphite.h @@@ -26,16 -26,13 +26,15 @@@ #include "plugin.h" - #define GRAPHITE_STORE_RATES 0x01 + #define GRAPHITE_STORE_RATES 0x01 #define GRAPHITE_SEPARATE_INSTANCES 0x02 - #define GRAPHITE_ALWAYS_APPEND_DS 0x04 - #define GRAPHITE_DROP_DUPE_FIELDS 0x08 + #define GRAPHITE_ALWAYS_APPEND_DS 0x04 ++#define GRAPHITE_DROP_DUPE_FIELDS 0x08 +#define GRAPHITE_PRESERVE_SEPARATOR 0x10 - int format_graphite (char *buffer, - size_t buffer_size, const data_set_t *ds, - const value_list_t *vl, const char *prefix, - const char *postfix, const char escape_char, - unsigned int flags); + int format_graphite(char *buffer, size_t buffer_size, const data_set_t *ds, + const value_list_t *vl, const char *prefix, + const char *postfix, const char escape_char, + unsigned int flags); #endif /* UTILS_FORMAT_GRAPHITE_H */ diff --cc src/utils_latency.c index 5749f10d,651547ab..f0311e84 --- a/src/utils_latency.c +++ b/src/utils_latency.c @@@ -26,24 -26,27 +26,23 @@@ #include "collectd.h" + #include "common.h" #include "plugin.h" #include "utils_latency.h" - #include "common.h" - #include #include + #include #ifndef LLONG_MAX - # define LLONG_MAX 9223372036854775807LL + #define LLONG_MAX 9223372036854775807LL #endif -#ifndef HISTOGRAM_NUM_BINS -#define HISTOGRAM_NUM_BINS 1000 -#endif - #ifndef HISTOGRAM_DEFAULT_BIN_WIDTH /* 1048576 = 2^20 ^= 1/1024 s */ - # define HISTOGRAM_DEFAULT_BIN_WIDTH 1048576 + #define HISTOGRAM_DEFAULT_BIN_WIDTH 1048576 #endif - struct latency_counter_s - { + struct latency_counter_s { cdtime_t start_time; cdtime_t sum; diff --cc src/utils_latency.h index 8fdf0249,7c339c60..85493e1a --- a/src/utils_latency.h +++ b/src/utils_latency.h @@@ -28,39 -28,20 +28,38 @@@ #include "utils_time.h" +#ifndef HISTOGRAM_NUM_BINS - # define HISTOGRAM_NUM_BINS 1000 ++#define HISTOGRAM_NUM_BINS 1000 +#endif + struct latency_counter_s; typedef struct latency_counter_s latency_counter_t; - latency_counter_t *latency_counter_create (void); - void latency_counter_destroy (latency_counter_t *lc); + latency_counter_t *latency_counter_create(void); + void latency_counter_destroy(latency_counter_t *lc); - void latency_counter_add (latency_counter_t *lc, cdtime_t latency); - void latency_counter_reset (latency_counter_t *lc); + void latency_counter_add(latency_counter_t *lc, cdtime_t latency); + void latency_counter_reset(latency_counter_t *lc); - cdtime_t latency_counter_get_min (latency_counter_t *lc); - cdtime_t latency_counter_get_max (latency_counter_t *lc); - cdtime_t latency_counter_get_sum (latency_counter_t *lc); - size_t latency_counter_get_num (latency_counter_t *lc); - cdtime_t latency_counter_get_average (latency_counter_t *lc); - cdtime_t latency_counter_get_percentile (latency_counter_t *lc, - double percent); + cdtime_t latency_counter_get_min(latency_counter_t *lc); + cdtime_t latency_counter_get_max(latency_counter_t *lc); + cdtime_t latency_counter_get_sum(latency_counter_t *lc); + size_t latency_counter_get_num(latency_counter_t *lc); + cdtime_t latency_counter_get_average(latency_counter_t *lc); + cdtime_t latency_counter_get_percentile(latency_counter_t *lc, double percent); +/* + * NAME + * latency_counter_get_rate(counter,lower,upper,now) + * + * DESCRIPTION + * Calculates rate of latency values fall within requested interval. + * Interval specified as (lower,upper], i.e. the lower boundary is exclusive, + * the upper boundary is inclusive. + * When lower is zero, then the interval is (0, upper]. + * When upper is zero, then the interval is (lower, infinity). + */ - double latency_counter_get_rate (const latency_counter_t *lc, - cdtime_t lower, cdtime_t upper, const cdtime_t now); ++double latency_counter_get_rate(const latency_counter_t *lc, cdtime_t lower, ++ cdtime_t upper, const cdtime_t now); + /* vim: set sw=2 sts=2 et : */ diff --cc src/utils_latency_test.c index 01f194f1,7d160398..ef29d8bd --- a/src/utils_latency_test.c +++ b/src/utils_latency_test.c @@@ -96,139 -101,9 +101,134 @@@ DEF_TEST(percentile) return 0; } - DEF_TEST (get_rate) { ++DEF_TEST(get_rate) { + /* We re-declare the struct here so we can inspect its content. */ + struct { + cdtime_t start_time; + cdtime_t sum; + size_t num; + cdtime_t min; + cdtime_t max; + cdtime_t bin_width; + int histogram[HISTOGRAM_NUM_BINS]; - } *peek; ++ } * peek; + latency_counter_t *l; + - CHECK_NOT_NULL (l = latency_counter_create ()); - peek = (void *) l; ++ CHECK_NOT_NULL(l = latency_counter_create()); ++ peek = (void *)l; + + for (time_t i = 1; i <= 125; i++) { - latency_counter_add (l, TIME_T_TO_CDTIME_T(i)); ++ latency_counter_add(l, TIME_T_TO_CDTIME_T(i)); + } + + /* We expect a bucket width of 125ms. */ - EXPECT_EQ_UINT64 (DOUBLE_TO_CDTIME_T(0.125), peek->bin_width); ++ EXPECT_EQ_UINT64(DOUBLE_TO_CDTIME_T(0.125), peek->bin_width); + + struct { + size_t index; + int want; + } bucket_cases[] = { - { 0, 0}, /* (0.000-0.125] */ - { 1, 0}, /* (0.125-0.250] */ - { 2, 0}, /* (0.250-0.375] */ - { 3, 0}, /* (0.375-0.500] */ - { 4, 0}, /* (0.500-0.625] */ - { 5, 0}, /* (0.625-0.750] */ - { 6, 0}, /* (0.750-0.875] */ - { 7, 1}, /* (0.875-1.000] */ - { 8, 0}, /* (1.000-1.125] */ - { 9, 0}, /* (1.125-1.250] */ - {10, 0}, /* (1.250-1.375] */ - {11, 0}, /* (1.375-1.500] */ - {12, 0}, /* (1.500-1.625] */ - {13, 0}, /* (1.625-1.750] */ - {14, 0}, /* (1.750-1.875] */ - {15, 1}, /* (1.875-2.000] */ - {16, 0}, /* (2.000-2.125] */ ++ {0, 0}, /* (0.000-0.125] */ ++ {1, 0}, /* (0.125-0.250] */ ++ {2, 0}, /* (0.250-0.375] */ ++ {3, 0}, /* (0.375-0.500] */ ++ {4, 0}, /* (0.500-0.625] */ ++ {5, 0}, /* (0.625-0.750] */ ++ {6, 0}, /* (0.750-0.875] */ ++ {7, 1}, /* (0.875-1.000] */ ++ {8, 0}, /* (1.000-1.125] */ ++ {9, 0}, /* (1.125-1.250] */ ++ {10, 0}, /* (1.250-1.375] */ ++ {11, 0}, /* (1.375-1.500] */ ++ {12, 0}, /* (1.500-1.625] */ ++ {13, 0}, /* (1.625-1.750] */ ++ {14, 0}, /* (1.750-1.875] */ ++ {15, 1}, /* (1.875-2.000] */ ++ {16, 0}, /* (2.000-2.125] */ + }; + + for (size_t i = 0; i < STATIC_ARRAY_SIZE(bucket_cases); i++) { + size_t index = bucket_cases[i].index; + EXPECT_EQ_INT(bucket_cases[i].want, peek->histogram[index]); + } + + struct { + cdtime_t lower_bound; + cdtime_t upper_bound; + double want; + } cases[] = { - { // bucket 6 is zero - DOUBLE_TO_CDTIME_T_STATIC(0.750), - DOUBLE_TO_CDTIME_T_STATIC(0.875), - 0.00, - }, - { // bucket 7 contains the t=1 update - DOUBLE_TO_CDTIME_T_STATIC(0.875), - DOUBLE_TO_CDTIME_T_STATIC(1.000), - 1.00, - }, - { // range: bucket 7 - bucket 15; contains the t=1 and t=2 updates - DOUBLE_TO_CDTIME_T_STATIC(0.875), - DOUBLE_TO_CDTIME_T_STATIC(2.000), - 2.00, - }, - { // lower bucket is only partially applied - DOUBLE_TO_CDTIME_T_STATIC(0.875 + (0.125 / 4)), - DOUBLE_TO_CDTIME_T_STATIC(2.000), - 1.75, - }, - { // upper bucket is only partially applied - DOUBLE_TO_CDTIME_T_STATIC(0.875), - DOUBLE_TO_CDTIME_T_STATIC(2.000 - (0.125 / 4)), - 1.75, - }, - { // both buckets are only partially applied - DOUBLE_TO_CDTIME_T_STATIC(0.875 + (0.125 / 4)), - DOUBLE_TO_CDTIME_T_STATIC(2.000 - (0.125 / 4)), - 1.50, - }, - { // lower bound is unspecified - 0, - DOUBLE_TO_CDTIME_T_STATIC(2.000), - 2.00, - }, - { // upper bound is unspecified - DOUBLE_TO_CDTIME_T_STATIC(125.000 - 0.125), - 0, - 1.00, - }, - { // overflow test: upper >> longest latency - DOUBLE_TO_CDTIME_T_STATIC(1.000), - DOUBLE_TO_CDTIME_T_STATIC(999999), - 124.00, - }, - { // overflow test: lower > longest latency - DOUBLE_TO_CDTIME_T_STATIC(130), - 0, - 0.00, - }, - { // lower > upper => error - DOUBLE_TO_CDTIME_T_STATIC(10), - DOUBLE_TO_CDTIME_T_STATIC(9), - NAN, - }, - { // lower == upper => zero - DOUBLE_TO_CDTIME_T_STATIC(9), - DOUBLE_TO_CDTIME_T_STATIC(9), - 0.00, - }, ++ { ++ // bucket 6 is zero ++ DOUBLE_TO_CDTIME_T_STATIC(0.750), DOUBLE_TO_CDTIME_T_STATIC(0.875), ++ 0.00, ++ }, ++ { ++ // bucket 7 contains the t=1 update ++ DOUBLE_TO_CDTIME_T_STATIC(0.875), DOUBLE_TO_CDTIME_T_STATIC(1.000), ++ 1.00, ++ }, ++ { ++ // range: bucket 7 - bucket 15; contains the t=1 and t=2 updates ++ DOUBLE_TO_CDTIME_T_STATIC(0.875), DOUBLE_TO_CDTIME_T_STATIC(2.000), ++ 2.00, ++ }, ++ { ++ // lower bucket is only partially applied ++ DOUBLE_TO_CDTIME_T_STATIC(0.875 + (0.125 / 4)), ++ DOUBLE_TO_CDTIME_T_STATIC(2.000), 1.75, ++ }, ++ { ++ // upper bucket is only partially applied ++ DOUBLE_TO_CDTIME_T_STATIC(0.875), ++ DOUBLE_TO_CDTIME_T_STATIC(2.000 - (0.125 / 4)), 1.75, ++ }, ++ { ++ // both buckets are only partially applied ++ DOUBLE_TO_CDTIME_T_STATIC(0.875 + (0.125 / 4)), ++ DOUBLE_TO_CDTIME_T_STATIC(2.000 - (0.125 / 4)), 1.50, ++ }, ++ { ++ // lower bound is unspecified ++ 0, DOUBLE_TO_CDTIME_T_STATIC(2.000), 2.00, ++ }, ++ { ++ // upper bound is unspecified ++ DOUBLE_TO_CDTIME_T_STATIC(125.000 - 0.125), 0, 1.00, ++ }, ++ { ++ // overflow test: upper >> longest latency ++ DOUBLE_TO_CDTIME_T_STATIC(1.000), DOUBLE_TO_CDTIME_T_STATIC(999999), ++ 124.00, ++ }, ++ { ++ // overflow test: lower > longest latency ++ DOUBLE_TO_CDTIME_T_STATIC(130), 0, 0.00, ++ }, ++ { ++ // lower > upper => error ++ DOUBLE_TO_CDTIME_T_STATIC(10), DOUBLE_TO_CDTIME_T_STATIC(9), NAN, ++ }, ++ { ++ // lower == upper => zero ++ DOUBLE_TO_CDTIME_T_STATIC(9), DOUBLE_TO_CDTIME_T_STATIC(9), 0.00, ++ }, + }; + + for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) { + cdtime_t now = peek->start_time + TIME_T_TO_CDTIME_T(1); - EXPECT_EQ_DOUBLE (cases[i].want, - latency_counter_get_rate (l, cases[i].lower_bound, cases[i].upper_bound, now)); ++ EXPECT_EQ_DOUBLE(cases[i].want, ++ latency_counter_get_rate(l, cases[i].lower_bound, ++ cases[i].upper_bound, now)); + } + - latency_counter_destroy (l); ++ latency_counter_destroy(l); + return 0; +} + - int main (void) - { + int main(void) { RUN_TEST(simple); RUN_TEST(percentile); + RUN_TEST(get_rate); END_TEST; }