From: Florian Forster Date: Wed, 4 Feb 2009 13:29:45 +0000 (+0100) Subject: src/plugin.c: Add the `{Pre,Post}CacheChain' options and appropriate chains. X-Git-Tag: collectd-4.6.0~71 X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=9fbc4088ce8b5c67602e0ee059686aa426c2c637;p=collectd.git src/plugin.c: Add the `{Pre,Post}CacheChain' options and appropriate chains. The PreCacheChain is executed before the values are added to the cache, the PostCacheChain afterwards. If no post-cache chain is given, values will be dispatched to all write plugins by default. --- diff --git a/src/configfile.c b/src/configfile.c index f9ade29b..0f49de26 100644 --- a/src/configfile.c +++ b/src/configfile.c @@ -1,6 +1,6 @@ /** * collectd - src/configfile.c - * Copyright (C) 2005-2008 Florian octo Forster + * Copyright (C) 2005-2009 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 @@ -98,7 +98,9 @@ static cf_global_option_t cf_global_options[] = {"Hostname", NULL, NULL}, {"FQDNLookup", NULL, "false"}, {"Interval", NULL, "10"}, - {"ReadThreads", NULL, "5"} + {"ReadThreads", NULL, "5"}, + {"PreCacheChain", NULL, "PreCache"}, + {"PostCacheChain", NULL, "PostCache"} }; static int cf_global_options_num = STATIC_ARRAY_LEN (cf_global_options); diff --git a/src/filter_chain.c b/src/filter_chain.c index 01cd224c..6d0bca7b 100644 --- a/src/filter_chain.c +++ b/src/filter_chain.c @@ -1,6 +1,6 @@ /** * collectd - src/filter_chain.h - * Copyright (C) 2008 Florian octo Forster + * Copyright (C) 2008,2009 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 @@ -102,9 +102,7 @@ struct fc_rule_s }; /* }}} */ /* List of chains, used for `chain_list_head' */ -struct fc_chain_s; -typedef struct fc_chain_s fc_chain_t; /* {{{ */ -struct fc_chain_s +struct fc_chain_s /* {{{ */ { char name[DATA_MAX_NAME_LEN]; fc_rule_t *rules; @@ -555,157 +553,6 @@ static int fc_config_add_chain (const oconfig_item_t *ci) /* {{{ */ return (0); } /* }}} int fc_config_add_chain */ -int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */ - fc_chain_t *chain) -{ - fc_rule_t *rule; - fc_target_t *target; - int status; - - if (chain == NULL) - return (-1); - - DEBUG ("fc_process_chain (chain = %s);", chain->name); - - status = FC_TARGET_CONTINUE; - for (rule = chain->rules; rule != NULL; rule = rule->next) - { - fc_match_t *match; - - if (rule->name[0] != 0) - { - DEBUG ("fc_process_chain (%s): Testing the `%s' rule.", - chain->name, rule->name); - } - - /* N. B.: rule->matches may be NULL. */ - for (match = rule->matches; match != NULL; match = match->next) - { - status = (*match->proc.match) (ds, vl, /* meta = */ NULL, - &match->user_data); - if (status < 0) - { - WARNING ("fc_process_chain (%s): A match failed.", chain->name); - break; - } - else if (status != FC_MATCH_MATCHES) - break; - } - - /* for-loop has been aborted: Either error or no match. */ - if (match != NULL) - { - status = FC_TARGET_CONTINUE; - continue; - } - - if (rule->name[0] != 0) - { - DEBUG ("fc_process_chain (%s): Rule `%s' matches.", - chain->name, rule->name); - } - - for (target = rule->targets; target != NULL; target = target->next) - { - /* If we get here, all matches have matched the value. Execute the - * target. */ - status = (*target->proc.invoke) (ds, vl, /* meta = */ NULL, - &target->user_data); - if (status < 0) - { - WARNING ("fc_process_chain (%s): A target failed.", chain->name); - continue; - } - else if (status == FC_TARGET_CONTINUE) - continue; - else if (status == FC_TARGET_STOP) - break; - else if (status == FC_TARGET_RETURN) - break; - else - { - WARNING ("fc_process_chain (%s): Unknown return value " - "from target `%s': %i", - chain->name, target->name, status); - } - } - - if ((status == FC_TARGET_STOP) - || (status == FC_TARGET_RETURN)) - { - if (rule->name[0] != 0) - { - DEBUG ("fc_process_chain (%s): Rule `%s' signaled " - "the %s condition.", - chain->name, rule->name, - (status == FC_TARGET_STOP) ? "stop" : "return"); - } - break; - } - else - { - status = FC_TARGET_CONTINUE; - } - } /* for (rule) */ - - if (status == FC_TARGET_STOP) - return (FC_TARGET_STOP); - else if (status == FC_TARGET_RETURN) - return (FC_TARGET_CONTINUE); - - /* for-loop has been aborted: A target returned `FC_TARGET_STOP' */ - if (rule != NULL) - return (FC_TARGET_CONTINUE); - - DEBUG ("fc_process_chain (%s): Executing the default targets.", - chain->name); - - status = FC_TARGET_CONTINUE; - for (target = chain->targets; target != NULL; target = target->next) - { - /* If we get here, all matches have matched the value. Execute the - * target. */ - status = (*target->proc.invoke) (ds, vl, /* meta = */ NULL, - &target->user_data); - if (status < 0) - { - WARNING ("fc_process_chain (%s): The default target failed.", - chain->name); - } - else if (status == FC_TARGET_CONTINUE) - continue; - else if (status == FC_TARGET_STOP) - break; - else if (status == FC_TARGET_RETURN) - break; - else - { - WARNING ("fc_process_chain (%s): Unknown return value " - "from target `%s': %i", - chain->name, target->name, status); - } - } - - if ((status == FC_TARGET_STOP) - || (status == FC_TARGET_RETURN)) - { - assert (target != NULL); - DEBUG ("fc_process_chain (%s): Default target `%s' signaled " - "the %s condition.", - chain->name, target->name, - (status == FC_TARGET_STOP) ? "stop" : "return"); - if (status == FC_TARGET_STOP) - return (FC_TARGET_STOP); - else - return (FC_TARGET_CONTINUE); - } - - DEBUG ("fc_process_chain (%s): Signaling `continue' at end of chain.", - chain->name); - - return (FC_TARGET_CONTINUE); -} /* }}} int fc_process_chain */ - /* * Built-in target "jump" * @@ -1022,22 +869,178 @@ int fc_register_target (const char *name, target_proc_t proc) /* {{{ */ return (0); } /* }}} int fc_register_target */ -/* Iterate over all rules in the chain and execute all targets for which all - * matches match. */ -int fc_process (const data_set_t *ds, value_list_t *vl) /* {{{ */ +fc_chain_t *fc_chain_get_by_name (const char *chain_name) /* {{{ */ { fc_chain_t *chain; + if (chain_name == NULL) + return (NULL); + for (chain = chain_list_head; chain != NULL; chain = chain->next) - if (strcasecmp ("Main", chain->name) == 0) + if (strcasecmp (chain_name, chain->name) == 0) + return (chain); + + return (NULL); +} /* }}} int fc_chain_get_by_name */ + +int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */ + fc_chain_t *chain) +{ + fc_rule_t *rule; + fc_target_t *target; + int status; + + if (chain == NULL) + return (-1); + + DEBUG ("fc_process_chain (chain = %s);", chain->name); + + status = FC_TARGET_CONTINUE; + for (rule = chain->rules; rule != NULL; rule = rule->next) + { + fc_match_t *match; + + if (rule->name[0] != 0) + { + DEBUG ("fc_process_chain (%s): Testing the `%s' rule.", + chain->name, rule->name); + } + + /* N. B.: rule->matches may be NULL. */ + for (match = rule->matches; match != NULL; match = match->next) + { + status = (*match->proc.match) (ds, vl, /* meta = */ NULL, + &match->user_data); + if (status < 0) + { + WARNING ("fc_process_chain (%s): A match failed.", chain->name); + break; + } + else if (status != FC_MATCH_MATCHES) + break; + } + + /* for-loop has been aborted: Either error or no match. */ + if (match != NULL) + { + status = FC_TARGET_CONTINUE; + continue; + } + + if (rule->name[0] != 0) + { + DEBUG ("fc_process_chain (%s): Rule `%s' matches.", + chain->name, rule->name); + } + + for (target = rule->targets; target != NULL; target = target->next) + { + /* If we get here, all matches have matched the value. Execute the + * target. */ + status = (*target->proc.invoke) (ds, vl, /* meta = */ NULL, + &target->user_data); + if (status < 0) + { + WARNING ("fc_process_chain (%s): A target failed.", chain->name); + continue; + } + else if (status == FC_TARGET_CONTINUE) + continue; + else if (status == FC_TARGET_STOP) + break; + else if (status == FC_TARGET_RETURN) + break; + else + { + WARNING ("fc_process_chain (%s): Unknown return value " + "from target `%s': %i", + chain->name, target->name, status); + } + } + + if ((status == FC_TARGET_STOP) + || (status == FC_TARGET_RETURN)) + { + if (rule->name[0] != 0) + { + DEBUG ("fc_process_chain (%s): Rule `%s' signaled " + "the %s condition.", + chain->name, rule->name, + (status == FC_TARGET_STOP) ? "stop" : "return"); + } break; + } + else + { + status = FC_TARGET_CONTINUE; + } + } /* for (rule) */ - if (chain != NULL) - return (fc_process_chain (ds, vl, chain)); + if (status == FC_TARGET_STOP) + return (FC_TARGET_STOP); + else if (status == FC_TARGET_RETURN) + return (FC_TARGET_CONTINUE); + + /* for-loop has been aborted: A target returned `FC_TARGET_STOP' */ + if (rule != NULL) + return (FC_TARGET_CONTINUE); + DEBUG ("fc_process_chain (%s): Executing the default targets.", + chain->name); + + status = FC_TARGET_CONTINUE; + for (target = chain->targets; target != NULL; target = target->next) + { + /* If we get here, all matches have matched the value. Execute the + * target. */ + status = (*target->proc.invoke) (ds, vl, /* meta = */ NULL, + &target->user_data); + if (status < 0) + { + WARNING ("fc_process_chain (%s): The default target failed.", + chain->name); + } + else if (status == FC_TARGET_CONTINUE) + continue; + else if (status == FC_TARGET_STOP) + break; + else if (status == FC_TARGET_RETURN) + break; + else + { + WARNING ("fc_process_chain (%s): Unknown return value " + "from target `%s': %i", + chain->name, target->name, status); + } + } + + if ((status == FC_TARGET_STOP) + || (status == FC_TARGET_RETURN)) + { + assert (target != NULL); + DEBUG ("fc_process_chain (%s): Default target `%s' signaled " + "the %s condition.", + chain->name, target->name, + (status == FC_TARGET_STOP) ? "stop" : "return"); + if (status == FC_TARGET_STOP) + return (FC_TARGET_STOP); + else + return (FC_TARGET_CONTINUE); + } + + DEBUG ("fc_process_chain (%s): Signaling `continue' at end of chain.", + chain->name); + + return (FC_TARGET_CONTINUE); +} /* }}} int fc_process_chain */ + +/* Iterate over all rules in the chain and execute all targets for which all + * matches match. */ +int fc_default_action (const data_set_t *ds, value_list_t *vl) /* {{{ */ +{ return (fc_bit_write_invoke (ds, vl, /* meta = */ NULL, /* user_data = */ NULL)); -} /* }}} int fc_process */ +} /* }}} int fc_default_action */ int fc_configure (const oconfig_item_t *ci) /* {{{ */ { diff --git a/src/filter_chain.h b/src/filter_chain.h index 2fd78d97..187fe22e 100644 --- a/src/filter_chain.h +++ b/src/filter_chain.h @@ -1,6 +1,6 @@ /** * collectd - src/filter_chain.h - * Copyright (C) 2008 Florian octo Forster + * Copyright (C) 2008,2009 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 @@ -58,6 +58,9 @@ struct target_proc_s }; typedef struct target_proc_s target_proc_t; +struct fc_chain_s; +typedef struct fc_chain_s fc_chain_t; + int fc_register_target (const char *name, target_proc_t proc); /* @@ -82,7 +85,12 @@ int fc_rule_delete (const char *chain_name, int position); /* * Processing function */ -int fc_process (const data_set_t *ds, value_list_t *vl); +fc_chain_t *fc_chain_get_by_name (const char *chain_name); + +int fc_process_chain (const data_set_t *ds, value_list_t *vl, + fc_chain_t *chain); + +int fc_default_action (const data_set_t *ds, value_list_t *vl); /* * Shortcut for global configuration diff --git a/src/plugin.c b/src/plugin.c index bf707eca..fa1d2718 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -1,6 +1,6 @@ /** * collectd - src/plugin.c - * Copyright (C) 2005-2008 Florian octo Forster + * Copyright (C) 2005-2009 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 @@ -62,6 +62,9 @@ static llist_t *list_shutdown; static llist_t *list_log; static llist_t *list_notification; +static fc_chain_t *pre_cache_chain = NULL; +static fc_chain_t *post_cache_chain = NULL; + static c_avl_tree_t *data_sets; static char *plugindir = NULL; @@ -596,6 +599,7 @@ int plugin_unregister_notification (const char *name) void plugin_init_all (void) { + const char *chain_name; int (*callback) (void); llentry_t *le; int status; @@ -603,6 +607,13 @@ void plugin_init_all (void) /* Init the value cache */ uc_init (); + chain_name = global_option_get ("PreCacheChain"); + pre_cache_chain = fc_chain_get_by_name (chain_name); + + chain_name = global_option_get ("PostCacheChain"); + post_cache_chain = fc_chain_get_by_name (chain_name); + + if ((list_init == NULL) && (list_read == NULL)) return; @@ -898,10 +909,16 @@ int plugin_dispatch_values (value_list_t *vl) escape_slashes (vl->type, sizeof (vl->type)); escape_slashes (vl->type_instance, sizeof (vl->type_instance)); + if (pre_cache_chain != NULL) + fc_process_chain (ds, vl, pre_cache_chain); + /* Update the value cache */ uc_update (ds, vl); - fc_process (ds, vl); + if (post_cache_chain != NULL) + fc_process_chain (ds, vl, post_cache_chain); + else + fc_default_action (ds, vl); return (0); } /* int plugin_dispatch_values */