From f0c4eb8af9128f960f1d7dff62ef2305bbc7724a Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Fri, 14 Sep 2007 09:51:29 +0200 Subject: [PATCH] snmp plugin: Added the options `Scale' and `Shift' to Data-blocks.. ..to correct the values returned by SNMP-agents. --- ChangeLog | 4 ++++ src/collectd-snmp.pod | 20 ++++++++++++++++++ src/snmp.c | 49 ++++++++++++++++++++++++++++++++++++++----- 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 66d339da..74d2a0a8 100644 --- 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. diff --git a/src/collectd-snmp.pod b/src/collectd-snmp.pod index 0f7e3a4e..4e546da8 100644 --- a/src/collectd-snmp.pod +++ b/src/collectd-snmp.pod @@ -11,12 +11,14 @@ collectd-snmp - Documentation of collectd's C Type "voltage" Table false Instance "input_line1" + Scale 0.1 Values "SNMPv2-SMI::enterprises.6050.5.4.1.1.2.1" Type "users" Table false Instance "" + Shift -1 Values "HOST-RESOURCES-MIB::hrSystemNumUsers.0" @@ -148,6 +150,24 @@ If B is set to I, each I must be the OID of exactly one value, e.Eg. C for the third counter of incoming traffic. +=item B I + +The gauge-values returned by the SNMP-agent are multiplied by I. 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 I + +I is added to gauge-values returned by the SNMP-agent after they have +been multiplied by any B 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 diff --git a/src/snmp.c b/src/snmp.c index 2c4c930c..dd3763d0 100644 --- a/src/snmp.c +++ b/src/snmp.c @@ -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); -- 2.30.2