X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fwrite_sensu.c;h=d764d2605351cefd716547a055d09437cac39ccb;hb=41288c6a9ed050b41ad47184aa1b53668c3588cc;hp=475354c83bb0110c89b81dde3e85cb33a3203953;hpb=50345eec33951b964e2829e83c30399b71f2baba;p=collectd.git diff --git a/src/write_sensu.c b/src/write_sensu.c index 475354c8..d764d260 100644 --- a/src/write_sensu.c +++ b/src/write_sensu.c @@ -27,21 +27,69 @@ #define _GNU_SOURCE #include "collectd.h" + #include "plugin.h" #include "common.h" -#include "configfile.h" #include "utils_cache.h" #include #include #include #include -#include #include #include #define SENSU_HOST "localhost" #define SENSU_PORT "3030" +#ifdef HAVE_ASPRINTF +#define my_asprintf asprintf +#define my_vasprintf vasprintf +#else +/* + * asprintf() is available from Solaris 10 update 11. + * For older versions, use asprintf() portable implementation from + * https://github.com/littlstar/asprintf.c/blob/master/ + * copyright (c) 2014 joseph werle under MIT license. + */ + +static int my_vasprintf(char **str, const char *fmt, va_list args) { + int size = 0; + va_list tmpa; + // copy + va_copy(tmpa, args); + // apply variadic arguments to + // sprintf with format to get size + size = vsnprintf(NULL, size, fmt, tmpa); + // toss args + va_end(tmpa); + // return -1 to be compliant if + // size is less than 0 + if (size < 0) { return -1; } + // alloc with size plus 1 for `\0' + *str = (char *) malloc(size + 1); + // return -1 to be compliant + // if pointer is `NULL' + if (NULL == *str) { return -1; } + // format string with original + // variadic arguments and set new size + size = vsprintf(*str, fmt, args); + return size; +} + +static int my_asprintf(char **str, const char *fmt, ...) { + int size = 0; + va_list args; + // init variadic argumens + va_start(args, fmt); + // format and get size + size = my_vasprintf(str, fmt, args); + // toss args + va_end(args); + return size; +} + +#endif + struct str_list { int nb_strs; char **strs; @@ -95,8 +143,7 @@ static int add_str_to_list(struct str_list *strs, static void free_str_list(struct str_list *strs) /* {{{ */ { - int i; - for (i=0; inb_strs; i++) + for (int i=0; inb_strs; i++) free(strs->strs[i]); free(strs->strs); } @@ -105,25 +152,24 @@ static void free_str_list(struct str_list *strs) /* {{{ */ static int sensu_connect(struct sensu_host *host) /* {{{ */ { int e; - struct addrinfo *ai, hints; char const *node; char const *service; // Resolve the target if we haven't done already if (!(host->flags & F_READY)) { - memset(&hints, 0, sizeof(hints)); memset(&service, 0, sizeof(service)); host->res = NULL; - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; -#ifdef AI_ADDRCONFIG - hints.ai_flags |= AI_ADDRCONFIG; -#endif node = (host->node != NULL) ? host->node : SENSU_HOST; service = (host->service != NULL) ? host->service : SENSU_PORT; - if ((e = getaddrinfo(node, service, &hints, &(host->res))) != 0) { + struct addrinfo ai_hints = { + .ai_family = AF_INET, + .ai_flags = AI_ADDRCONFIG, + .ai_socktype = SOCK_STREAM + }; + + if ((e = getaddrinfo(node, service, &ai_hints, &(host->res))) != 0) { ERROR("write_sensu plugin: Unable to resolve host \"%s\": %s", node, gai_strerror(e)); return -1; @@ -135,7 +181,7 @@ static int sensu_connect(struct sensu_host *host) /* {{{ */ struct linger so_linger; host->s = -1; - for (ai = host->res; ai != NULL; ai = ai->ai_next) { + for (struct addrinfo *ai = host->res; ai != NULL; ai = ai->ai_next) { // create the socket if ((host->s = socket(ai->ai_family, ai->ai_socktype, @@ -149,6 +195,8 @@ static int sensu_connect(struct sensu_host *host) /* {{{ */ if (setsockopt(host->s, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger) != 0) WARNING("write_sensu plugin: failed to set socket close() lingering"); + set_sock_opts(host->s); + // connect the socket if (connect(host->s, ai->ai_addr, ai->ai_addrlen) != 0) { close(host->s); @@ -179,7 +227,6 @@ static char *build_json_str_list(const char *tag, struct str_list const *list) / int res; char *ret_str = NULL; char *temp_str; - int i; if (list->nb_strs == 0) { ret_str = malloc(sizeof(char)); if (ret_str == NULL) { @@ -189,14 +236,14 @@ static char *build_json_str_list(const char *tag, struct str_list const *list) / ret_str[0] = '\0'; } - res = asprintf(&temp_str, "\"%s\": [\"%s\"", tag, list->strs[0]); + res = my_asprintf(&temp_str, "\"%s\": [\"%s\"", tag, list->strs[0]); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); free(ret_str); return NULL; } - for (i=1; inb_strs; i++) { - res = asprintf(&ret_str, "%s, \"%s\"", temp_str, list->strs[i]); + for (int i=1; inb_strs; i++) { + res = my_asprintf(&ret_str, "%s, \"%s\"", temp_str, list->strs[i]); free(temp_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -204,7 +251,7 @@ static char *build_json_str_list(const char *tag, struct str_list const *list) / } temp_str = ret_str; } - res = asprintf(&ret_str, "%s]", temp_str); + res = my_asprintf(&ret_str, "%s]", temp_str); free(temp_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -261,9 +308,8 @@ static int sensu_format_name2(char *ret, int ret_len, static void in_place_replace_sensu_name_reserved(char *orig_name) /* {{{ */ { - int i; int len=strlen(orig_name); - for (i=0; iplugin); + res = my_asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, vl->plugin); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -326,7 +371,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ ret_str = temp_str; // incorporate the plugin type - res = asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, vl->type); + res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, vl->type); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -336,7 +381,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ // incorporate the plugin instance if any if (vl->plugin_instance[0] != 0) { - res = asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", ret_str, vl->plugin_instance); + res = my_asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", ret_str, vl->plugin_instance); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -347,7 +392,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ // incorporate the plugin type instance if any if (vl->type_instance[0] != 0) { - res = asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", ret_str, vl->type_instance); + res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", ret_str, vl->type_instance); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -360,7 +405,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL)) { char ds_type[DATA_MAX_NAME_LEN]; ssnprintf (ds_type, sizeof (ds_type), "%s:rate", DS_TYPE_TO_STRING(ds->ds[index].type)); - res = asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, ds_type); + res = my_asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, ds_type); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -368,7 +413,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ } ret_str = temp_str; } else { - res = asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, DS_TYPE_TO_STRING(ds->ds[index].type)); + res = my_asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, DS_TYPE_TO_STRING(ds->ds[index].type)); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -378,7 +423,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ } // incorporate the data source name - res = asprintf(&temp_str, "%s, \"collectd_data_source_name\": \"%s\"", ret_str, ds->ds[index].name); + res = my_asprintf(&temp_str, "%s, \"collectd_data_source_name\": \"%s\"", ret_str, ds->ds[index].name); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -390,7 +435,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ { char ds_index[DATA_MAX_NAME_LEN]; ssnprintf (ds_index, sizeof (ds_index), "%zu", index); - res = asprintf(&temp_str, "%s, \"collectd_data_source_index\": %s", ret_str, ds_index); + res = my_asprintf(&temp_str, "%s, \"collectd_data_source_index\": %s", ret_str, ds_index); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -400,8 +445,8 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ } // add key value attributes from config if any - for (i = 0; i < sensu_attrs_num; i += 2) { - res = asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], sensu_attrs[i+1]); + for (size_t i = 0; i < sensu_attrs_num; i += 2) { + res = my_asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], sensu_attrs[i+1]); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -412,7 +457,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ // incorporate sensu tags from config if any if ((sensu_tags != NULL) && (strlen(sensu_tags) != 0)) { - res = asprintf(&temp_str, "%s, %s", ret_str, sensu_tags); + res = my_asprintf(&temp_str, "%s, %s", ret_str, sensu_tags); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -423,14 +468,14 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ // calculate the value and set to a string if (ds->ds[index].type == DS_TYPE_GAUGE) { - res = asprintf(&value_str, GAUGE_FORMAT, vl->values[index].gauge); + res = my_asprintf(&value_str, GAUGE_FORMAT, vl->values[index].gauge); if (res == -1) { free(ret_str); ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } } else if (rates != NULL) { - res = asprintf(&value_str, GAUGE_FORMAT, rates[index]); + res = my_asprintf(&value_str, GAUGE_FORMAT, rates[index]); if (res == -1) { free(ret_str); ERROR("write_sensu plugin: Unable to alloc memory"); @@ -438,7 +483,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ } } else { if (ds->ds[index].type == DS_TYPE_DERIVE) { - res = asprintf(&value_str, "%"PRIi64, vl->values[index].derive); + res = my_asprintf(&value_str, "%"PRIi64, vl->values[index].derive); if (res == -1) { free(ret_str); ERROR("write_sensu plugin: Unable to alloc memory"); @@ -446,7 +491,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ } } else if (ds->ds[index].type == DS_TYPE_ABSOLUTE) { - res = asprintf(&value_str, "%"PRIu64, vl->values[index].absolute); + res = my_asprintf(&value_str, "%"PRIu64, vl->values[index].absolute); if (res == -1) { free(ret_str); ERROR("write_sensu plugin: Unable to alloc memory"); @@ -454,7 +499,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ } } else { - res = asprintf(&value_str, "%llu", vl->values[index].counter); + res = my_asprintf(&value_str, "%llu", vl->values[index].counter); if (res == -1) { free(ret_str); ERROR("write_sensu plugin: Unable to alloc memory"); @@ -486,7 +531,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ in_place_replace_sensu_name_reserved(service_buffer); // finalize the buffer by setting the output and closing curly bracket - res = asprintf(&temp_str, "%s, \"output\": \"%s %s %ld\"}\n", ret_str, service_buffer, value_str, CDTIME_T_TO_TIME_T(vl->time)); + res = my_asprintf(&temp_str, "%s, \"output\": \"%s %s %lld\"}\n",ret_str, service_buffer, value_str, (long long)CDTIME_T_TO_TIME_T(vl->time)); free(ret_str); free(value_str); if (res == -1) { @@ -591,7 +636,6 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ { char service_buffer[6 * DATA_MAX_NAME_LEN]; char const *severity; - notification_meta_t *meta; char *ret_str; char *temp_str; int status; @@ -615,7 +659,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ severity = "UNKNOWN"; status = 3; } - res = asprintf(&temp_str, "{\"status\": %d", status); + res = my_asprintf(&temp_str, "{\"status\": %d", status); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; @@ -623,7 +667,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ ret_str = temp_str; // incorporate the timestamp - res = asprintf(&temp_str, "%s, \"timestamp\": %ld", ret_str, CDTIME_T_TO_TIME_T(n->time)); + res = my_asprintf(&temp_str, "%s, \"timestamp\": %lld", ret_str, (long long)CDTIME_T_TO_TIME_T(n->time)); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -639,7 +683,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ } // incorporate the handlers if (strlen(handlers_str) != 0) { - res = asprintf(&temp_str, "%s, %s", ret_str, handlers_str); + res = my_asprintf(&temp_str, "%s, %s", ret_str, handlers_str); free(ret_str); free(handlers_str); if (res == -1) { @@ -653,7 +697,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ // incorporate the plugin name information if any if (n->plugin[0] != 0) { - res = asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, n->plugin); + res = my_asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, n->plugin); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -664,7 +708,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ // incorporate the plugin type if any if (n->type[0] != 0) { - res = asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, n->type); + res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, n->type); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -675,7 +719,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ // incorporate the plugin instance if any if (n->plugin_instance[0] != 0) { - res = asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", ret_str, n->plugin_instance); + res = my_asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", ret_str, n->plugin_instance); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -686,7 +730,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ // incorporate the plugin type instance if any if (n->type_instance[0] != 0) { - res = asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", ret_str, n->type_instance); + res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", ret_str, n->type_instance); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -697,7 +741,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ // add key value attributes from config if any for (i = 0; i < sensu_attrs_num; i += 2) { - res = asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], sensu_attrs[i+1]); + res = my_asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], sensu_attrs[i+1]); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -708,7 +752,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ // incorporate sensu tags from config if any if ((sensu_tags != NULL) && (strlen(sensu_tags) != 0)) { - res = asprintf(&temp_str, "%s, %s", ret_str, sensu_tags); + res = my_asprintf(&temp_str, "%s, %s", ret_str, sensu_tags); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -723,7 +767,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ n->type, n->type_instance, host->separator); // replace sensu event name chars that are considered illegal in_place_replace_sensu_name_reserved(service_buffer); - res = asprintf(&temp_str, "%s, \"name\": \"%s\"", ret_str, &service_buffer[1]); + res = my_asprintf(&temp_str, "%s, \"name\": \"%s\"", ret_str, &service_buffer[1]); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -739,7 +783,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ free(ret_str); return NULL; } - res = asprintf(&temp_str, "%s, \"output\": \"%s - %s\"", ret_str, severity, msg); + res = my_asprintf(&temp_str, "%s, \"output\": \"%s - %s\"", ret_str, severity, msg); free(ret_str); free(msg); if (res == -1) { @@ -750,9 +794,9 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ } // Pull in values from threshold and add extra attributes - for (meta = n->meta; meta != NULL; meta = meta->next) { + for (notification_meta_t *meta = n->meta; meta != NULL; meta = meta->next) { if (strcasecmp("CurrentValue", meta->name) == 0 && meta->type == NM_TYPE_DOUBLE) { - res = asprintf(&temp_str, "%s, \"current_value\": \"%.8f\"", ret_str, meta->nm_value.nm_double); + res = my_asprintf(&temp_str, "%s, \"current_value\": \"%.8f\"", ret_str, meta->nm_value.nm_double); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -761,7 +805,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ ret_str = temp_str; } if (meta->type == NM_TYPE_STRING) { - res = asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, meta->name, meta->nm_value.nm_string); + res = my_asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, meta->name, meta->nm_value.nm_string); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -772,7 +816,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ } // close the curly bracket - res = asprintf(&temp_str, "%s}\n", ret_str); + res = my_asprintf(&temp_str, "%s}\n", ret_str); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -839,7 +883,6 @@ static int sensu_write(const data_set_t *ds, /* {{{ */ int statuses[vl->values_len]; struct sensu_host *host = ud->data; gauge_t *rates = NULL; - size_t i; char *msg; pthread_mutex_lock(&host->lock); @@ -853,7 +896,7 @@ static int sensu_write(const data_set_t *ds, /* {{{ */ return -1; } } - for (i = 0; i < vl->values_len; i++) { + for (size_t i = 0; i < vl->values_len; i++) { msg = sensu_value_to_json(host, ds, vl, (int) i, rates, statuses[i]); if (msg == NULL) { sfree(rates); @@ -933,10 +976,8 @@ static int sensu_config_node(oconfig_item_t *ci) /* {{{ */ { struct sensu_host *host = NULL; int status = 0; - int i; oconfig_item_t *child; char callback_name[DATA_MAX_NAME_LEN]; - user_data_t ud; if ((host = calloc(1, sizeof(*host))) == NULL) { ERROR("write_sensu plugin: calloc failed."); @@ -968,7 +1009,7 @@ static int sensu_config_node(oconfig_item_t *ci) /* {{{ */ return -1; } - for (i = 0; i < ci->children_num; i++) { + for (int i = 0; i < ci->children_num; i++) { child = &ci->children[i]; status = 0; @@ -1066,8 +1107,11 @@ static int sensu_config_node(oconfig_item_t *ci) /* {{{ */ } ssnprintf(callback_name, sizeof(callback_name), "write_sensu/%s", host->name); - ud.data = host; - ud.free_func = sensu_free; + + user_data_t ud = { + .data = host, + .free_func = sensu_free + }; pthread_mutex_lock(&host->lock); @@ -1109,7 +1153,6 @@ static int sensu_config_node(oconfig_item_t *ci) /* {{{ */ static int sensu_config(oconfig_item_t *ci) /* {{{ */ { - int i; oconfig_item_t *child; int status; struct str_list sensu_tags_arr; @@ -1117,7 +1160,7 @@ static int sensu_config(oconfig_item_t *ci) /* {{{ */ sensu_tags_arr.nb_strs = 0; sensu_tags_arr.strs = NULL; - for (i = 0; i < ci->children_num; i++) { + for (int i = 0; i < ci->children_num; i++) { child = &ci->children[i]; if (strcasecmp("Node", child->key) == 0) {