X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fwrite_http.c;h=f14636bde5ec79e355aa2166e152992f8b651cfd;hb=1a991a476428fa1d72c8658b2dc74efea9b622fd;hp=b17a3422e1153f15455bd0e1a5ba2a9930d5b6f9;hpb=56bcb4af5888121cef3a3c6bab1084bf225aa012;p=collectd.git diff --git a/src/write_http.c b/src/write_http.c index b17a3422..f14636bd 100644 --- a/src/write_http.c +++ b/src/write_http.c @@ -28,6 +28,7 @@ #include "common.h" #include "utils_cache.h" #include "utils_parse_option.h" +#include "utils_format_json.h" #if HAVE_PTHREAD_H # include @@ -49,6 +50,10 @@ struct wh_callback_s int verify_host; char *cacert; +#define WH_FORMAT_COMMAND 0 +#define WH_FORMAT_JSON 1 + int format; + CURL *curl; char curl_errbuf[CURL_ERROR_SIZE]; @@ -67,6 +72,13 @@ static void wh_reset_buffer (wh_callback_t *cb) /* {{{ */ cb->send_buffer_free = sizeof (cb->send_buffer); cb->send_buffer_fill = 0; cb->send_buffer_init_time = time (NULL); + + if (cb->format == WH_FORMAT_JSON) + { + format_json_initialize (cb->send_buffer, + &cb->send_buffer_fill, + &cb->send_buffer_free); + } } /* }}} wh_reset_buffer */ static int wh_send_buffer (wh_callback_t *cb) /* {{{ */ @@ -78,7 +90,7 @@ static int wh_send_buffer (wh_callback_t *cb) /* {{{ */ if (status != 0) { ERROR ("write_http plugin: curl_easy_perform failed with " - "staus %i: %s", + "status %i: %s", status, cb->curl_errbuf); } return (status); @@ -102,7 +114,11 @@ static int wh_callback_init (wh_callback_t *cb) /* {{{ */ headers = NULL; headers = curl_slist_append (headers, "Accept: */*"); - headers = curl_slist_append (headers, "Content-Type: text/plain"); + if (cb->format == WH_FORMAT_JSON) + headers = curl_slist_append (headers, "Content-Type: application/json"); + else + headers = curl_slist_append (headers, "Content-Type: text/plain"); + headers = curl_slist_append (headers, "Expect:"); curl_easy_setopt (cb->curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt (cb->curl, CURLOPT_ERRORBUFFER, cb->curl_errbuf); @@ -157,14 +173,46 @@ static int wh_flush_nolock (int timeout, wh_callback_t *cb) /* {{{ */ return (0); } - if (cb->send_buffer_fill <= 0) + if (cb->format == WH_FORMAT_COMMAND) { - cb->send_buffer_init_time = time (NULL); - return (0); + if (cb->send_buffer_fill <= 0) + { + cb->send_buffer_init_time = time (NULL); + return (0); + } + + status = wh_send_buffer (cb); + wh_reset_buffer (cb); } + else if (cb->format == WH_FORMAT_JSON) + { + if (cb->send_buffer_fill <= 2) + { + cb->send_buffer_init_time = time (NULL); + return (0); + } - status = wh_send_buffer (cb); - wh_reset_buffer (cb); + status = format_json_finalize (cb->send_buffer, + &cb->send_buffer_fill, + &cb->send_buffer_free); + if (status != 0) + { + ERROR ("write_http: wh_flush_nolock: " + "format_json_finalize failed."); + wh_reset_buffer (cb); + return (status); + } + + status = wh_send_buffer (cb); + wh_reset_buffer (cb); + } + else + { + ERROR ("write_http: wh_flush_nolock: " + "Unknown format: %i", + cb->format); + return (-1); + } return (status); } /* }}} wh_flush_nolock */ @@ -303,7 +351,7 @@ static int wh_write_command (const data_set_t *ds, const value_list_t *vl, /* {{ } command_len = (size_t) ssnprintf (command, sizeof (command), - "PUTVAL %s interval=%i %s\n", + "PUTVAL %s interval=%i %s\r\n", key, vl->interval, values); if (command_len >= sizeof (command)) { ERROR ("write_http plugin: Command buffer too small: " @@ -354,6 +402,60 @@ static int wh_write_command (const data_set_t *ds, const value_list_t *vl, /* {{ return (0); } /* }}} int wh_write_command */ +static int wh_write_json (const data_set_t *ds, const value_list_t *vl, /* {{{ */ + wh_callback_t *cb) +{ + int status; + + pthread_mutex_lock (&cb->send_lock); + + if (cb->curl == NULL) + { + status = wh_callback_init (cb); + if (status != 0) + { + ERROR ("write_http plugin: wh_callback_init failed."); + pthread_mutex_unlock (&cb->send_lock); + return (-1); + } + } + + status = format_json_value_list (cb->send_buffer, + &cb->send_buffer_fill, + &cb->send_buffer_free, + ds, vl); + if (status == (-ENOMEM)) + { + status = wh_flush_nolock (/* timeout = */ -1, cb); + if (status != 0) + { + wh_reset_buffer (cb); + pthread_mutex_unlock (&cb->send_lock); + return (status); + } + + status = format_json_value_list (cb->send_buffer, + &cb->send_buffer_fill, + &cb->send_buffer_free, + ds, vl); + } + if (status != 0) + { + pthread_mutex_unlock (&cb->send_lock); + return (status); + } + + DEBUG ("write_http plugin: <%s> buffer %zu/%zu (%g%%)", + cb->location, + cb->send_buffer_fill, sizeof (cb->send_buffer), + 100.0 * ((double) cb->send_buffer_fill) / ((double) sizeof (cb->send_buffer))); + + /* Check if we have enough space for this command. */ + pthread_mutex_unlock (&cb->send_lock); + + return (0); +} /* }}} int wh_write_json */ + static int wh_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */ user_data_t *user_data) { @@ -365,7 +467,11 @@ static int wh_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */ cb = user_data->data; - status = wh_write_command (ds, vl, cb); + if (cb->format == WH_FORMAT_JSON) + status = wh_write_json (ds, vl, cb); + else + status = wh_write_command (ds, vl, cb); + return (status); } /* }}} int wh_write */ @@ -410,6 +516,34 @@ static int config_set_boolean (int *dest, oconfig_item_t *ci) /* {{{ */ return (0); } /* }}} int config_set_boolean */ +static int config_set_format (wh_callback_t *cb, /* {{{ */ + oconfig_item_t *ci) +{ + char *string; + + if ((ci->values_num != 1) + || (ci->values[0].type != OCONFIG_TYPE_STRING)) + { + WARNING ("write_http plugin: The `%s' config option " + "needs exactly one string argument.", ci->key); + return (-1); + } + + string = ci->values[0].value.string; + if (strcasecmp ("Command", string) == 0) + cb->format = WH_FORMAT_COMMAND; + else if (strcasecmp ("JSON", string) == 0) + cb->format = WH_FORMAT_JSON; + else + { + ERROR ("write_http plugin: Invalid format string: %s", + string); + return (-1); + } + + return (0); +} /* }}} int config_set_string */ + static int wh_config_url (oconfig_item_t *ci) /* {{{ */ { wh_callback_t *cb; @@ -430,6 +564,7 @@ static int wh_config_url (oconfig_item_t *ci) /* {{{ */ cb->verify_peer = 1; cb->verify_host = 1; cb->cacert = NULL; + cb->format = WH_FORMAT_COMMAND; cb->curl = NULL; pthread_mutex_init (&cb->send_lock, /* attr = */ NULL); @@ -452,6 +587,8 @@ static int wh_config_url (oconfig_item_t *ci) /* {{{ */ config_set_boolean (&cb->verify_host, child); else if (strcasecmp ("CACert", child->key) == 0) config_set_string (&cb->cacert, child); + else if (strcasecmp ("Format", child->key) == 0) + config_set_format (cb, child); else { ERROR ("write_http plugin: Invalid configuration "