diff --git a/src/target_scale.c b/src/target_scale.c
index 29fecdfd7b5818479437659982226c993934a63d..b29a02bfa64801d9e967294ba4d1af7e6ce0cb48 100644 (file)
--- a/src/target_scale.c
+++ b/src/target_scale.c
* collectd - src/target_scale.c
* Copyright (C) 2008-2009 Florian Forster
*
* collectd - src/target_scale.c
* Copyright (C) 2008-2009 Florian Forster
*
- * 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.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
*
*
- * 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.
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
*
*
- * 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
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
*
* Authors:
*
* Authors:
- * Florian Forster <octo at verplant.org>
+ * Florian Forster <octo at collectd.org>
**/
#include "collectd.h"
**/
#include "collectd.h"
{
double factor;
double offset;
{
double factor;
double offset;
+
+ char **data_sources;
+ size_t data_sources_num;
};
typedef struct ts_data_s ts_data_t;
};
typedef struct ts_data_s ts_data_t;
{
difference = curr_counter - prev_counter;
}
{
difference = curr_counter - prev_counter;
}
- rate = ((double) difference) / ((double) vl->interval);
+ rate = ((double) difference) / CDTIME_T_TO_DOUBLE (vl->interval);
/* Modify the rate. */
if (!isnan (data->factor))
/* Modify the rate. */
if (!isnan (data->factor))
rate += data->offset;
/* Calculate the internal counter. */
rate += data->offset;
/* Calculate the internal counter. */
- int_fraction += (rate * ((double) vl->interval));
+ int_fraction += (rate * CDTIME_T_TO_DOUBLE (vl->interval));
difference = (uint64_t) int_fraction;
int_fraction -= ((double) difference);
int_counter += difference;
difference = (uint64_t) int_fraction;
int_fraction -= ((double) difference);
int_counter += difference;
/* Calcualte the rate */
difference = curr_derive - prev_derive;
/* Calcualte the rate */
difference = curr_derive - prev_derive;
- rate = ((double) difference) / ((double) vl->interval);
+ rate = ((double) difference) / CDTIME_T_TO_DOUBLE (vl->interval);
/* Modify the rate. */
if (!isnan (data->factor))
/* Modify the rate. */
if (!isnan (data->factor))
rate += data->offset;
/* Calculate the internal derive. */
rate += data->offset;
/* Calculate the internal derive. */
- int_fraction += (rate * ((double) vl->interval));
+ int_fraction += (rate * CDTIME_T_TO_DOUBLE (vl->interval));
if (int_fraction < 0.0) /* handle negative integer rounding correctly */
difference = ((int64_t) int_fraction) - 1;
else
if (int_fraction < 0.0) /* handle negative integer rounding correctly */
difference = ((int64_t) int_fraction) - 1;
else
@@ -263,7 +271,7 @@ static int ts_invoke_absolute (const data_set_t *ds, value_list_t *vl, /* {{{ */
if (status != 0)
int_fraction = 0.0;
if (status != 0)
int_fraction = 0.0;
- rate = ((double) curr_absolute) / ((double) vl->interval);
+ rate = ((double) curr_absolute) / CDTIME_T_TO_DOUBLE (vl->interval);
/* Modify the rate. */
if (!isnan (data->factor))
/* Modify the rate. */
if (!isnan (data->factor))
@@ -272,7 +280,7 @@ static int ts_invoke_absolute (const data_set_t *ds, value_list_t *vl, /* {{{ */
rate += data->offset;
/* Calculate the new absolute. */
rate += data->offset;
/* Calculate the new absolute. */
- int_fraction += (rate * ((double) vl->interval));
+ int_fraction += (rate * CDTIME_T_TO_DOUBLE (vl->interval));
curr_absolute = (uint64_t) int_fraction;
int_fraction -= ((double) curr_absolute);
curr_absolute = (uint64_t) int_fraction;
int_fraction -= ((double) curr_absolute);
return (0);
} /* }}} int ts_config_set_double */
return (0);
} /* }}} int ts_config_set_double */
+static int ts_config_add_data_source(ts_data_t *data, /* {{{ */
+ oconfig_item_t *ci)
+{
+ size_t new_data_sources_num;
+ char **temp;
+ int i;
+
+ /* Check number of arbuments. */
+ if (ci->values_num < 1)
+ {
+ ERROR ("`value' match: `%s' needs at least one argument.",
+ ci->key);
+ return (-1);
+ }
+
+ /* Check type of arguments */
+ for (i = 0; i < ci->values_num; i++)
+ {
+ if (ci->values[i].type == OCONFIG_TYPE_STRING)
+ continue;
+
+ ERROR ("`value' match: `%s' accepts only string arguments "
+ "(argument %i is a %s).",
+ ci->key, i + 1,
+ (ci->values[i].type == OCONFIG_TYPE_BOOLEAN)
+ ? "truth value" : "number");
+ return (-1);
+ }
+
+ /* Allocate space for the char pointers */
+ new_data_sources_num = data->data_sources_num + ((size_t) ci->values_num);
+ temp = (char **) realloc (data->data_sources,
+ new_data_sources_num * sizeof (char *));
+ if (temp == NULL)
+ {
+ ERROR ("`value' match: realloc failed.");
+ return (-1);
+ }
+ data->data_sources = temp;
+
+ /* Copy the strings, allocating memory as needed. */
+ for (i = 0; i < ci->values_num; i++)
+ {
+ size_t j;
+
+ /* If we get here, there better be memory for us to write to. */
+ assert (data->data_sources_num < new_data_sources_num);
+
+ j = data->data_sources_num;
+ data->data_sources[j] = sstrdup (ci->values[i].value.string);
+ if (data->data_sources[j] == NULL)
+ {
+ ERROR ("`value' match: sstrdup failed.");
+ continue;
+ }
+ data->data_sources_num++;
+ }
+
+ return (0);
+} /* }}} int ts_config_add_data_source */
+
static int ts_destroy (void **user_data) /* {{{ */
{
static int ts_destroy (void **user_data) /* {{{ */
{
- ts_data_t **data;
+ ts_data_t *data;
if (user_data == NULL)
return (-EINVAL);
if (user_data == NULL)
return (-EINVAL);
- data = (ts_data_t **) user_data;
+ data = (ts_data_t *) *user_data;
- free (*data);
- *data = NULL;
+ if ((data != NULL) && (data->data_sources != NULL))
+ {
+ size_t i;
+ for (i = 0; i < data->data_sources_num; i++)
+ sfree (data->data_sources[i]);
+ sfree (data->data_sources);
+ }
+
+ sfree (data);
+ *user_data = NULL;
return (0);
} /* }}} int ts_destroy */
return (0);
} /* }}} int ts_destroy */
status = ts_config_set_double (&data->factor, child);
else if (strcasecmp ("Offset", child->key) == 0)
status = ts_config_set_double (&data->offset, child);
status = ts_config_set_double (&data->factor, child);
else if (strcasecmp ("Offset", child->key) == 0)
status = ts_config_set_double (&data->offset, child);
+ else if (strcasecmp ("DataSource", child->key) == 0)
+ status = ts_config_add_data_source(data, child);
else
{
ERROR ("Target `scale': The `%s' configuration option is not understood "
else
{
ERROR ("Target `scale': The `%s' configuration option is not understood "
for (i = 0; i < ds->ds_num; i++)
{
for (i = 0; i < ds->ds_num; i++)
{
+ /* If we've got a list of data sources, is it in the list? */
+ if (data->data_sources) {
+ size_t j;
+ for (j = 0; j < data->data_sources_num; j++)
+ if (strcasecmp(ds->ds[i].name, data->data_sources[j]) == 0)
+ break;
+
+ /* No match, ignore */
+ if (j >= data->data_sources_num)
+ continue;
+ }
+
if (ds->ds[i].type == DS_TYPE_COUNTER)
ts_invoke_counter (ds, vl, data, i);
else if (ds->ds[i].type == DS_TYPE_GAUGE)
if (ds->ds[i].type == DS_TYPE_COUNTER)
ts_invoke_counter (ds, vl, data, i);
else if (ds->ds[i].type == DS_TYPE_GAUGE)