[collectd] [PATCH] src/plugin.[ch]: Added support for "filter" callbacks.

Sebastian Harl sh at tokkee.org
Wed Oct 15 09:28:15 CEST 2008


This type of callback is very similar to write callbacks:

  int (*) (const data_set_t *, value_list_t *)

The return value of that callback indicates what further actions are to be
taken. It may be a bitwise OR of any of the following new flags:
FILTER_NOWRITE or FILTER_NOTHRESHOLD_CHECK. If both flags are used (which
equals the flag FILTER_IGNORE), the value list is ignored completely.

If more than one such callback is available, the respective return values are
bitwise OR'ed. If they "sum" up to FILTER_IGNORE, no further callbacks are
executed (lazy evaluation).

This type of callback may be used for the following purposes:

 * rewrite information included in the value list (e.g. the instance
   name)

 * discard certain information on a fine-grained level based on the
   information provided by the data set and value list

Signed-off-by: Sebastian Harl <sh at tokkee.org>
---

Comments, feedback and suggestions are, as always, welcome ;-)

The lazy evaluation of multiple filter callbacks and "XOR consolidation"
of the respective return values made the most sense to me but this might
be debatable and I don't have a very strong opinion on that if somebody
comes up with a better solution.

---
 src/plugin.c |   42 ++++++++++++++++++++++++++++++++++++++----
 src/plugin.h |    8 ++++++++
 2 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/src/plugin.c b/src/plugin.c
index 0ae6e44..4d503f7 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -55,6 +55,7 @@ typedef struct read_func_s read_func_t;
 static llist_t *list_init;
 static llist_t *list_read;
 static llist_t *list_write;
+static llist_t *list_filter;
 static llist_t *list_flush;
 static llist_t *list_shutdown;
 static llist_t *list_log;
@@ -442,6 +443,12 @@ int plugin_register_write (const char *name,
 	return (register_callback (&list_write, name, (void *) callback));
 } /* int plugin_register_write */
 
+int plugin_register_filter (const char *name,
+		int (*callback) (const data_set_t *ds, value_list_t *vl))
+{
+	return (register_callback (&list_filter, name, (void *) callback));
+} /* int plugin_register_filter */
+
 int plugin_register_flush (const char *name,
 		int (*callback) (const int timeout, const char *identifier))
 {
@@ -542,6 +549,11 @@ int plugin_unregister_write (const char *name)
 	return (plugin_unregister (list_write, name));
 }
 
+int plugin_unregister_filter (const char *name)
+{
+	return (plugin_unregister (list_filter, name));
+}
+
 int plugin_unregister_flush (const char *name)
 {
 	return (plugin_unregister (list_flush, name));
@@ -720,10 +732,11 @@ int plugin_dispatch_values (value_list_t *vl)
 {
 	static c_complain_t no_write_complaint = C_COMPLAIN_INIT_STATIC;
 
-	int (*callback) (const data_set_t *, const value_list_t *);
 	data_set_t *ds;
 	llentry_t *le;
 
+	int filter = 0;
+
 	if ((vl == NULL) || (*vl->type == '\0')) {
 		ERROR ("plugin_dispatch_values: Invalid value list.");
 		return (-1);
@@ -785,15 +798,36 @@ int plugin_dispatch_values (value_list_t *vl)
 	escape_slashes (vl->type, sizeof (vl->type));
 	escape_slashes (vl->type_instance, sizeof (vl->type_instance));
 
+	le = llist_head (list_filter);
+	while (le != NULL)
+	{
+		int (*filter_callback) (const data_set_t *, value_list_t *) =
+				(int (*) (const data_set_t *, value_list_t *)) le->value;
+
+		filter |= (*filter_callback) (ds, vl);
+
+		if (filter == FILTER_IGNORE)
+			return (-1);
+
+		le = le->next;
+	}
+
 	/* Update the value cache */
 	uc_update (ds, vl);
-	ut_check_threshold (ds, vl);
+
+	if ((filter & FILTER_NOTHRESHOLD_CHECK) == 0)
+		ut_check_threshold (ds, vl);
+
+	if (filter & FILTER_NOWRITE)
+		return (0);
 
 	le = llist_head (list_write);
 	while (le != NULL)
 	{
-		callback = (int (*) (const data_set_t *, const value_list_t *)) le->value;
-		(*callback) (ds, vl);
+		int (*write_callback) (const data_set_t *, const value_list_t *) =
+				(int (*) (const data_set_t *, const value_list_t *)) le->value;
+
+		(*write_callback) (ds, vl);
 
 		le = le->next;
 	}
diff --git a/src/plugin.h b/src/plugin.h
index 3ffde46..b90811c 100644
--- a/src/plugin.h
+++ b/src/plugin.h
@@ -52,6 +52,11 @@
 #define NOTIF_WARNING 2
 #define NOTIF_OKAY    4
 
+#define FILTER_NOWRITE 1
+#define FILTER_NOTHRESHOLD_CHECK 2
+/* FILTER_IGNORE has to equal the bitwise or of all other filter flags */
+#define FILTER_IGNORE (FILTER_NOWRITE | FILTER_NOTHRESHOLD_CHECK)
+
 /*
  * Public data types
  */
@@ -196,6 +201,8 @@ int plugin_register_read (const char *name,
 		int (*callback) (void));
 int plugin_register_write (const char *name,
 		int (*callback) (const data_set_t *ds, const value_list_t *vl));
+int plugin_register_filter (const char *name,
+		int (*callback) (const data_set_t *ds, value_list_t *vl));
 int plugin_register_flush (const char *name,
 		int (*callback) (const int timeout, const char *identifier));
 int plugin_register_shutdown (char *name,
@@ -211,6 +218,7 @@ int plugin_unregister_complex_config (const char *name);
 int plugin_unregister_init (const char *name);
 int plugin_unregister_read (const char *name);
 int plugin_unregister_write (const char *name);
+int plugin_unregister_filter (const char *name);
 int plugin_unregister_flush (const char *name);
 int plugin_unregister_shutdown (const char *name);
 int plugin_unregister_data_set (const char *name);
-- 
1.6.0.2.307.gc4275

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://mailman.verplant.org/pipermail/collectd/attachments/20081015/f04c160e/attachment.pgp 


More information about the collectd mailing list