Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * collectd - src/csv.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 <octo at verplant.org>
- * Doug MacEachern <[email protected]>
- **/
- #define C_AVL_CREATE_STRCMP() (c_avl_create((int (*)(const void *, const void *))strcmp))
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include "collectd.h"
- #include "plugin.h"
- #include "common.h"
- #include "utils_cache.h"
- #include "utils_parse_option.h"
- #include "utils_avltree.h"
- /*
- * Private variables
- */
- /* static const char *config_keys[] = */
- /* { */
- /* "DataDir", */
- /* "FilePrefix", */
- /* "StoreRates", */
- /* "IncludePlugins", */
- /* "IncludeTypes", */
- /* }; */
- /* static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); */
- /*
- * TODO: Implement this kind of options
- *
- *
- *
- * <Plugin "pax_write">
- * DataDir "/opt/collectd/var/lib/collectd/csv/"
- * FilePrefix "data-file"
- * StoreRates false
- *
- * EveryThing yes|no default no
- *
- *
- * <Host "hostname">
- * <Plugin "plugin[-plugininstance]/type[-typeinstance]">
- * DS "datasources" "datasources" ...
- * </Plugin>
- *
- * <Plugin "plugin[-plugininstance]/type[-typeinstance] /> # All datasources
- * </Host>
- *
- *
- * </Plugin>
- *
- *
- */
- static char *datadir = NULL;
- static int store_rates = 0;
- static c_avl_tree_t *hosts_tree = NULL;
- /* static char **include_plugins_keys = NULL; */
- /* static char **include_plugins_values = NULL; */
- static char *fileprefix = NULL;
- /* static char *format = 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;
- /* char **keys; */
- int i;
- gauge_t *rates = NULL;
- assert (0 == strcmp (ds->type, vl->type));
- /*
- * Search plugin on AVL tree and
- * return if not found
- */
- void *tmp;
- char **p_types;
- if (c_avl_get(include_plugins, vl->plugin, &tmp) != 0)
- return -1;
- p_types = (char **)tmp;
- DEBUG ("pax write plugin: pax_write: Plugin %s found on AVL tree", vl->plugin);
- memset (buffer, '\0', buffer_len);
- for (i = 0; i < ds->ds_num; i++)
- {
- int j;
- int bit;
- for (j = 0, bit = 0; p_types[j]; j++)
- {
- if (strcmp(p_types[j], ds->ds[i].name) == 0)
- {
- bit = 1;
- break;
- }
- }
- if (bit == 0)
- {
- continue;
- }
- DEBUG("pax write plugin: pax_write: Data source %s found on plugin %s", ds->ds[i].name, vl->plugin);
- /*
- * A new line if we are not on
- * first iteration
- */
- if (i > 0)
- {
- status = ssnprintf(buffer + offset, buffer_len - offset, "\n");
- if ((status < 1) || (status >= buffer_len - offset))
- return (-1);
- offset += status;
- }
- /*
- * Host
- */
- status = ssnprintf (buffer + offset, buffer_len - offset,
- "%s", vl->host);
- 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);
- }
- else
- {
- status = ssnprintf (buffer + offset, buffer_len - offset,
- ",%s-%s", vl->plugin, vl->plugin_instance);
- }
- 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);
- }
- else
- {
- status = ssnprintf (buffer + offset, buffer_len - offset,
- ",%s-%s", vl->type, vl->type_instance);
- }
- if ((status < 1) || (status >= buffer_len - offset))
- return (-1);
- offset += status;
- /*
- * Data source name
- */
- status = ssnprintf (buffer + offset, buffer_len - offset,
- ",%s", ds->ds[i].name);
- if ((status < 1) || (status >= buffer_len - offset))
- return (-1);
- offset += status;
- /*
- * Data source
- */
- if ((ds->ds[i].type != DS_TYPE_COUNTER)
- && (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_GAUGE)
- {
- 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)
- {
- WARNING ("pax 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_COUNTER)
- {
- 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)))
- {
- sfree (rates);
- return (-1);
- }
- offset += status;
- /*
- * Epoch/Time
- */
- status = ssnprintf (buffer + offset, buffer_len - offset, ",%.3f",
- CDTIME_T_TO_DOUBLE (vl->time));
- if ((status < 1) || (status >= buffer_len - offset))
- return (-1);
- offset += status;
- } /* for ds->ds_num */
- sfree (rates);
- return (0);
- } /* int value_list_to_string */
- static int value_list_to_filename (char *buffer, int buffer_len, const char *fileprefix)
- {
- int status;
- int offset = 0;
- if (datadir != NULL)
- {
- status = ssnprintf (buffer, buffer_len,
- "%s/", datadir);
- if ((status < 1) || (status >= buffer_len))
- return (-1);
- offset += status;
- } else {
- ERROR ("pax write plugin: value_list_to_filename: DataDir is NULL at %d", __LINE__);
- return (-1);
- }
- assert(fileprefix);
- status = ssnprintf (buffer + offset, buffer_len,
- "%s", fileprefix);
- if ((status < 1) || (status >= buffer_len))
- return (-1);
- offset += status;
- time_t now;
- struct tm stm;
- /* 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 ("pax plugin: localtime_r failed");
- return (1);
- }
- strftime (buffer + offset, buffer_len - offset,
- "-%Y-%m-%d", &stm);
- return (0);
- } /* int value_list_to_filename */
- static int pax_create_file (const char *filename, const data_set_t *ds)
- {
- int fd;
- if (check_create_dir (datadir))
- return (-1);
- fd = creat (filename, S_IRWXU | S_IWUSR | S_IRGRP | S_IROTH);
- if (fd == -1)
- {
- char errbuf[1024];
- ERROR ("pax plugin: fopen (%s) failed: %s",
- filename,
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return (-1);
- }
- close (fd);
- return 0;
- } /* int pax_create_file */
- static int pax_config_add_plugin(oconfig_item_t pluginopt, c_avl_tree_t *ptree)
- {
- int j;
- char **datasources = NULL;
- char *pname;
- assert(ptree);
- pname = strdup(pluginopt->values[0].values.string);
- /* No datasources mean, collect all datasources */
- if (pluginopt->children_num == 1)
- {
- datasources = malloc(sizeof(char *) * pluginopt->children[0].values_num);
- if (!datasources)
- {
- int errbuf[1024];
- ERROR("pax write plugin: pax_config: Can't allocate memory %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
- }
- for (j = 0; j < pluginopt->children[0].values_num; j++)
- {
- datasources[j] = strdup(pluginopt->children[0].values[j].values.string);
- }
- }
- if (pluginopt->children_num == 0)
- {
- int error = c_avl_insert(ptree, pname, datasources);
- if (error)
- {
- ERROR("pax write plugin: pax_config_add_plugin: Can't insert %s at plugin tree", pname);
- return (-1);
- }
- }
- static int pax_config_add_host (oconfig_item_t *hostopt)
- {
- int error;
- int i;
- char *hostname = strdup(hostopt->values[0].value.string);
- c_avl_tree_t *plugin_tree = NULL;
- if (!hostname)
- {
- char errbuf[1024];
- ERROR("pax write plugin: pax_config_add_host: Can't allocate memory: %s\n",
- sstrerror (errno, errbuf,sizeof (errbuf)));
- return (-1);
- }
- if (!hosts_tree)
- {
- hosts_tree = C_AVL_CREATE_STRCMP();
- if (!hosts_tree)
- {
- ERROR("pax write plugin: pax_config: Can't allocate memory for AVL Trees at %d", __LINE__);
- return (-1);
- }
- }
- plugin_tree = C_AVL_CREATE_STRCMP();
- if (!plugin_tree)
- {
- ERROR("pax write plugin: pax_config: Can't allocate memory for AVL Trees at %d", __LINE__);
- return (-1);
- }
- for (i = 0; i < hostopt->children_num; i++)
- {
- oconfig_item_t *pluginopt = hostopt->children + i;
- if (strcasecmp("Plugin", pluginopt->key) == 0)
- {
- int error = pax_config_add_plugin(plugin_opt, plugin_tree);
- if (error)
- return (-1)
- }
- }
- error = c_avl_insert(hosts_tree, hostname, plugins_tree);
- }
- static int pax_config_complex (oconfig_item_t *ci)
- {
- int i;
- include_plugins = c_avl_create((int (*)(const void *, const void *))strcmp);
- if (!include_plugins)
- {
- ERROR("pax write plugin: pax_config: Can't allocate memory for AVL Trees at %d", __LINE__);
- return (-1);
- }
- for (i = 0; i < ci->children_num; i++)
- {
- oconfig_item_t *option = ci->children + i;
- if (strcasecmp ("DataDir", option->key) == 0)
- {
- if (datadir != NULL)
- free (datadir);
- datadir = strdup (option->values[0].value.string);
- if (datadir != NULL && datadir[strlen(datadir) - 1] != '/')
- {
- ERROR("pax write plugin: pax_config: Directory path should end with a slash");
- free (datadir);
- datadir = NULL;
- return (-1);
- }
- DEBUG("pax write plugin: pax_config: DataDir = '%s'", datadir);
- }
- else if (strcasecmp ("StoreRates", option->key) == 0)
- {
- if (option->values[0].value.boolean)
- store_rates = 1;
- else
- store_rates = 0;
- DEBUG("pax write plugin: pax_config: StoreRates = '%s'", (store_rates ? "true" : "false"));
- }
- else if (strcasecmp ("FilePrefix", option->key) == 0)
- {
- if (fileprefix != NULL)
- free(fileprefix);
- fileprefix = strdup(option->values[0].value.string);
- DEBUG("pax write plugin: pax_config: FilePrefix = '%s'", fileprefix);
- }
- else if (strcasecmp ("Host", option->key) == 0)
- {
- int error = pax_config_add_host(option);
- if (error)
- {
- ERROR("pax write plugin: pax_config: Can't add host %s", option->values[0].value.string);
- return (-1);
- }
- }
- /* else if (strcasecmp ("IncludePlugins", option->key) == 0) */
- /* { */
- /* int j; */
- /* include_plugins_keys = malloc(sizeof(char *) * option->children_num); */
- /* for (j = 0; j < option->children_num; j++) */
- /* { */
- /* int k; */
- /* oconfig_item_t *plugin_opt = option->children + j; */
- /* char **values = malloc(plugin_opt->values_num * sizeof(char *) + 1); */
- /* memset(values, '\0', plugin_opt->values_num * sizeof(char *) + 1); */
- /* include_plugins_keys[j] = strdup(plugin_opt->key); */
- /* /\* DEBUG(">>>>> %s", include_plugins_keys[j]); *\/ */
- /* for (k = 0; k < plugin_opt->values_num; k++) */
- /* { */
- /* /\* DEBUG(">>>>>>>>>>>> %s", plugin_opt->values[k].value.string); *\/ */
- /* values[k] = strdup(plugin_opt->values[k].value.string); */
- /* } */
- /* values[k] = NULL; /\* NULL terminated array *\/ */
- /* c_avl_insert(include_plugins, include_plugins_keys[j], values); } */
- /* } */
- else
- {
- return (-1);
- }
- }
- return (0);
- } /* int pax_config_complex */
- /* static int pax_config (const char *key, const char *value) */
- /* { */
- /* if (strcasecmp ("DataDir", key) == 0) */
- /* { */
- /* if (datadir != NULL) */
- /* free (datadir); */
- /* datadir = strdup (value); */
- /* if (datadir != NULL && datadir[strlen(datadir) - 1] != '/') */
- /* { */
- /* ERROR("pax write plugin: pax_config: Directory path should end with a slash"); */
- /* free (datadir); */
- /* datadir = NULL; */
- /* return (-1); */
- /* } */
- /* DEBUG("pax write plugin: pax_config: DataDir = '%s'", datadir); */
- /* } */
- /* else if (strcasecmp ("StoreRates", key) == 0) */
- /* { */
- /* if (IS_TRUE (value)) */
- /* store_rates = 1; */
- /* else */
- /* store_rates = 0; */
- /* } */
- /* else if (strcasecmp ("FilePrefix", key) == 0) */
- /* { */
- /* if (fileprefix != NULL) */
- /* free(fileprefix); */
- /* fileprefix = strdup(value); */
- /* } */
- /* else */
- /* { */
- /* return (-1); */
- /* } */
- /* return (0); */
- /* } /\* int pax_config *\/ */
- static int pax_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[4096];
- FILE *pax_fp;
- int pax_fd;
- struct flock fl;
- int status;
- if (0 != strcmp (ds->type, vl->type)) {
- ERROR ("pax plugin: DS type does not match value list type");
- return -1;
- }
- if (value_list_to_filename (filename, sizeof (filename), fileprefix) != 0)
- return (-1);
- DEBUG ("pax write plugin: pax_write: filename = %s;", filename);
- if (value_list_to_string (values, sizeof (values), ds, vl) != 0)
- return (-1);
- if (stat (filename, &statbuf) == -1)
- {
- if (errno == ENOENT)
- {
- if (pax_create_file (filename, ds))
- return (-1);
- }
- else
- {
- char errbuf[1024];
- ERROR ("stat(%s) failed: %s", filename,
- sstrerror (errno, errbuf,
- sizeof (errbuf)));
- return (-1);
- }
- }
- else if (!S_ISREG (statbuf.st_mode))
- {
- ERROR ("stat(%s): Not a regular file!",
- filename);
- return (-1);
- }
- pax_fp = fopen (filename, "a");
- if (pax_fp == NULL)
- {
- char errbuf[1024];
- ERROR ("pax write plugin: fopen (%s) failed: %s", filename,
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return (-1);
- }
- pax_fd = fileno (pax_fp);
- memset (&fl, '\0', sizeof (fl));
- fl.l_start = 0;
- fl.l_len = 0; /* till end of file */
- fl.l_pid = getpid ();
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
- status = fcntl (pax_fd, F_SETLK, &fl);
- if (status != 0)
- {
- char errbuf[1024];
- ERROR ("pax plugin: flock (%s) failed: %s", filename,
- sstrerror (errno, errbuf, sizeof (errbuf)));
- fclose (pax_fp);
- return (-1);
- }
- fprintf (pax_fp, "%s\n", values);
- /* The lock is implicitely released. I we don't release it explicitely
- * because the `FILE *' may need to flush a cache first */
- fclose (pax_fp);
- return (0);
- } /* int pax_write */
- void module_register (void)
- {
- plugin_register_complex_config ("pax_write", pax_config_complex);
- /* plugin_register_config ("pax_write", pax_config, */
- /* config_keys, config_keys_num); */
- plugin_register_write ("pax_write", pax_write, /* user_data = */ NULL);
- } /* void module_register */
Advertisement
Add Comment
Please, Sign In to add comment