Merge branch 'collectd-4.5' into collectd-4.6
[collectd.git] / src / csv.c
index ff59f91..8189bd1 100644 (file)
--- 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
  *
  * Authors:
  *   Florian octo Forster <octo at verplant.org>
+ *   Doug MacEachern <dougm@hyperic.com>
  **/
 
 #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)
@@ -45,9 +49,11 @@ static int value_list_to_string (char *buffer, int buffer_len,
        int i;
        gauge_t *rates = NULL;
 
+       assert (0 == strcmp (ds->type, vl->type));
+
        memset (buffer, '\0', buffer_len);
 
-       status = snprintf (buffer, buffer_len, "%u", (unsigned int) vl->time);
+       status = ssnprintf (buffer, buffer_len, "%u", (unsigned int) vl->time);
        if ((status < 1) || (status >= buffer_len))
                return (-1);
        offset = status;
@@ -62,7 +68,7 @@ static int value_list_to_string (char *buffer, int buffer_len,
                {
                        if (store_rates == 0)
                        {
-                               status = snprintf (buffer + offset,
+                               status = ssnprintf (buffer + offset,
                                                buffer_len - offset,
                                                ",%llu",
                                                vl->values[i].counter);
@@ -77,14 +83,14 @@ static int value_list_to_string (char *buffer, int buffer_len,
                                                        "uc_get_rate failed.");
                                        return (-1);
                                }
-                               status = snprintf (buffer + offset,
+                               status = ssnprintf (buffer + offset,
                                                buffer_len - offset,
                                                ",%lf", rates[i]);
                        }
                }
                else /* if (ds->ds[i].type == DS_TYPE_GAUGE) */
                {
-                       status = snprintf (buffer + offset, buffer_len - offset,
+                       status = ssnprintf (buffer + offset, buffer_len - offset,
                                        ",%lf", vl->values[i].gauge);
                }
 
@@ -107,41 +113,44 @@ static int value_list_to_filename (char *buffer, int buffer_len,
        int offset = 0;
        int status;
 
+       assert (0 == strcmp (ds->type, vl->type));
+
        if (datadir != NULL)
        {
-               status = snprintf (buffer + offset, buffer_len - offset,
+               status = ssnprintf (buffer + offset, buffer_len - offset,
                                "%s/", datadir);
                if ((status < 1) || (status >= buffer_len - offset))
                        return (-1);
                offset += status;
        }
 
-       status = snprintf (buffer + offset, buffer_len - offset,
+       status = ssnprintf (buffer + offset, buffer_len - offset,
                        "%s/", vl->host);
        if ((status < 1) || (status >= buffer_len - offset))
                return (-1);
        offset += status;
 
        if (strlen (vl->plugin_instance) > 0)
-               status = snprintf (buffer + offset, buffer_len - offset,
+               status = ssnprintf (buffer + offset, buffer_len - offset,
                                "%s-%s/", vl->plugin, vl->plugin_instance);
        else
-               status = snprintf (buffer + offset, buffer_len - offset,
+               status = ssnprintf (buffer + offset, buffer_len - offset,
                                "%s/", vl->plugin);
        if ((status < 1) || (status >= buffer_len - offset))
                return (-1);
        offset += status;
 
        if (strlen (vl->type_instance) > 0)
-               status = snprintf (buffer + offset, buffer_len - offset,
-                               "%s-%s", ds->type, vl->type_instance);
+               status = ssnprintf (buffer + offset, buffer_len - offset,
+                               "%s-%s", vl->type, vl->type_instance);
        else
-               status = snprintf (buffer + offset, buffer_len - offset,
-                               "%s", ds->type);
+               status = ssnprintf (buffer + offset, buffer_len - offset,
+                               "%s", vl->type);
        if ((status < 1) || (status >= buffer_len - offset))
                return (-1);
        offset += status;
 
+       if (!use_stdio)
        {
                time_t now;
                struct tm stm;
@@ -196,6 +205,16 @@ static int csv_config (const char *key, const char *value)
        {
                if (datadir != NULL)
                        free (datadir);
+               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)
                {
@@ -242,6 +261,11 @@ static int csv_write (const data_set_t *ds, const value_list_t *vl)
        struct flock fl;
        int          status;
 
+       if (0 != strcmp (ds->type, vl->type)) {
+               ERROR ("csv plugin: DS type does not match value list type");
+               return -1;
+       }
+
        if (value_list_to_filename (filename, sizeof (filename), ds, vl) != 0)
                return (-1);
 
@@ -250,6 +274,27 @@ 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=%i %s\n",
+                        filename, interval_g, values);
+               return (0);
+       }
+
        if (stat (filename, &statbuf) == -1)
        {
                if (errno == ENOENT)