From 86928d3feaa0ba8f85dc3cbe0d3c34219d201a33 Mon Sep 17 00:00:00 2001 From: Paul Sadauskas Date: Tue, 7 Jul 2009 18:38:36 +0200 Subject: [PATCH] http plugin: Start in http plugin that can output csv to stdout --- configure.in | 1 + src/Makefile.am | 8 ++ src/http.c | 243 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 252 insertions(+) create mode 100644 src/http.c diff --git a/configure.in b/configure.in index af790d15..fcb39538 100644 --- a/configure.in +++ b/configure.in @@ -3698,6 +3698,7 @@ AC_PLUGIN([couchdb], [$plugin_couchdb], [CouchDB statistics]) AC_PLUGIN([cpufreq], [$plugin_cpufreq], [CPU frequency statistics]) AC_PLUGIN([cpu], [$plugin_cpu], [CPU usage statistics]) AC_PLUGIN([csv], [yes], [CSV output plugin]) +AC_PLUGIN([http], [yes], [HTTP output plugin]) AC_PLUGIN([curl], [$with_libcurl], [CURL generic web statistics]) AC_PLUGIN([dbi], [$with_libdbi], [General database statistics]) AC_PLUGIN([df], [$plugin_df], [Filesystem usage statistics]) diff --git a/src/Makefile.am b/src/Makefile.am index 0ca68095..1fd3bba9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -224,6 +224,14 @@ collectd_LDADD += "-dlopen" csv.la collectd_DEPENDENCIES += csv.la endif +if BUILD_PLUGIN_HTTP +pkglib_LTLIBRARIES += http.la +http_la_SOURCES = http.c +http_la_LDFLAGS = -module -avoid-version +collectd_LDADD += "-dlopen" http.la +collectd_DEPENDENCIES += http.la +endif + if BUILD_PLUGIN_CURL pkglib_LTLIBRARIES += curl.la curl_la_SOURCES = curl.c diff --git a/src/http.c b/src/http.c new file mode 100644 index 00000000..6c0a296e --- /dev/null +++ b/src/http.c @@ -0,0 +1,243 @@ +/** + * collectd - src/http.c + * Copyright (C) 2007-2009 Florian octo Forster + * Copyright (C) 2009 Doug MacEachern + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; only version 2 of the License is applicable. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: + * Florian octo Forster + * Doug MacEachern + **/ + +#include "collectd.h" +#include "plugin.h" +#include "common.h" +#include "utils_cache.h" +#include "utils_parse_option.h" + +/* + * Private variables + */ +static const char *config_keys[] = +{ + "Location", +}; +static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); + +static char *location = NULL; + +static int value_list_to_string (char *buffer, int buffer_len, + const data_set_t *ds, const value_list_t *vl) +{ + int offset = 0; + int status; + int i; + gauge_t *rates = NULL; + + assert (0 == strcmp (ds->type, vl->type)); + + memset (buffer, '\0', buffer_len); + + for (i = 0; i < ds->ds_num; i++) + { + if (i > 0) + { + status = ssnprintf (buffer + offset, + buffer_len - offset, + ":"); + offset += status; + } + 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 (rates == NULL) + rates = uc_get_rate (ds, vl); + if (rates == NULL) + { + WARNING ("http plugin: " + "uc_get_rate failed."); + return (-1); + } + if (isnan(rates[i])) + { + /* dont output */ + 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 */ + +static int value_list_to_timestamp (char *buffer, int buffer_len, + const data_set_t *ds, const value_list_t *vl) +{ + int offset = 0; + int status; + + 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; + + return (0); +} /* int value_list_to_timestamp */ + +static int value_list_to_metric_name (char *buffer, int buffer_len, + const data_set_t *ds, const value_list_t *vl) +{ + int offset = 0; + int status; + + assert (0 == strcmp (ds->type, vl->type)); + + /* hostname */ + status = ssnprintf (buffer + offset, buffer_len - offset, + "%s", vl->host); + if ((status < 1) || (status >= buffer_len - offset)) + return (-1); + offset += status; + + /* plugin */ + status = ssnprintf (buffer + offset, buffer_len - offset, + ",%s", vl->plugin); + if ((status < 1) || (status >= buffer_len - offset)) + return (-1); + offset += status; + + /* plugin_instance */ + if (strlen (vl->plugin_instance) > 0) + { + status = ssnprintf (buffer + offset, buffer_len - offset, + ",%s", vl->plugin_instance); + if ((status < 1) || (status >= buffer_len - offset)) + return (-1); + offset += status; + } + + /* type (if its the same as plugin, don't bother repeating it */ + if (0 != strcmp (vl->type, vl->plugin)) + { + status = ssnprintf (buffer + offset, buffer_len - offset, + ",%s", vl->type); + if ((status < 1) || (status >= buffer_len - offset)) + return (-1); + offset += status; + } + + /* type_instance */ + if (strlen (vl->type_instance) > 0) + { + status = ssnprintf (buffer + offset, buffer_len - offset, + ",%s", vl->type_instance); + if ((status < 1) || (status >= buffer_len - offset)) + return (-1); + offset += status; + } + + return (0); +} /* int value_list_to_metric_name */ + +static int http_config (const char *key, const char *value) +{ + if (strcasecmp ("Location", key) == 0) + { + if (location != NULL) + free (location); + location = strdup (value); + if (location != NULL) + { + int len = strlen (location); + while ((len > 0) && (location[len - 1] == '/')) + { + len--; + location[len] = '\0'; + } + if (len <= 0) + { + free (location); + location = NULL; + } + } + } + else + { + return (-1); + } + return (0); +} /* int http_config */ + +static int http_write (const data_set_t *ds, const value_list_t *vl, + user_data_t __attribute__((unused)) *user_data) +{ + char metric_name[512]; + char values[512]; + char timestamp[512]; + + if (0 != strcmp (ds->type, vl->type)) { + ERROR ("http plugin: DS type does not match value list type"); + return -1; + } + + if (value_list_to_metric_name (metric_name, sizeof (metric_name), ds, vl) != 0) + return (-1); + + DEBUG ("http plugin: http_write: metric_name = %s;", metric_name); + + if (value_list_to_timestamp (timestamp, sizeof (timestamp), ds, vl) != 0) + return (-1); + + if (value_list_to_string (values, sizeof (values), ds, vl) != 0) + return (-1); + + escape_string (metric_name, sizeof (metric_name)); + + fprintf (stdout, + "\"%s\",%s,%s\n", + metric_name, timestamp, values); + return (0); + +} /* int http_write */ + +void module_register (void) +{ + plugin_register_config ("http", http_config, + config_keys, config_keys_num); + plugin_register_write ("http", http_write, /* user_data = */ NULL); +} /* void module_register */ -- 2.30.2