snmp plugin: Improve the timing method, so that hosts are queried more steadily.
authorFlorian Forster <octo@huhu.verplant.org>
Thu, 4 Oct 2007 13:34:57 +0000 (15:34 +0200)
committerFlorian Forster <octo@huhu.verplant.org>
Thu, 4 Oct 2007 13:34:57 +0000 (15:34 +0200)
src/snmp.c

index 0c2b79a..4bcdcf7 100644 (file)
@@ -64,16 +64,16 @@ struct host_definition_s
   char *community;
   int version;
   void *sess_handle;
-  int16_t skip_num;
-  int16_t skip_left;
+  uint32_t interval;
+  time_t next_update;
   data_definition_t **data_list;
   int data_list_len;
-  enum          /****************************************************/
-  {             /* This host..                                      */
-    STATE_IDLE, /* - just sits there until `skip_left < interval_g' */
-    STATE_WAIT, /* - waits to be queried.                           */
-    STATE_BUSY  /* - is currently being queried.                    */
-  } state;      /****************************************************/
+  enum          /******************************************************/
+  {             /* This host..                                        */
+    STATE_IDLE, /* - just sits there until `next_update < interval_g' */
+    STATE_WAIT, /* - waits to be queried.                             */
+    STATE_BUSY  /* - is currently being queried.                      */
+  } state;      /******************************************************/
   struct host_definition_s *next;
 };
 typedef struct host_definition_s host_definition_t;
@@ -456,8 +456,6 @@ static int csnmp_config_add_host_collect (host_definition_t *host,
 
 static int csnmp_config_add_host_interval (host_definition_t *hd, oconfig_item_t *ci)
 {
-  int interval;
-
   if ((ci->values_num != 1)
       || (ci->values[0].type != OCONFIG_TYPE_NUMBER))
   {
@@ -465,10 +463,9 @@ static int csnmp_config_add_host_interval (host_definition_t *hd, oconfig_item_t
     return (-1);
   }
 
-  interval = (int) ci->values[0].value.number;
-  hd->skip_num = interval;
-  if (hd->skip_num < 0)
-    hd->skip_num = 0;
+  hd->interval = (int) ci->values[0].value.number;
+  if (hd->interval < 0)
+    hd->interval = 0;
 
   return (0);
 } /* int csnmp_config_add_host_interval */
@@ -499,8 +496,8 @@ static int csnmp_config_add_host (oconfig_item_t *ci)
   }
 
   hd->sess_handle = NULL;
-  hd->skip_num = 0;
-  hd->skip_left = 0;
+  hd->interval = 0;
+  hd->next_update = 0;
   hd->state = STATE_IDLE;
 
   for (i = 0; i < ci->children_num; i++)
@@ -728,7 +725,7 @@ static int csnmp_dispatch_table (host_definition_t *host, data_definition_t *dat
   vl.host[sizeof (vl.host) - 1] = '\0';
   strcpy (vl.plugin, "snmp");
 
-  vl.interval = host->skip_num;
+  vl.interval = host->interval;
   vl.time = time (NULL);
 
   for (instance_list_ptr = instance_list;
@@ -1072,7 +1069,7 @@ static int csnmp_read_value (host_definition_t *host, data_definition_t *data)
   strncpy (vl.type_instance, data->instance.string, sizeof (vl.type_instance));
   vl.type_instance[sizeof (vl.type_instance) - 1] = '\0';
 
-  vl.interval = host->skip_num;
+  vl.interval = host->interval;
 
   req = snmp_pdu_create (SNMP_MSG_GET);
   if (req == NULL)
@@ -1152,13 +1149,13 @@ static int csnmp_read_host (host_definition_t *host)
   }
 
   time_end = time (NULL);
-  DEBUG ("snmp plugin: csnmp_read_host (%s)  at %u;", host->name,
+  DEBUG ("snmp plugin: csnmp_read_host (%s) finished at %u;", host->name,
       (unsigned int) time_end);
-  if ((time_end - time_start) > host->skip_num)
+  if ((time_end - time_start) > host->interval)
   {
     WARNING ("snmp plugin: Host `%s' should be queried every %i seconds, "
        "but reading all values takes %i seconds.",
-       host->name, host->skip_num, time_end - time_start);
+       host->name, host->interval, time_end - time_start);
   }
 
   return (0);
@@ -1210,18 +1207,18 @@ static int csnmp_init (void)
   for (host = host_head; host != NULL; host = host->next)
   {
     threads_num++;
-    /* We need to initialize `skip_num' here, because `interval_g' isn't
+    /* We need to initialize `interval' here, because `interval_g' isn't
      * initialized during `configure'. */
-    host->skip_left = interval_g;
-    if (host->skip_num == 0)
+    host->next_update = time (NULL);
+    if (host->interval == 0)
     {
-      host->skip_num = interval_g;
+      host->interval = interval_g;
     }
-    else if (host->skip_num < interval_g)
+    else if (host->interval < interval_g)
     {
-      host->skip_num = interval_g;
+      host->interval = interval_g;
       WARNING ("snmp plugin: Data for host `%s' will be collected every %i seconds.",
-         host->name, host->skip_num);
+         host->name, host->interval);
     }
 
     csnmp_host_open_session (host);
@@ -1268,13 +1265,12 @@ static int csnmp_read (void)
     if (host->state != STATE_IDLE)
       continue;
 
-    host->skip_left -= interval_g;
-    if (host->skip_left >= interval_g)
+    /* Skip this host if the next or a later iteration will be sufficient. */
+    if (host->next_update >= (now + interval_g))
       continue;
 
     host->state = STATE_WAIT;
-
-    host->skip_left = host->skip_num;
+    host->next_update = now + host->interval;
   } /* for (host) */
 
   pthread_cond_broadcast (&host_cond);