summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 0a1424b)
raw | patch | inline | side by side (parent: 0a1424b)
author | Sebastian Harl <sh@tokkee.org> | |
Sun, 19 Aug 2012 10:38:21 +0000 (12:38 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Sun, 19 Aug 2012 10:38:21 +0000 (12:38 +0200) |
Similar to other write plugins, this option causes counter values to be
converted to rates before submitting them to the database. The option defaults
to true.
converted to rates before submitting them to the database. The option defaults
to true.
src/collectd.conf.pod | patch | blob | history | |
src/postgresql.c | patch | blob | history |
diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod
index 7d287cc2fdf21f4a41dd4377f0431557376df003..6a1cdd2cad75f2a32103d787cb8335dbe642bc6f 100644 (file)
--- a/src/collectd.conf.pod
+++ b/src/collectd.conf.pod
PostgreSQL will do (see chapter "Server Programming" in the PostgreSQL manual
for details).
+=item B<StoreRates> B<false>|B<true>
+
+If set to B<true> (the default), convert counter values to rates. If set to
+B<false> counter values are stored as is, i.E<nbsp>e. as an increasing integer
+number.
+
=back
The B<Database> block defines one PostgreSQL database for which to collect
diff --git a/src/postgresql.c b/src/postgresql.c
index 7bc450eaae51bc20c413c2e36269c4760432d62e..62a54da4380d24c95f5d17079a83e9677ed56f60 100644 (file)
--- a/src/postgresql.c
+++ b/src/postgresql.c
#include "configfile.h"
#include "plugin.h"
+#include "utils_cache.h"
#include "utils_db_query.h"
#include "utils_complain.h"
typedef struct {
char *name;
char *statement;
+ _Bool store_rates;
} c_psql_writer_t;
typedef struct {
} /* values_name_to_sqlarray */
static char *values_to_sqlarray (const data_set_t *ds, const value_list_t *vl,
- char *string, size_t string_len)
+ char *string, size_t string_len, _Bool store_rates)
{
char *str_ptr;
size_t str_len;
+ gauge_t *rates = NULL;
+
int i;
str_ptr = string;
for (i = 0; i < vl->values_len; ++i) {
int status;
+ if ((ds->ds[i].type != DS_TYPE_GAUGE)
+ && (ds->ds[i].type != DS_TYPE_COUNTER)
+ && (ds->ds[i].type != DS_TYPE_DERIVE)
+ && (ds->ds[i].type != DS_TYPE_ABSOLUTE)) {
+ log_err ("c_psql_write: Unknown data source type: %i",
+ ds->ds[i].type);
+ sfree (rates);
+ return NULL;
+ }
+
if (ds->ds[i].type == DS_TYPE_GAUGE)
status = ssnprintf (str_ptr, str_len,
",%f", vl->values[i].gauge);
+ else if (store_rates) {
+ if (rates == NULL)
+ rates = uc_get_rate (ds, vl);
+
+ if (rates == NULL) {
+ log_err ("c_psql_write: Failed to determine rate");
+ return NULL;
+ }
+
+ status = ssnprintf (str_ptr, str_len,
+ ",%lf", rates[i]);
+ }
else if (ds->ds[i].type == DS_TYPE_COUNTER)
status = ssnprintf (str_ptr, str_len,
",%llu", vl->values[i].counter);
@@ -622,14 +648,11 @@ static char *values_to_sqlarray (const data_set_t *ds, const value_list_t *vl,
else if (ds->ds[i].type == DS_TYPE_ABSOLUTE)
status = ssnprintf (str_ptr, str_len,
",%"PRIu64, vl->values[i].absolute);
- else {
- log_err ("c_psql_write: Unknown data source type: %i",
- ds->ds[i].type);
- return NULL;
- }
- if (status < 1)
- return NULL;
+ if (status < 1) {
+ str_len = 0;
+ break;
+ }
else if ((size_t)status >= str_len) {
str_len = 0;
break;
}
}
+ sfree (rates);
+
if (str_len <= 2) {
log_err ("c_psql_write: Failed to stringify value list");
return NULL;
values_name_str, sizeof (values_name_str)) == NULL)
return -1;
- if (values_to_sqlarray (ds, vl, values_str, sizeof (values_str)) == NULL)
- return -1;
-
#define VALUE_OR_NULL(v) ((((v) == NULL) || (*(v) == '\0')) ? NULL : (v))
params[0] = time_str;
params[4] = vl->type;
params[5] = VALUE_OR_NULL(vl->type_instance);
params[6] = values_name_str;
- params[7] = values_str;
#undef VALUE_OR_NULL
writer = db->writers[i];
+ if (values_to_sqlarray (ds, vl,
+ values_str, sizeof (values_str),
+ writer->store_rates) == NULL)
+ return -1;
+
+ params[7] = values_str;
+
res = PQexecParams (db->conn, writer->statement,
STATIC_ARRAY_SIZE (params), NULL,
(const char *const *)params,
writer->name = sstrdup (ci->values[0].value.string);
writer->statement = NULL;
+ writer->store_rates = 1;
for (i = 0; i < ci->children_num; ++i) {
oconfig_item_t *c = ci->children + i;
if (strcasecmp ("Statement", c->key) == 0)
status = cf_util_get_string (c, &writer->statement);
+ if (strcasecmp ("StoreRates", c->key) == 0)
+ status = cf_util_get_boolean (c, &writer->store_rates);
else
log_warn ("Ignoring unknown config key \"%s\".", c->key);
}