From: Florian Forster Date: Sat, 14 Feb 2009 18:18:23 +0000 (+0100) Subject: timediff match: Add a match for values with an invalid time. X-Git-Tag: collectd-4.6.0~31 X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=892fbd80737d74ee6a6ab5d05d5fbbb76e43c530;p=collectd.git timediff match: Add a match for values with an invalid time. The time is compared to the server's local time and values which differ too much (configurable, of course) are matched. --- diff --git a/configure.in b/configure.in index d8cee585..6b2adc18 100644 --- a/configure.in +++ b/configure.in @@ -3064,6 +3064,7 @@ AC_PLUGIN([libvirt], [$plugin_libvirt], [Virtual machine statistics]) AC_PLUGIN([load], [$plugin_load], [System load]) AC_PLUGIN([logfile], [yes], [File logging plugin]) AC_PLUGIN([match_regex], [yes], [The regex match]) +AC_PLUGIN([match_timediff], [yes], [The timediff match]) AC_PLUGIN([match_value], [yes], [The value match]) AC_PLUGIN([mbmon], [yes], [Query mbmond]) AC_PLUGIN([memcached], [yes], [memcached statistics]) @@ -3263,6 +3264,7 @@ Configuration: load . . . . . . . . $enable_load logfile . . . . . . . $enable_logfile match_regex . . . . . $enable_match_regex + match_timediff . . . $enable_match_timediff match_value . . . . . $enable_match_value mbmon . . . . . . . . $enable_mbmon memcached . . . . . . $enable_memcached diff --git a/src/Makefile.am b/src/Makefile.am index 0c3b476b..5c691b26 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -421,6 +421,14 @@ collectd_LDADD += "-dlopen" match_regex.la collectd_DEPENDENCIES += match_regex.la endif +if BUILD_PLUGIN_MATCH_TIMEDIFF +pkglib_LTLIBRARIES += match_timediff.la +match_timediff_la_SOURCES = match_timediff.c +match_timediff_la_LDFLAGS = -module -avoid-version +collectd_LDADD += "-dlopen" match_timediff.la +collectd_DEPENDENCIES += match_timediff.la +endif + if BUILD_PLUGIN_MATCH_VALUE pkglib_LTLIBRARIES += match_value.la match_value_la_SOURCES = match_value.c diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index 0077d243..28f86a82 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -3151,6 +3151,50 @@ Example: Plugin "^foobar$" +=item B + +Matches values that have a time which differs from the time on the server. + +This match is mainly intended for servers that receive values over the +C plugin and write them to disk using the C plugin. RRDtool +is very sensitive to the timestamp used when updating the RRD files. In +particular, the time must be ever increasing. If a misbehaving client sends one +packet with a timestamp far in the future, all further packets with a correct +time will be ignored because of that one packet. What's worse, such corrupted +RRD files are hard to fix. + +This match lets one match all values B a specified time range +(relative to the server's time), so you can use the B target (see below) +to ignore the value, for example. + +Available options: + +=over 4 + +=item B I + +Matches all values that are I of the server's time by I or more +seconds. Set to zero for no limit. Either B or B must be +non-zero. + +=item B I + +Matches all values that are I of the server's time by I or +more seconds. Set to zero for no limit. Either B or B must be +non-zero. + +=back + +Example: + + + Future 300 + Past 3600 + + +This example matches all values that are five minutes or more ahead of the +server or one hour (or more) lagging behind. + =item B Matches the actual value of data sources against given minimumE/ maximum diff --git a/src/match_timediff.c b/src/match_timediff.c new file mode 100644 index 00000000..673c8d9d --- /dev/null +++ b/src/match_timediff.c @@ -0,0 +1,169 @@ +/** + * collectd - src/match_timediff.c + * Copyright (C) 2008,2009 Florian 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. + * + * 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 + * + * Authors: + * Florian Forster + **/ + +#include "collectd.h" +#include "common.h" +#include "utils_cache.h" +#include "filter_chain.h" + +#define SATISFY_ALL 0 +#define SATISFY_ANY 1 + +/* + * private data types + */ +struct mt_match_s; +typedef struct mt_match_s mt_match_t; +struct mt_match_s +{ + time_t future; + time_t past; +}; + +/* + * internal helper functions + */ +static int mt_config_add_time_t (time_t *ret_value, /* {{{ */ + oconfig_item_t *ci) +{ + + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) + { + ERROR ("timediff match: `%s' needs exactly one numeric argument.", + ci->key); + return (-1); + } + + *ret_value = (time_t) ci->values[0].value.number; + + return (0); +} /* }}} int mt_config_add_time_t */ + +static int mt_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ +{ + mt_match_t *m; + int status; + int i; + + m = (mt_match_t *) malloc (sizeof (*m)); + if (m == NULL) + { + ERROR ("mt_create: malloc failed."); + return (-ENOMEM); + } + memset (m, 0, sizeof (*m)); + + m->future = 0; + m->past = 0; + + status = 0; + for (i = 0; i < ci->children_num; i++) + { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp ("Future", child->key) == 0) + status = mt_config_add_time_t (&m->future, child); + else if (strcasecmp ("Past", child->key) == 0) + status = mt_config_add_time_t (&m->past, child); + else + { + ERROR ("timediff match: The `%s' configuration option is not " + "understood and will be ignored.", child->key); + status = 0; + } + + if (status != 0) + break; + } + + /* Additional sanity-checking */ + while (status == 0) + { + if ((m->future == 0) && (m->past == 0)) + { + ERROR ("timediff match: Either `Future' or `Past' must be configured. " + "This match will be ignored."); + status = -1; + } + + break; + } + + if (status != 0) + { + free (m); + return (status); + } + + *user_data = m; + return (0); +} /* }}} int mt_create */ + +static int mt_destroy (void **user_data) /* {{{ */ +{ + if (user_data != NULL) + { + sfree (*user_data); + } + + return (0); +} /* }}} int mt_destroy */ + +static int mt_match (const data_set_t __attribute__((unused)) *ds, /* {{{ */ + const value_list_t *vl, + notification_meta_t __attribute__((unused)) **meta, void **user_data) +{ + mt_match_t *m; + time_t now; + + if ((user_data == NULL) || (*user_data == NULL)) + return (-1); + + m = *user_data; + now = time (NULL); + + if (m->future != 0) + { + if (vl->time >= (now + m->future)) + return (FC_MATCH_MATCHES); + } + + if (m->past != 0) + { + if (vl->time <= (now - m->past)) + return (FC_MATCH_MATCHES); + } + + return (FC_MATCH_NO_MATCH); +} /* }}} int mt_match */ + +void module_register (void) +{ + match_proc_t mproc; + + memset (&mproc, 0, sizeof (mproc)); + mproc.create = mt_create; + mproc.destroy = mt_destroy; + mproc.match = mt_match; + fc_register_match ("value", mproc); +} /* module_register */ + +/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */