[collectd] Exporting the collectd's loop variable for plugins

Luboš Staněk lubek at users.sourceforge.net
Tue Nov 7 19:32:31 CET 2006


Hi Florian,
the quick exit has one negative feature.

The restart (stop & start) of the daemon could occur so fast that the
initial plugin_read_all() starts at the same second as the last write.

The effect of this is a bunch of the plugins' complaints at the first
read about the same time of the update:

Nov  7 18:22:50 test1 collectd[27432]: rrd_update failed: users.rrd:
illegal attempt to update using time 1162920170 when last update time is
1162920170 (minimum one second step)
Nov  7 18:22:50 test1 collectd[27432]: rrd_update failed:
traffic-eth0.rrd: illegal attempt to update using time 1162920170 when
last update time is 1162920170 (minimum one second step)
...


I would recommend to start the plugin_read_all() at the next second.
I tried to use the same variables and functions used inside the step
loop to wait for the next second before going into the loop.

The effect of the slow start is that collectd (local) will always start
the first plugin_read_all at least at the next second, no matter how
many plugins it will load.

Maybe it looks useless but I would like to preserve the fast stop. If we
will use some plugin's cleanup function, the stop will take more time
and this precaution will not be in effect.

Best regards,
Lubos



E.g. something like:


--- collectd.c.old	2006-11-04 13:52:35.000000000 +0100
+++ collectd.c	2006-11-07 19:14:20.000000000 +0100
@@ -149,6 +149,15 @@
 	struct timeval tv_next;
 	struct timespec ts_wait;

+	/* record the second to start the first read loop earliest */
+	if (gettimeofday (&tv_next, NULL) < 0)
+	{
+		syslog (LOG_ERR, "gettimeofday failed: %s", strerror (errno));
+		return (-1);
+	}
+	tv_next.tv_sec += 1;
+	tv_next.tv_usec = 0;
+
 	step = atoi (COLLECTD_STEP);
 	if (step <= 0)
 		step = 10;
@@ -174,6 +183,25 @@

 	plugin_init_all ();

+	if (gettimeofday (&tv_now, NULL) < 0)
+	{
+		syslog (LOG_ERR, "gettimeofday failed: %s", strerror (errno));
+		return (-1);
+	}
+
+	/* check & wait for the recorded time to start the loop */
+	if (timeval_sub_timespec (&tv_next, &tv_now, &ts_wait) == 0)
+	{
+		while (nanosleep (&ts_wait, &ts_wait) == -1)
+		{
+			if (errno != EINTR)
+			{
+				syslog (LOG_ERR, "nanosleep failed: %s", strerror (errno));
+				break;
+			}
+		}
+	}
+
 	while (loop == 0)
 	{
 		if (gettimeofday (&tv_next, NULL) < 0)



More information about the collectd mailing list