* collectd - src/dbi.c
* Copyright (C) 2008-2015 Florian octo 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:
* Florian octo Forster <octo at collectd.org>
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "configfile.h"
char *name;
char *select_db;
+ cdtime_t interval;
+
char *driver;
char *host;
cdbi_driver_option_t *driver_options;
static cdbi_database_t **databases = NULL;
static size_t databases_num = 0;
+static int cdbi_read_database (user_data_t *ud);
+
/*
* Functions
*/
else if (src_type == DBI_TYPE_STRING)
{
const char *value;
-
+
value = dbi_result_get_string_idx (res, index);
if (value == NULL)
sstrncpy (buffer, "", buffer_size);
static void cdbi_database_free (cdbi_database_t *db) /* {{{ */
{
- size_t i;
-
if (db == NULL)
return;
sfree (db->name);
sfree (db->driver);
- for (i = 0; i < db->driver_options_num; i++)
+ for (size_t i = 0; i < db->driver_options_num; i++)
{
sfree (db->driver_options[i].key);
if (!db->driver_options[i].is_numeric)
sfree (db->driver_options);
if (db->q_prep_areas)
- for (i = 0; i < db->queries_num; ++i)
+ for (size_t i = 0; i < db->queries_num; ++i)
udb_query_delete_preparation_area (db->q_prep_areas[i]);
free (db->q_prep_areas);
* </Result>
* ...
* </Query>
- *
+ *
* <Database "plugin_instance1">
* Driver "mysql"
+ * Interval 120
* DriverOption "hostname" "localhost"
* ...
* Query "plugin_instance0"
return (-1);
}
- option = (cdbi_driver_option_t *) realloc (db->driver_options,
+ option = realloc (db->driver_options,
sizeof (*option) * (db->driver_options_num + 1));
if (option == NULL)
{
{
cdbi_database_t *db;
int status;
- int i;
if ((ci->values_num != 1)
|| (ci->values[0].type != OCONFIG_TYPE_STRING))
return (-1);
}
- db = (cdbi_database_t *) malloc (sizeof (*db));
+ db = calloc (1, sizeof (*db));
if (db == NULL)
{
- ERROR ("dbi plugin: malloc failed.");
+ ERROR ("dbi plugin: calloc failed.");
return (-1);
}
- memset (db, 0, sizeof (*db));
status = cf_util_get_string (ci, &db->name);
if (status != 0)
}
/* Fill the `cdbi_database_t' structure.. */
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *child = ci->children + i;
&db->queries, &db->queries_num);
else if (strcasecmp ("Host", child->key) == 0)
status = cf_util_get_string (child, &db->host);
+ else if (strcasecmp ("Interval", child->key) == 0)
+ status = cf_util_get_cdtime(child, &db->interval);
else
{
WARNING ("dbi plugin: Option `%s' not allowed here.", child->key);
while ((status == 0) && (db->queries_num > 0))
{
- db->q_prep_areas = (udb_query_preparation_area_t **) calloc (
- db->queries_num, sizeof (*db->q_prep_areas));
-
+ db->q_prep_areas = calloc (db->queries_num, sizeof (*db->q_prep_areas));
if (db->q_prep_areas == NULL)
{
- WARNING ("dbi plugin: malloc failed");
+ WARNING ("dbi plugin: calloc failed");
status = -1;
break;
}
- for (i = 0; i < db->queries_num; ++i)
+ for (size_t i = 0; i < db->queries_num; ++i)
{
db->q_prep_areas[i]
= udb_query_allocate_preparation_area (db->queries[i]);
{
cdbi_database_t **temp;
- temp = (cdbi_database_t **) realloc (databases,
+ temp = realloc (databases,
sizeof (*databases) * (databases_num + 1));
if (temp == NULL)
{
}
else
{
+ user_data_t ud = { 0 };
+ char *name = NULL;
+
databases = temp;
databases[databases_num] = db;
databases_num++;
+
+ ud.data = (void *) db;
+ ud.free_func = NULL;
+ name = ssnprintf_alloc("dbi:%s", db->name);
+
+ plugin_register_complex_read (/* group = */ NULL,
+ /* name = */ name ? name : db->name,
+ /* callback = */ cdbi_read_database,
+ /* interval = */ (db->interval > 0) ? db->interval : 0,
+ /* user_data = */ &ud);
+ free (name);
}
}
static int cdbi_config (oconfig_item_t *ci) /* {{{ */
{
- int i;
-
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *child = ci->children + i;
if (strcasecmp ("Query", child->key) == 0)
char **column_names;
char **column_values;
int status;
- size_t i;
/* Macro that cleans up dynamically allocated memory and returns the
* specified status. */
column_names = NULL;
column_values = NULL;
- res = NULL;
statement = udb_query_get_statement (q);
assert (statement != NULL);
}
/* Allocate `column_names' and `column_values'. {{{ */
- column_names = (char **) calloc (column_num, sizeof (char *));
+ column_names = calloc (column_num, sizeof (*column_names));
if (column_names == NULL)
{
- ERROR ("dbi plugin: malloc failed.");
+ ERROR ("dbi plugin: calloc failed.");
BAIL_OUT (-1);
}
- column_names[0] = (char *) calloc (column_num,
- DATA_MAX_NAME_LEN * sizeof (char));
+ column_names[0] = calloc (column_num, DATA_MAX_NAME_LEN);
if (column_names[0] == NULL)
{
- ERROR ("dbi plugin: malloc failed.");
+ ERROR ("dbi plugin: calloc failed.");
BAIL_OUT (-1);
}
- for (i = 1; i < column_num; i++)
+ for (size_t i = 1; i < column_num; i++)
column_names[i] = column_names[i - 1] + DATA_MAX_NAME_LEN;
- column_values = (char **) calloc (column_num, sizeof (char *));
+ column_values = calloc (column_num, sizeof (*column_values));
if (column_values == NULL)
{
- ERROR ("dbi plugin: malloc failed.");
+ ERROR ("dbi plugin: calloc failed.");
BAIL_OUT (-1);
}
- column_values[0] = (char *) calloc (column_num,
- DATA_MAX_NAME_LEN * sizeof (char));
+ column_values[0] = calloc (column_num, DATA_MAX_NAME_LEN);
if (column_values[0] == NULL)
{
- ERROR ("dbi plugin: malloc failed.");
+ ERROR ("dbi plugin: calloc failed.");
BAIL_OUT (-1);
}
- for (i = 1; i < column_num; i++)
+ for (size_t i = 1; i < column_num; i++)
column_values[i] = column_values[i - 1] + DATA_MAX_NAME_LEN;
/* }}} */
/* Copy the field names to `column_names' */
- for (i = 0; i < column_num; i++) /* {{{ */
+ for (size_t i = 0; i < column_num; i++) /* {{{ */
{
const char *column_name;
udb_query_prepare_result (q, prep_area, (db->host ? db->host : hostname_g),
/* plugin = */ "dbi", db->name,
- column_names, column_num, /* interval = */ 0);
+ column_names, column_num, /* interval = */ (db->interval > 0) ? db->interval : 0);
/* 0 = error; 1 = success; */
status = dbi_result_first_row (res); /* {{{ */
{
status = 0;
/* Copy the value of the columns to `column_values' */
- for (i = 0; i < column_num; i++) /* {{{ */
+ for (size_t i = 0; i < column_num; i++) /* {{{ */
{
status = cdbi_result_get_field (res, (unsigned int) (i + 1),
column_values[i], DATA_MAX_NAME_LEN);
{
dbi_driver driver;
dbi_conn connection;
- size_t i;
int status;
if (db->connection != NULL)
* encountered, it will get a list of options understood by the driver and
* report that as `INFO'. This way, users hopefully don't have too much
* trouble finding out how to configure the plugin correctly.. */
- for (i = 0; i < db->driver_options_num; i++)
+ for (size_t i = 0; i < db->driver_options_num; i++)
{
if (db->driver_options[i].is_numeric)
{
if (status != 0)
{
- char const *opt;
-
INFO ("dbi plugin: This is a list of all options understood "
"by the `%s' driver:", db->driver);
- for (opt = dbi_conn_get_option_list (connection, NULL);
+ for (const char *opt = dbi_conn_get_option_list (connection, NULL);
opt != NULL;
opt = dbi_conn_get_option_list (connection, opt))
{
return (0);
} /* }}} int cdbi_connect_database */
-static int cdbi_read_database (cdbi_database_t *db) /* {{{ */
+static int cdbi_read_database (user_data_t *ud) /* {{{ */
{
- size_t i;
+ cdbi_database_t *db = (cdbi_database_t *) ud->data;
int success;
int status;
/* TODO: Complain if `db_version == 0' */
success = 0;
- for (i = 0; i < db->queries_num; i++)
+ for (size_t i = 0; i < db->queries_num; i++)
{
/* Check if we know the database's version and if so, if this query applies
* to that version. */
return (0);
} /* }}} int cdbi_read_database */
-static int cdbi_read (void) /* {{{ */
-{
- size_t i;
- int success = 0;
- int status;
-
- /* TODO(octo): Starting with libdbi 0.9.0, there is an "instance" argument to
- * the *_r-functions. We should probably have multiple read callbacks instead
- * of this loop. */
- for (i = 0; i < databases_num; i++)
- {
- status = cdbi_read_database (databases[i]);
- if (status == 0)
- success++;
- }
-
- if (success == 0)
- {
- ERROR ("dbi plugin: No database could be read. Will return an error so "
- "the plugin will be delayed.");
- return (-1);
- }
-
- return (0);
-} /* }}} int cdbi_read */
-
static int cdbi_shutdown (void) /* {{{ */
{
- size_t i;
-
- for (i = 0; i < databases_num; i++)
+ for (size_t i = 0; i < databases_num; i++)
{
if (databases[i]->connection != NULL)
{
{
plugin_register_complex_config ("dbi", cdbi_config);
plugin_register_init ("dbi", cdbi_init);
- plugin_register_read ("dbi", cdbi_read);
plugin_register_shutdown ("dbi", cdbi_shutdown);
} /* }}} void module_register */