[collectd] [PATCH] Notify DBI plugin
Manuel Luis Sanmartín Rozada
manuel.luis at gmail.com
Tue Sep 20 16:35:42 CEST 2011
Hello.
I created a plugin to insert notifications in a database, It's based on dbi.c.
A issue is remaining: dbi.c and notify_dbi.c both call dbi_initialize on init.
You can get tracking of the Failure and Warning notifications active.
In the following example only the Ok notifications deletes Failure and Warnings:
LoadPlugin notify_dbi
<Plugin notify_dbi>
<Database "mysql">
Driver "mysql"
DriverOption "host" "localhost"
DriverOption "username" "collectd"
DriverOption "password" "collectd"
DriverOption "dbname" "collectd"
Query "Failure" "Warning" "Ok" "INSERT INTO alert_history (host,
plugin, plugin_instance, type, type_instance, time, severity, message)
VALUES ('%{host}', '%{plugin}', '%{plugin_instance}', '%{type}',
'%{type_instance}', '%{time}', '%{severity}', '%{message}')"
Query "Failure" "Warning" "INSERT INTO alert (host, plugin,
plugin_instance, type, type_instance, time, severity, message) VALUES
('%{host}', '%{plugin}', '%{plugin_instance}', '%{type}',
'%{type_instance}', '%{time}', '%{severity}', '%{message}')"
Query "Ok" "DELETE FROM alert where host = '%{host}' and plugin =
'%{plugin}' and plugin_instance = '%{plugin_instance}' and type =
'%{type}' and type_instance = '%{type_instance}'"
</Database>
</Plugin>
and the tables:
CREATE TABLE `alert` (
`id` int(10) NOT NULL auto_increment,
`time` int(10) unsigned default NULL,
`severity` varchar(8) default NULL,
`host` varchar(64) default NULL,
`plugin` varchar(64) default NULL,
`plugin_instance` varchar(64) default NULL,
`type` varchar(64) default NULL,
`type_instance` varchar(64) default NULL,
`message` varchar(256) default NULL,
PRIMARY KEY (`id`),
KEY `host` (`host`)
);
CREATE TABLE `alert_history` (
`time` int(10) unsigned default NULL,
`severity` varchar(8) default NULL,
`host` varchar(64) default NULL,
`plugin` varchar(64) default NULL,
`plugin_instance` varchar(64) default NULL,
`type` varchar(64) default NULL,
`type_instance` varchar(64) default NULL,
`message` varchar(256) default NULL
);
---
configure.in | 2 +
src/Makefile.am | 11 +
src/notify_dbi.c | 691 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 704 insertions(+), 0 deletions(-)
create mode 100644 src/notify_dbi.c
diff --git a/configure.in b/configure.in
index 9b6397f..4141d89 100644
--- a/configure.in
+++ b/configure.in
@@ -4629,6 +4629,7 @@ AC_PLUGIN([netlink], [$with_libnetlink],
[Enhanced Linux network statistic
AC_PLUGIN([network], [yes], [Network communication plugin])
AC_PLUGIN([nfs], [$plugin_nfs], [NFS statistics])
AC_PLUGIN([nginx], [$with_libcurl], [nginx statistics])
+AC_PLUGIN([notify_dbi], [$with_libdbi], [Database notifier])
AC_PLUGIN([notify_desktop], [$with_libnotify], [Desktop notifications])
AC_PLUGIN([notify_email], [$with_libesmtp], [Email notifier])
AC_PLUGIN([ntpd], [yes], [NTPd statistics])
@@ -4951,6 +4952,7 @@ Configuration:
network . . . . . . . $enable_network
nfs . . . . . . . . . $enable_nfs
nginx . . . . . . . . $enable_nginx
+ notify_dbi . . . . . $enable_notify_dbi
notify_desktop . . . $enable_notify_desktop
notify_email . . . . $enable_notify_email
ntpd . . . . . . . . $enable_ntpd
diff --git a/src/Makefile.am b/src/Makefile.am
index 795de57..04bc1aa 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -731,6 +731,17 @@ collectd_LDADD += "-dlopen" nginx.la
collectd_DEPENDENCIES += nginx.la
endif
+if BUILD_PLUGIN_NOTIFY_DBI
+pkglib_LTLIBRARIES += notify_dbi.la
+notify_dbi_la_SOURCES = notify_dbi.c \
+ utils_db_query.c utils_db_query.h
+notify_dbi_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBDBI_CPPFLAGS)
+notify_dbi_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBDBI_LDFLAGS)
+notify_dbi_la_LIBADD = $(BUILD_WITH_LIBDBI_LIBS)
+collectd_LDADD += "-dlopen" notify_dbi.la
+collectd_DEPENDENCIES += notify_dbi.la
+endif
+
if BUILD_PLUGIN_NOTIFY_DESKTOP
pkglib_LTLIBRARIES += notify_desktop.la
notify_desktop_la_SOURCES = notify_desktop.c
diff --git a/src/notify_dbi.c b/src/notify_dbi.c
new file mode 100644
index 0000000..7d4bad4
--- /dev/null
+++ b/src/notify_dbi.c
@@ -0,0 +1,691 @@
+/**
+ * collectd - src/notify_dbi.c
+ * Copyright (C) 2008,2009 Florian octo Forster
+ * Copyright (C) 2011 Manuel Sanmartin
+ *
+ * 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
+ *
+ * Heavily based on dbi.c
+ *
+ * Authors:
+ * Florian octo Forster <octo at verplant.org>
+ * Manuel Sanmartin <manuel.luis at gmail.com>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "configfile.h"
+#include "utils_subst.h"
+
+#include <dbi/dbi.h>
+
+/*
+ * Data types
+ */
+struct notify_dbi_driver_option_s /* {{{ */
+{
+ char *key;
+ char *value;
+};
+typedef struct notify_dbi_driver_option_s notify_dbi_driver_option_t; /* }}} */
+
+struct notify_dbi_query_s /* {{{ */
+{
+ int severity;
+ char *query;
+};
+typedef struct notify_dbi_query_s notify_dbi_query_t; /* }}} */
+
+struct notify_dbi_database_s /* {{{ */
+{
+ char *name;
+ char *select_db;
+
+ char *driver;
+ notify_dbi_driver_option_t *driver_options;
+ size_t driver_options_num;
+
+ notify_dbi_query_t *queries;
+ size_t queries_num;
+
+ dbi_conn connection;
+};
+typedef struct notify_dbi_database_s notify_dbi_database_t; /* }}} */
+
+/*
+ * Global variables
+ */
+static notify_dbi_database_t **databases = NULL;
+static size_t databases_num = 0;
+
+/*
+ * Functions
+ */
+static const char *notify_dbi_strerror (dbi_conn conn, /* {{{ */
+ char *buffer, size_t buffer_size)
+{
+ const char *msg;
+ int status;
+
+ if (conn == NULL)
+ {
+ sstrncpy (buffer, "connection is NULL", buffer_size);
+ return (buffer);
+ }
+
+ msg = NULL;
+ status = dbi_conn_error (conn, &msg);
+ if ((status >= 0) && (msg != NULL))
+ ssnprintf (buffer, buffer_size, "%s (status %i)", msg, status);
+ else
+ ssnprintf (buffer, buffer_size, "dbi_conn_error failed with status %i",
+ status);
+
+ return (buffer);
+} /* }}} const char *notify_dbi_conn_error */
+
+static void notify_dbi_database_free (notify_dbi_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++)
+ {
+ sfree (db->driver_options[i].key);
+ sfree (db->driver_options[i].value);
+ }
+ sfree (db->driver_options);
+
+ for (i = 0; i < db->queries_num; i++)
+ sfree (db->queries[i].query);
+ sfree (db->queries);
+
+ sfree (db);
+} /* }}} void notify_dbi_database_free */
+
+/* Configuration handling functions {{{
+ * <Plugin notify_dbi>
+ * <Database "mysql">
+ * Driver "mysql"
+ * DriverOption "host" "localhost"
+ * DriverOption "username" "collectd"
+ * DriverOption "password" "collectd"
+ * DriverOption "dbname" "collectd"
+
+ * Query "Failure" "Warning" "Ok" "INSERT INTO alert_history
(host, plugin, plugin_instance, type, type_instance, time, severity,
message) VALUES ('%{host}', '%{plugin}', '%{plugin_instance}',
'%{type}', '%{type_instance}', '%{time}', '%{severity}',
'%{message}')"
+ * Query "Failure" "Warning" "INSERT INTO alert (host, plugin,
plugin_instance, type, type_instance, time, severity, message) VALUES
('%{host}', '%{plugin}', '%{plugin_instance}', '%{type}',
'%{type_instance}', '%{time}', '%{severity}', '%{message}')"
+ * Query "Ok" "DELETE FROM alert where host = '%{host}' and
plugin = '%{plugin}' and plugin_instance = '%{plugin_instance}' and
type = '%{type}' and type_instance = '%{type_instance}'"
+ * </Database>
+ * </Plugin>
+ */
+
+static int notify_dbi_config_set_string (char **ret_string, /* {{{ */
+ oconfig_item_t *ci)
+{
+ char *string;
+
+ if ((ci->values_num != 1)
+ || (ci->values[0].type != OCONFIG_TYPE_STRING))
+ {
+ WARNING ("notify_dbi plugin: The `%s' config option "
+ "needs exactly one string argument.", ci->key);
+ return (-1);
+ }
+
+ string = strdup (ci->values[0].value.string);
+ if (string == NULL)
+ {
+ ERROR ("notify_dbi plugin: strdup failed.");
+ return (-1);
+ }
+
+ if (*ret_string != NULL)
+ free (*ret_string);
+ *ret_string = string;
+
+ return (0);
+} /* }}} int notify_dbi_config_set_string */
+
+static int notify_dbi_config_add_database_driver_option
(notify_dbi_database_t *db, /* {{{ */
+ oconfig_item_t *ci)
+{
+ notify_dbi_driver_option_t *option;
+
+ if ((ci->values_num != 2)
+ || (ci->values[0].type != OCONFIG_TYPE_STRING)
+ || (ci->values[1].type != OCONFIG_TYPE_STRING))
+ {
+ WARNING ("notify_dbi plugin: The `DriverOption' config option "
+ "needs exactly two string arguments.");
+ return (-1);
+ }
+
+ option = (notify_dbi_driver_option_t *) realloc (db->driver_options,
+ sizeof (*option) * (db->driver_options_num + 1));
+ if (option == NULL)
+ {
+ ERROR ("notify_dbi plugin: realloc failed");
+ return (-1);
+ }
+
+ db->driver_options = option;
+ option = db->driver_options + db->driver_options_num;
+
+ option->key = strdup (ci->values[0].value.string);
+ if (option->key == NULL)
+ {
+ ERROR ("notify_dbi plugin: strdup failed.");
+ return (-1);
+ }
+
+ option->value = strdup (ci->values[1].value.string);
+ if (option->value == NULL)
+ {
+ ERROR ("notify_dbi plugin: strdup failed.");
+ sfree (option->key);
+ return (-1);
+ }
+
+ db->driver_options_num++;
+ return (0);
+} /* }}} int notify_dbi_config_add_database_driver_option */
+
+int notify_dbi_config_add_database_query (notify_dbi_database_t *db, /* {{{ */
+ oconfig_item_t *ci)
+{
+ size_t i;
+ int severity;
+ char *query;
+ notify_dbi_query_t *tmp_list;
+
+ if (ci->values_num < 2)
+ {
+ WARNING ("notify_dbi plugin: The `Query' config option "
+ "needs two or more string arguments.");
+ return (-1);
+ }
+
+ severity = 0;
+ query = NULL;
+
+ for (i = 0; i < ci->values_num; i++)
+ {
+ if (ci->values[i].type != OCONFIG_TYPE_STRING)
+ {
+ WARNING ("notify_dbi plugin: The arguments of `Query' config option "
+ "must be strings.");
+ return (-1);
+ }
+
+ if (i < (ci->values_num-1))
+ {
+ if (!strcasecmp(ci->values[i].value.string, "failure"))
+ {
+ severity |= NOTIF_FAILURE;
+ }
+ else if (!strcasecmp(ci->values[i].value.string, "warning"))
+ {
+ severity |= NOTIF_WARNING;
+ }
+ else if (!strcasecmp(ci->values[i].value.string, "ok"))
+ {
+ severity |= NOTIF_OKAY;
+ }
+ else
+ {
+ WARNING ("notify_dbi plugin: Unknow severity in `Query'
config option: "
+ "`%s'", ci->values[i].value.string);
+ return (-1);
+ }
+ }
+ else
+ {
+ query = strdup(ci->values[i].value.string);
+ }
+ }
+
+ tmp_list = (notify_dbi_query_t *) realloc(db->queries, (db->queries_num+1)
+ * sizeof(notify_dbi_query_t));
+ if (tmp_list == NULL)
+ {
+ sfree(query);
+ ERROR ("notify_dbi plugin: realloc failed.");
+ return (-ENOMEM);
+ }
+
+ tmp_list[db->queries_num].query = query;
+ tmp_list[db->queries_num].severity = severity;
+ db->queries = tmp_list;
+ db->queries_num++;
+
+ return (0);
+} /* }}} int notify_dbi_config_add_database_query */
+
+static int notify_dbi_config_add_database (oconfig_item_t *ci) /* {{{ */
+{
+ notify_dbi_database_t *db;
+ int status;
+ int i;
+
+ if ((ci->values_num != 1)
+ || (ci->values[0].type != OCONFIG_TYPE_STRING))
+ {
+ WARNING ("notify_dbi plugin: The `Database' block "
+ "needs exactly one string argument.");
+ return (-1);
+ }
+
+ db = (notify_dbi_database_t *) malloc (sizeof (*db));
+ if (db == NULL)
+ {
+ ERROR ("notify_dbi plugin: malloc failed.");
+ return (-1);
+ }
+ memset (db, 0, sizeof (*db));
+
+ status = notify_dbi_config_set_string (&db->name, ci);
+ if (status != 0)
+ {
+ sfree (db);
+ return (status);
+ }
+
+ /* Fill the `notify_dbi_database_t' structure.. */
+ for (i = 0; i < ci->children_num; i++)
+ {
+ oconfig_item_t *child = ci->children + i;
+
+ if (strcasecmp ("Driver", child->key) == 0)
+ status = notify_dbi_config_set_string (&db->driver, child);
+ else if (strcasecmp ("DriverOption", child->key) == 0)
+ status = notify_dbi_config_add_database_driver_option (db, child);
+ else if (strcasecmp ("SelectDB", child->key) == 0)
+ status = notify_dbi_config_set_string (&db->select_db, child);
+ else if (strcasecmp ("Query", child->key) == 0)
+ status = notify_dbi_config_add_database_query (db, child);
+ else
+ {
+ WARNING ("notify_dbi plugin: Option `%s' not allowed here.", child->key);
+ status = -1;
+ }
+
+ if (status != 0)
+ break;
+ }
+
+ /* Check that all necessary options have been given. */
+ while (status == 0)
+ {
+ if (db->driver == NULL)
+ {
+ WARNING ("notify_dbi plugin: `Driver' not given for database
`%s'", db->name);
+ status = -1;
+ }
+ if (db->driver_options_num == 0)
+ {
+ WARNING ("notify_dbi plugin: No `DriverOption' given for database `%s'. "
+ "This will likely not work.", db->name);
+ }
+
+ break;
+ } /* while (status == 0) */
+
+ /* If all went well, add this database to the global list of databases. */
+ if (status == 0)
+ {
+ notify_dbi_database_t **temp;
+
+ temp = (notify_dbi_database_t **) realloc (databases,
+ sizeof (*databases) * (databases_num + 1));
+ if (temp == NULL)
+ {
+ ERROR ("notify_dbi plugin: realloc failed");
+ status = -1;
+ }
+ else
+ {
+ databases = temp;
+ databases[databases_num] = db;
+ databases_num++;
+ }
+ }
+
+ if (status != 0)
+ {
+ notify_dbi_database_free (db);
+ return (-1);
+ }
+
+ return (0);
+} /* }}} int notify_dbi_config_add_database */
+
+static int notify_dbi_config (oconfig_item_t *ci) /* {{{ */
+{
+ int i;
+
+ for (i = 0; i < ci->children_num; i++)
+ {
+ oconfig_item_t *child = ci->children + i;
+ if (strcasecmp ("Database", child->key) == 0)
+ notify_dbi_config_add_database (child);
+ else
+ {
+ WARNING ("notify_dbi plugin: Ignoring unknown config option
`%s'.", child->key);
+ }
+ } /* for (ci->children) */
+
+ return (0);
+} /* }}} int notify_dbi_config */
+
+/* }}} End of configuration handling functions */
+
+static int notify_dbi_init (void) /* {{{ */
+{
+ static int did_init = 0;
+ int status;
+
+ if (did_init != 0)
+ return (0);
+
+ if (databases_num == 0)
+ {
+ ERROR ("notify_dbi plugin: No <Database> blocks have been found.
Without them, "
+ "this plugin can't do anything useful, so we will returns an error.");
+ return (-1);
+ }
+
+ status = dbi_initialize (NULL);
+ if (status < 0)
+ {
+ ERROR ("notify_dbi plugin: notify_dbi_init: dbi_initialize failed
with status %i.",
+ status);
+ return (-1);
+ }
+ else if (status == 0)
+ {
+ ERROR ("notify_dbi plugin: `dbi_initialize' could not load any
drivers. Please "
+ "install at least one `DBD' or check your installation.");
+ return (-1);
+ }
+ DEBUG ("notify_dbi plugin: notify_dbi_init: dbi_initialize reports
%i driver%s.",
+ status, (status == 1) ? "" : "s");
+
+ return (0);
+} /* }}} int notify_dbi_init */
+
+static int notify_dbi_notification_database_query
(notify_dbi_database_t *db, /* {{{ */
+ const char *statement, const notification_t *n)
+{
+ dbi_result res;
+ int status;
+ char query[4096];
+ char temp[4096];
+ char time_buffer[12];
+ char severity_buffer[8];
+
+ res = NULL;
+ assert (statement != NULL);
+
+ status = ssnprintf (time_buffer, sizeof(time_buffer), "%u",
(unsigned int) n->time);
+ if ((status < 1) || (status >= sizeof(time_buffer)))
+ return (-1);
+
+ if (n->severity & NOTIF_FAILURE)
+ strncpy(severity_buffer, "FAILURE", sizeof(severity_buffer));
+ else if (n->severity & NOTIF_WARNING)
+ strncpy(severity_buffer, "WARNING", sizeof(severity_buffer));
+ else if (n->severity & NOTIF_OKAY)
+ strncpy(severity_buffer, "OKAY", sizeof(severity_buffer));
+
+ strncpy(query, statement, sizeof(query));
+
+#define REPLACE_FIELD(t,v) \
+ if (subst_string (temp, sizeof (temp), query, t, v) != NULL) \
+ sstrncpy (query, temp, sizeof (query));
+ REPLACE_FIELD ("%{host}", n->host);
+ REPLACE_FIELD ("%{plugin}", n->plugin);
+ REPLACE_FIELD ("%{plugin_instance}", n->plugin_instance);
+ REPLACE_FIELD ("%{type}", n->type);
+ REPLACE_FIELD ("%{type_instance}", n->type_instance);
+ REPLACE_FIELD ("%{message}", n->message);
+ REPLACE_FIELD ("%{time}", time_buffer);
+ REPLACE_FIELD ("%{severity}", severity_buffer);
+#undef REPLACE_FIELD
+
+ res = dbi_conn_query (db->connection, query);
+ if (res == NULL)
+ {
+ char errbuf[1024];
+ ERROR ("notify_dbi plugin: notify_dbi_notification_database_query
(%s, %s): "
+ "dbi_conn_query failed: %s",
+ db->name, query,
+ notify_dbi_strerror (db->connection, errbuf, sizeof (errbuf)));
+ return (-1);
+ }
+
+ /* Clean up and return `status = 0' (success) */
+ if (res != NULL)
+ {
+ dbi_result_free (res);
+ res = NULL;
+ }
+ return (0);
+} /* }}} int notify_dbi_read_database_query */
+
+static int notify_dbi_connect_database (notify_dbi_database_t *db) /* {{{ */
+{
+ dbi_driver driver;
+ dbi_conn connection;
+ size_t i;
+ int status;
+
+ if (db->connection != NULL)
+ {
+ status = dbi_conn_ping (db->connection);
+ if (status != 0) /* connection is alive */
+ return (0);
+
+ dbi_conn_close (db->connection);
+ db->connection = NULL;
+ }
+
+ driver = dbi_driver_open (db->driver);
+ if (driver == NULL)
+ {
+ ERROR ("notify_dbi plugin: notify_dbi_connect_database:
dbi_driver_open (%s) failed.",
+ db->driver);
+ INFO ("notify_dbi plugin: Maybe the driver isn't installed? "
+ "Known drivers are:");
+ for (driver = dbi_driver_list (NULL);
+ driver != NULL;
+ driver = dbi_driver_list (driver))
+ {
+ INFO ("notify_dbi plugin: * %s", dbi_driver_get_name (driver));
+ }
+ return (-1);
+ }
+
+ connection = dbi_conn_open (driver);
+ if (connection == NULL)
+ {
+ ERROR ("notify_dbi plugin: notify_dbi_connect_database:
dbi_conn_open (%s) failed.",
+ db->driver);
+ return (-1);
+ }
+
+ /* Set all the driver options. Because this is a very very very generic
+ * interface, the error handling is kind of long. If an invalid option is
+ * 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++)
+ {
+ DEBUG ("notify_dbi plugin: notify_dbi_connect_database (%s): "
+ "key = %s; value = %s;",
+ db->name,
+ db->driver_options[i].key,
+ db->driver_options[i].value);
+
+ status = dbi_conn_set_option (connection,
+ db->driver_options[i].key, db->driver_options[i].value);
+ if (status != 0)
+ {
+ char errbuf[1024];
+ const char *opt;
+
+ ERROR ("notify_dbi plugin: notify_dbi_connect_database (%s): "
+ "dbi_conn_set_option (%s, %s) failed: %s.",
+ db->name,
+ db->driver_options[i].key, db->driver_options[i].value,
+ notify_dbi_strerror (connection, errbuf, sizeof (errbuf)));
+
+ INFO ("notify_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);
+ opt != NULL;
+ opt = dbi_conn_get_option_list (connection, opt))
+ {
+ INFO ("notify_dbi plugin: * %s", opt);
+ }
+
+ dbi_conn_close (connection);
+ return (-1);
+ }
+ } /* for (i = 0; i < db->driver_options_num; i++) */
+
+ status = dbi_conn_connect (connection);
+ if (status != 0)
+ {
+ char errbuf[1024];
+ ERROR ("notify_dbi plugin: notify_dbi_connect_database (%s): "
+ "dbi_conn_connect failed: %s",
+ db->name, notify_dbi_strerror (connection, errbuf, sizeof (errbuf)));
+ dbi_conn_close (connection);
+ return (-1);
+ }
+
+ if (db->select_db != NULL)
+ {
+ status = dbi_conn_select_db (connection, db->select_db);
+ if (status != 0)
+ {
+ char errbuf[1024];
+ WARNING ("notify_dbi plugin: notify_dbi_connect_database (%s): "
+ "dbi_conn_select_db (%s) failed: %s. Check the `SelectDB' option.",
+ db->name, db->select_db,
+ notify_dbi_strerror (connection, errbuf, sizeof (errbuf)));
+ dbi_conn_close (connection);
+ return (-1);
+ }
+ }
+
+ db->connection = connection;
+ return (0);
+} /* }}} int notify_dbi_connect_database */
+
+static int notify_dbi_notification_database (notify_dbi_database_t
*db, /* {{{ */
+ const notification_t *n)
+{
+ size_t i;
+ int success;
+ int status;
+
+ status = notify_dbi_connect_database (db);
+ if (status != 0)
+ return (status);
+ assert (db->connection != NULL);
+
+ success = 0;
+ for (i = 0; i < db->queries_num; i++)
+ {
+ if (db->queries[i].severity & n->severity)
+ {
+ status = notify_dbi_notification_database_query (db,
+ db->queries[i].query, n);
+ if (status == 0)
+ success++;
+ }
+ }
+
+ if (success == 0)
+ {
+ ERROR ("notify_dbi plugin: All queries failed for database
`%s'.", db->name);
+ return (-1);
+ }
+
+ return (0);
+} /* }}} int notify_dbi_notification_database */
+
+
+static int notify_dbi_notification (const notification_t *n, /* {{{ */
+ user_data_t __attribute__((unused)) *user_data)
+{
+ size_t i;
+ int success = 0;
+ int status;
+
+ for (i = 0; i < databases_num; i++)
+ {
+ status = notify_dbi_notification_database (databases[i], n);
+ if (status == 0)
+ success++;
+ }
+
+ if (success == 0)
+ {
+ ERROR ("notify_dbi plugin: No database could be read. Will return
an error so "
+ "the plugin will be delayed.");
+ return (-1);
+ }
+
+ return (0);
+} /* }}} int notify_dbi_notification */
+
+static int notify_dbi_shutdown (void) /* {{{ */
+{
+ size_t i;
+
+ for (i = 0; i < databases_num; i++)
+ {
+ if (databases[i]->connection != NULL)
+ {
+ dbi_conn_close (databases[i]->connection);
+ databases[i]->connection = NULL;
+ }
+ notify_dbi_database_free (databases[i]);
+ }
+ sfree (databases);
+ databases_num = 0;
+
+ return (0);
+} /* }}} int notify_dbi_shutdown */
+
+void module_register (void) /* {{{ */
+{
+ plugin_register_complex_config ("notify_dbi", notify_dbi_config);
+ plugin_register_init ("notify_dbi", notify_dbi_init);
+ plugin_register_notification ("notify_dbi", notify_dbi_notification,
+ /* user_data = */ NULL);
+ plugin_register_shutdown ("notify_dbi", notify_dbi_shutdown);
+} /* }}} void module_register */
+
+/*
+ * vim: shiftwidth=2 softtabstop=2 et fdm=marker
+ */
--
1.7.6
More information about the collectd
mailing list