snmp plugin: Added the options `Scale' and `Shift' to Data-blocks..
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Fri, 14 Sep 2007 07:51:29 +0000 (09:51 +0200)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Fri, 14 Sep 2007 07:51:29 +0000 (09:51 +0200)
..to correct the values returned by SNMP-agents.

ChangeLog
src/collectd-snmp.pod
src/snmp.c

index 66d339d..74d2a0a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+yyyy-mm-dd, Version 4.2.0
+       * snmp plugin: Added the options `Scale' and `Shift' to Data-blocks to
+         correct the values returned by SNMP-agents.
+
 yyyy-mm-dd, Version 4.1.2
        * apcups plugin: Fix reporting of the `load percent' data.
 
index 0f7e3a4..4e546da 100644 (file)
@@ -11,12 +11,14 @@ collectd-snmp - Documentation of collectd's C<snmp plugin>
       Type "voltage"
       Table false
       Instance "input_line1"
+      Scale 0.1
       Values "SNMPv2-SMI::enterprises.6050.5.4.1.1.2.1"
     </Data>
     <Data "hr_users">
       Type "users"
       Table false
       Instance ""
+      Shift -1
       Values "HOST-RESOURCES-MIB::hrSystemNumUsers.0"
     </Data>
     <Data "std_traffic">
@@ -148,6 +150,24 @@ If B<Table> is set to I<false>, each I<OID> must be the OID of exactly one
 value, e.E<nbsp>g. C<IF-MIB::ifInOctets.3> for the third counter of incoming
 traffic.
 
+=item B<Scale> I<Value>
+
+The gauge-values returned by the SNMP-agent are multiplied by I<Value>.  This
+is useful when values are transfered as a fixed point real number. For example,
+thermometers may transfer B<243> but actually mean B<24.3>, so you can specify
+a scale value of B<0.1> to correct this. The default value is of course B<1.0>.
+
+This value is not applied to counter-values.
+
+=item B<Shift> I<Value>
+
+I<Value> is added to gauge-values returned by the SNMP-agent after they have
+been multiplied by any B<Scale> value. If, for example, a thermometer returns
+degrees Kelvin you could specify a shift of B<273.15> here to store values in
+degrees Celsius. The default value is is course B<0.0>.
+
+This value is not applied to counter-values.
+
 =back
 
 =head2 The Host block
index 2c4c930..dd3763d 100644 (file)
@@ -53,6 +53,8 @@ struct data_definition_s
   instance_t instance;
   oid_t *values;
   int values_len;
+  double scale;
+  double shift;
   struct data_definition_s *next;
 };
 typedef struct data_definition_s data_definition_t;
@@ -245,6 +247,34 @@ static int csnmp_config_add_data_values (data_definition_t *dd, oconfig_item_t *
   return (0);
 } /* int csnmp_config_add_data_instance */
 
+static int csnmp_config_add_data_shift (data_definition_t *dd, oconfig_item_t *ci)
+{
+  if ((ci->values_num != 1)
+      || (ci->values[0].type != OCONFIG_TYPE_NUMBER))
+  {
+    WARNING ("snmp plugin: The `Scale' config option needs exactly one number argument.");
+    return (-1);
+  }
+
+  dd->shift = ci->values[0].value.number;
+
+  return (0);
+} /* int csnmp_config_add_data_shift */
+
+static int csnmp_config_add_data_scale (data_definition_t *dd, oconfig_item_t *ci)
+{
+  if ((ci->values_num != 1)
+      || (ci->values[0].type != OCONFIG_TYPE_NUMBER))
+  {
+    WARNING ("snmp plugin: The `Scale' config option needs exactly one number argument.");
+    return (-1);
+  }
+
+  dd->scale = ci->values[0].value.number;
+
+  return (0);
+} /* int csnmp_config_add_data_scale */
+
 static int csnmp_config_add_data (oconfig_item_t *ci)
 {
   data_definition_t *dd;
@@ -269,6 +299,8 @@ static int csnmp_config_add_data (oconfig_item_t *ci)
     free (dd);
     return (-1);
   }
+  dd->scale = 1.0;
+  dd->shift = 0.0;
 
   for (i = 0; i < ci->children_num; i++)
   {
@@ -283,6 +315,10 @@ static int csnmp_config_add_data (oconfig_item_t *ci)
       status = csnmp_config_add_data_instance (dd, option);
     else if (strcasecmp ("Values", option->key) == 0)
       status = csnmp_config_add_data_values (dd, option);
+    else if (strcasecmp ("Shift", option->key) == 0)
+      status = csnmp_config_add_data_shift (dd, option);
+    else if (strcasecmp ("Scale", option->key) == 0)
+      status = csnmp_config_add_data_scale (dd, option);
     else
     {
       WARNING ("snmp plugin: Option `%s' not allowed here.", option->key);
@@ -645,7 +681,8 @@ static void csnmp_host_open_session (host_definition_t *host)
   }
 } /* void csnmp_host_open_session */
 
-static value_t csnmp_value_list_to_value (struct variable_list *vl, int type)
+static value_t csnmp_value_list_to_value (struct variable_list *vl, int type,
+    double scale, double shift)
 {
   value_t ret;
   uint64_t temp = 0;
@@ -680,7 +717,7 @@ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type)
   {
     ret.gauge = NAN;
     if (defined != 0)
-      ret.gauge = temp;
+      ret.gauge = (scale * temp) + shift;
   }
 
   return (ret);
@@ -910,7 +947,7 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data)
     }
     else
     {
-      value_t val = csnmp_value_list_to_value (vb, DS_TYPE_COUNTER);
+      value_t val = csnmp_value_list_to_value (vb, DS_TYPE_COUNTER, 1.0, 0.0);
       snprintf (il->instance, sizeof (il->instance),
          "%llu", val.counter);
     }
@@ -962,7 +999,8 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data)
       if (vt != NULL)
       {
        vt->subid = vb->name[vb->name_length - 1];
-       vt->value = csnmp_value_list_to_value (vb, ds->ds[i].type);
+       vt->value = csnmp_value_list_to_value (vb, ds->ds[i].type,
+           data->scale, data->shift);
        vt->next = NULL;
 
        if (value_table_ptr[i] == NULL)
@@ -1096,7 +1134,8 @@ static int csnmp_read_value (host_definition_t *host, data_definition_t *data)
     for (i = 0; i < data->values_len; i++)
       if (snmp_oid_compare (data->values[i].oid, data->values[i].oid_len,
            vb->name, vb->name_length) == 0)
-       vl.values[i] = csnmp_value_list_to_value (vb, ds->ds[i].type);
+       vl.values[i] = csnmp_value_list_to_value (vb, ds->ds[i].type,
+           data->scale, data->shift);
   } /* for (res->variables) */
 
   snmp_free_pdu (res);