X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fcsv.c;h=78037a940ca3981a150a3fa84055c490b83c955b;hb=633c3966f770e4d46651a2fe219a18d8a9907a9f;hp=a94b7001025419602961980efa993506e9755b33;hpb=d3fc6d0831a63af2e96300f488a9f8f5fc3183fb;p=collectd.git diff --git a/src/csv.c b/src/csv.c index a94b7001..e9a409d8 100644 --- a/src/csv.c +++ b/src/csv.c @@ -1,6 +1,7 @@ /** * collectd - src/csv.c - * Copyright (C) 2007 Florian octo Forster + * 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 @@ -16,13 +17,15 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: - * Florian octo Forster + * 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 @@ -36,6 +39,7 @@ static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); static char *datadir = NULL; static int store_rates = 0; +static int use_stdio = 0; static int value_list_to_string (char *buffer, int buffer_len, const data_set_t *ds, const value_list_t *vl) @@ -49,7 +53,8 @@ static int value_list_to_string (char *buffer, int buffer_len, memset (buffer, '\0', buffer_len); - status = ssnprintf (buffer, buffer_len, "%u", (unsigned int) vl->time); + status = ssnprintf (buffer, buffer_len, "%.3f", + CDTIME_T_TO_DOUBLE (vl->time)); if ((status < 1) || (status >= buffer_len)) return (-1); offset = status; @@ -57,37 +62,50 @@ static int value_list_to_string (char *buffer, int buffer_len, for (i = 0; i < ds->ds_num; i++) { if ((ds->ds[i].type != DS_TYPE_COUNTER) - && (ds->ds[i].type != DS_TYPE_GAUGE)) + && (ds->ds[i].type != DS_TYPE_GAUGE) + && (ds->ds[i].type != DS_TYPE_DERIVE) + && (ds->ds[i].type != DS_TYPE_ABSOLUTE)) return (-1); - if (ds->ds[i].type == DS_TYPE_COUNTER) + if (ds->ds[i].type == DS_TYPE_GAUGE) { - if (store_rates == 0) - { - status = ssnprintf (buffer + offset, - buffer_len - offset, - ",%llu", - vl->values[i].counter); - } - else /* if (store_rates == 1) */ + status = ssnprintf (buffer + offset, buffer_len - offset, + ",%lf", vl->values[i].gauge); + } + else if (store_rates != 0) + { + if (rates == NULL) + rates = uc_get_rate (ds, vl); + if (rates == NULL) { - if (rates == NULL) - rates = uc_get_rate (ds, vl); - if (rates == NULL) - { - WARNING ("csv plugin: " - "uc_get_rate failed."); - return (-1); - } - status = ssnprintf (buffer + offset, - buffer_len - offset, - ",%lf", rates[i]); + WARNING ("csv plugin: " + "uc_get_rate failed."); + return (-1); } + status = ssnprintf (buffer + offset, + buffer_len - offset, + ",%lf", rates[i]); } - else /* if (ds->ds[i].type == DS_TYPE_GAUGE) */ + else if (ds->ds[i].type == DS_TYPE_COUNTER) { - status = ssnprintf (buffer + offset, buffer_len - offset, - ",%lf", vl->values[i].gauge); + status = ssnprintf (buffer + offset, + buffer_len - offset, + ",%llu", + vl->values[i].counter); + } + else if (ds->ds[i].type == DS_TYPE_DERIVE) + { + status = ssnprintf (buffer + offset, + buffer_len - offset, + ",%"PRIi64, + vl->values[i].derive); + } + else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) + { + status = ssnprintf (buffer + offset, + buffer_len - offset, + ",%"PRIu64, + vl->values[i].absolute); } if ((status < 1) || (status >= (buffer_len - offset))) @@ -103,64 +121,62 @@ static int value_list_to_string (char *buffer, int buffer_len, return (0); } /* int value_list_to_string */ -static int value_list_to_filename (char *buffer, int buffer_len, - const data_set_t *ds, const value_list_t *vl) +static int value_list_to_filename (char *buffer, size_t buffer_size, + value_list_t const *vl) { - int offset = 0; int status; - assert (0 == strcmp (ds->type, vl->type)); + char *ptr = buffer; + size_t ptr_size = buffer_size; + time_t now; + struct tm struct_tm; if (datadir != NULL) { - status = ssnprintf (buffer + offset, buffer_len - offset, - "%s/", datadir); - if ((status < 1) || (status >= buffer_len - offset)) - return (-1); - offset += status; + size_t len = strlen (datadir) + 1; + + if (len >= ptr_size) + return (ENOBUFS); + + memcpy (ptr, datadir, len); + ptr[len-1] = '/'; + ptr_size -= len; + ptr += len; } - status = ssnprintf (buffer + offset, buffer_len - offset, - "%s/", vl->host); - if ((status < 1) || (status >= buffer_len - offset)) - return (-1); - offset += status; + status = FORMAT_VL (ptr, ptr_size, vl); + if (status != 0) + return (status); - if (strlen (vl->plugin_instance) > 0) - status = ssnprintf (buffer + offset, buffer_len - offset, - "%s-%s/", vl->plugin, vl->plugin_instance); - else - status = ssnprintf (buffer + offset, buffer_len - offset, - "%s/", vl->plugin); - if ((status < 1) || (status >= buffer_len - offset)) - return (-1); - offset += status; + /* Skip all the time formatting stuff when printing to STDOUT or + * STDERR. */ + if (use_stdio) + return (0); - if (strlen (vl->type_instance) > 0) - status = ssnprintf (buffer + offset, buffer_len - offset, - "%s-%s", vl->type, vl->type_instance); - else - status = ssnprintf (buffer + offset, buffer_len - offset, - "%s", vl->type); - if ((status < 1) || (status >= buffer_len - offset)) - return (-1); - offset += status; + ptr_size -= strlen (ptr); + ptr += strlen (ptr); + /* "-2013-07-12" => 11 bytes */ + if (ptr_size < 12) { - time_t now; - struct tm stm; + ERROR ("csv plugin: Buffer too small."); + return (ENOMEM); + } - /* TODO: Find a way to minimize the calls to `localtime_r', - * since they are pretty expensive.. */ - now = time (NULL); - if (localtime_r (&now, &stm) == NULL) - { - ERROR ("csv plugin: localtime_r failed"); - return (1); - } + /* TODO: Find a way to minimize the calls to `localtime_r', + * since they are pretty expensive.. */ + now = time (NULL); + if (localtime_r (&now, &struct_tm) == NULL) + { + ERROR ("csv plugin: localtime_r failed"); + return (-1); + } - strftime (buffer + offset, buffer_len - offset, - "-%Y-%m-%d", &stm); + status = strftime (ptr, ptr_size, "-%Y-%m-%d", &struct_tm); + if (status == 0) /* yep, it returns zero on error. */ + { + ERROR ("csv plugin: strftime failed"); + return (-1); } return (0); @@ -199,7 +215,20 @@ static int csv_config (const char *key, const char *value) if (strcasecmp ("DataDir", key) == 0) { if (datadir != NULL) + { free (datadir); + datadir = NULL; + } + if (strcasecmp ("stdout", value) == 0) + { + use_stdio = 1; + return (0); + } + else if (strcasecmp ("stderr", value) == 0) + { + use_stdio = 2; + return (0); + } datadir = strdup (value); if (datadir != NULL) { @@ -218,16 +247,10 @@ static int csv_config (const char *key, const char *value) } else if (strcasecmp ("StoreRates", key) == 0) { - if ((strcasecmp ("True", value) == 0) - || (strcasecmp ("Yes", value) == 0) - || (strcasecmp ("On", value) == 0)) - { + if (IS_TRUE (value)) store_rates = 1; - } else - { store_rates = 0; - } } else { @@ -236,11 +259,12 @@ static int csv_config (const char *key, const char *value) return (0); } /* int csv_config */ -static int csv_write (const data_set_t *ds, const value_list_t *vl) +static int csv_write (const data_set_t *ds, const value_list_t *vl, + user_data_t __attribute__((unused)) *user_data) { struct stat statbuf; char filename[512]; - char values[512]; + char values[4096]; FILE *csv; int csv_fd; struct flock fl; @@ -251,7 +275,8 @@ static int csv_write (const data_set_t *ds, const value_list_t *vl) return -1; } - if (value_list_to_filename (filename, sizeof (filename), ds, vl) != 0) + status = value_list_to_filename (filename, sizeof (filename), vl); + if (status != 0) return (-1); DEBUG ("csv plugin: csv_write: filename = %s;", filename); @@ -259,6 +284,29 @@ static int csv_write (const data_set_t *ds, const value_list_t *vl) if (value_list_to_string (values, sizeof (values), ds, vl) != 0) return (-1); + if (use_stdio) + { + size_t i; + + escape_string (filename, sizeof (filename)); + + /* Replace commas by colons for PUTVAL compatible output. */ + for (i = 0; i < sizeof (values); i++) + { + if (values[i] == 0) + break; + else if (values[i] == ',') + values[i] = ':'; + } + + fprintf (use_stdio == 1 ? stdout : stderr, + "PUTVAL %s interval=%.3f %s\n", + filename, + CDTIME_T_TO_DOUBLE (vl->interval), + values); + return (0); + } + if (stat (filename, &statbuf) == -1) { if (errno == ENOENT) @@ -322,5 +370,5 @@ void module_register (void) { plugin_register_config ("csv", csv_config, config_keys, config_keys_num); - plugin_register_write ("csv", csv_write); + plugin_register_write ("csv", csv_write, /* user_data = */ NULL); } /* void module_register */