From 1adcb690283e97b10cb31c8bb24e19cfb157eb41 Mon Sep 17 00:00:00 2001 From: Tom Leaman Date: Fri, 4 Oct 2013 14:12:42 +0100 Subject: [PATCH] Allow Interval per File block for tail plugin The allows each block in the tail plugin config to specify its own Interval value. If ommitted, will use the default. --- src/collectd.conf.in | 1 + src/collectd.conf.pod | 4 +++ src/tail.c | 63 +++++++++++++++++++++++------------------- src/utils_tail_match.c | 8 +++++- src/utils_tail_match.h | 2 +- 5 files changed, 48 insertions(+), 30 deletions(-) diff --git a/src/collectd.conf.in b/src/collectd.conf.in index 4542a4b5..9e4c2697 100644 --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@ -989,6 +989,7 @@ # # # Instance "exim" +# Interval 60 # # Regex "S=([1-9][0-9]*)" # DSType "CounterAdd" diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index fe72534e..7a6eefe3 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -5472,6 +5472,7 @@ user using (extended) regular expressions, as described in L. Instance "exim" + Interval 60 Regex "S=([1-9][0-9]*)" DSType "CounterAdd" @@ -5498,6 +5499,9 @@ This plugin instance is for all B blocks that B it, until the next B option. This way you can extract several plugin instances from one logfile, handy when parsing syslog and the like. +The B option allows you to define the length of time between reads. If +this is not set, the default Interval will be used. + Each B block has the following options to describe how the match should be performed: diff --git a/src/tail.c b/src/tail.c index bcb15725..20f2a9b4 100644 --- a/src/tail.c +++ b/src/tail.c @@ -28,6 +28,7 @@ * * * Instance "exim" + * Interval 60 * * Regex "S=([1-9][0-9]*)" * ExcludeRegex "U=root.*S=" @@ -46,11 +47,13 @@ struct ctail_config_match_s int flags; char *type; char *type_instance; + cdtime_t interval; }; typedef struct ctail_config_match_s ctail_config_match_t; cu_tail_match_t **tail_match_list = NULL; size_t tail_match_list_num = 0; +cdtime_t tail_match_list_intervals[255]; static int ctail_config_add_match_dstype (ctail_config_match_t *cm, oconfig_item_t *ci) @@ -123,7 +126,7 @@ static int ctail_config_add_match_dstype (ctail_config_match_t *cm, } /* int ctail_config_add_match_dstype */ static int ctail_config_add_match (cu_tail_match_t *tm, - const char *plugin_instance, oconfig_item_t *ci) + const char *plugin_instance, oconfig_item_t *ci, cdtime_t interval) { ctail_config_match_t cm; int status; @@ -190,7 +193,7 @@ static int ctail_config_add_match (cu_tail_match_t *tm, if (status == 0) { status = tail_match_add_match_simple (tm, cm.regex, cm.excluderegex, - cm.flags, "tail", plugin_instance, cm.type, cm.type_instance); + cm.flags, "tail", plugin_instance, cm.type, cm.type_instance, interval); if (status != 0) { @@ -209,6 +212,7 @@ static int ctail_config_add_match (cu_tail_match_t *tm, static int ctail_config_add_file (oconfig_item_t *ci) { cu_tail_match_t *tm; + cdtime_t interval = 0; char *plugin_instance = NULL; int num_matches = 0; int status; @@ -233,19 +237,20 @@ static int ctail_config_add_file (oconfig_item_t *ci) { oconfig_item_t *option = ci->children + i; - if (strcasecmp ("Match", option->key) == 0) + if (strcasecmp ("Instance", option->key) == 0) + status = cf_util_get_string (option, &plugin_instance); + else if (strcasecmp ("Interval", option->key) == 0) + cf_util_get_cdtime (option, &interval); + else if (strcasecmp ("Match", option->key) == 0) { - status = ctail_config_add_match (tm, plugin_instance, option); + status = ctail_config_add_match (tm, plugin_instance, option, interval); if (status == 0) num_matches++; /* Be mild with failed matches.. */ status = 0; } - else if (strcasecmp ("Instance", option->key) == 0) - status = cf_util_get_string (option, &plugin_instance); else { - WARNING ("tail plugin: Option `%s' not allowed here.", option->key); status = -1; } @@ -275,6 +280,7 @@ static int ctail_config_add_file (oconfig_item_t *ci) tail_match_list = temp; tail_match_list[tail_match_list_num] = tm; + tail_match_list_intervals[tail_match_list_num] = interval; tail_match_list_num++; } @@ -300,41 +306,43 @@ static int ctail_config (oconfig_item_t *ci) return (0); } /* int ctail_config */ -static int ctail_init (void) +static int ctail_read (user_data_t *ud) { - if (tail_match_list_num == 0) + int status; + + status = tail_match_read ((cu_tail_match_t *)ud->data); + if (status != 0) { - WARNING ("tail plugin: File list is empty. Returning an error."); + ERROR ("tail plugin: tail_match_read failed."); return (-1); } return (0); -} /* int ctail_init */ +} /* int ctail_read */ -static int ctail_read (void) +static int ctail_init (void) { - int success = 0; + struct timespec cb_interval; + char str[255]; + user_data_t ud; size_t i; - for (i = 0; i < tail_match_list_num; i++) + if (tail_match_list_num == 0) { - int status; + WARNING ("tail plugin: File list is empty. Returning an error."); + return (-1); + } - status = tail_match_read (tail_match_list[i]); - if (status != 0) - { - ERROR ("tail plugin: tail_match_read[%zu] failed.", i); - } - else - { - success++; - } + for (i = 0; i < tail_match_list_num; i++) + { + ud.data = (void *)tail_match_list[i]; + ssnprintf(str, sizeof(str), "tail-%zu", i); + CDTIME_T_TO_TIMESPEC (tail_match_list_intervals[i], &cb_interval); + plugin_register_complex_read (NULL, str, ctail_read, &cb_interval, &ud); } - if (success == 0) - return (-1); return (0); -} /* int ctail_read */ +} /* int ctail_init */ static int ctail_shutdown (void) { @@ -355,7 +363,6 @@ void module_register (void) { plugin_register_complex_config ("tail", ctail_config); plugin_register_init ("tail", ctail_init); - plugin_register_read ("tail", ctail_read); plugin_register_shutdown ("tail", ctail_shutdown); } /* void module_register */ diff --git a/src/utils_tail_match.c b/src/utils_tail_match.c index 8ae2208c..13b518b3 100644 --- a/src/utils_tail_match.c +++ b/src/utils_tail_match.c @@ -37,6 +37,7 @@ struct cu_tail_match_simple_s char plugin_instance[DATA_MAX_NAME_LEN]; char type[DATA_MAX_NAME_LEN]; char type_instance[DATA_MAX_NAME_LEN]; + cdtime_t interval; }; typedef struct cu_tail_match_simple_s cu_tail_match_simple_t; @@ -54,6 +55,7 @@ struct cu_tail_match_s int flags; cu_tail_t *tail; + cdtime_t interval; cu_tail_match_match_t *matches; size_t matches_num; }; @@ -88,6 +90,7 @@ static int simple_submit_match (cu_match_t *match, void *user_data) sstrncpy (vl.type_instance, data->type_instance, sizeof (vl.type_instance)); + vl.interval = data->interval; plugin_dispatch_values (&vl); if (match_value->ds_type & UTILS_MATCH_DS_TYPE_GAUGE) @@ -180,6 +183,7 @@ int tail_match_add_match (cu_tail_match_t *obj, cu_match_t *match, obj->matches = temp; obj->matches_num++; + DEBUG ("tail_match_add_match interval %lf", CDTIME_T_TO_DOUBLE(((cu_tail_match_simple_t *)user_data)->interval)); temp = obj->matches + (obj->matches_num - 1); temp->match = match; @@ -193,7 +197,7 @@ int tail_match_add_match (cu_tail_match_t *obj, cu_match_t *match, int tail_match_add_match_simple (cu_tail_match_t *obj, const char *regex, const char *excluderegex, int ds_type, const char *plugin, const char *plugin_instance, - const char *type, const char *type_instance) + const char *type, const char *type_instance, const cdtime_t interval) { cu_match_t *match; cu_tail_match_simple_t *user_data; @@ -221,6 +225,8 @@ int tail_match_add_match_simple (cu_tail_match_t *obj, sstrncpy (user_data->type_instance, type_instance, sizeof (user_data->type_instance)); + user_data->interval = interval; + status = tail_match_add_match (obj, match, simple_submit_match, user_data, free); diff --git a/src/utils_tail_match.h b/src/utils_tail_match.h index 76597457..abd98b63 100644 --- a/src/utils_tail_match.h +++ b/src/utils_tail_match.h @@ -105,7 +105,7 @@ int tail_match_add_match (cu_tail_match_t *obj, cu_match_t *match, int tail_match_add_match_simple (cu_tail_match_t *obj, const char *regex, const char *excluderegex, int ds_type, const char *plugin, const char *plugin_instance, - const char *type, const char *type_instance); + const char *type, const char *type_instance, const cdtime_t interval); /* * NAME -- 2.30.2