diff --git a/src/snmp.c b/src/snmp.c
index 622d64885e989ef49c719c5e819e71b50a4a09f5..8673df199e9ffe135993986a24f5cc1e1607b50e 100644 (file)
--- a/src/snmp.c
+++ b/src/snmp.c
char *type; /* used to find the data_set */
int is_table;
instance_t instance;
+ char *instance_prefix;
oid_t *values;
int values_len;
double scale;
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;
* ! +-> csnmp_config_add_data_type
* ! +-> csnmp_config_add_data_table
* ! +-> csnmp_config_add_data_instance
+ * ! +-> csnmp_config_add_data_instance_prefix
* ! +-> csnmp_config_add_data_values
* +-> csnmp_config_add_host
* +-> csnmp_config_add_host_address
@@ -151,9 +153,7 @@ static int csnmp_config_add_data_type (data_definition_t *dd, oconfig_item_t *ci
return (-1);
}
- if (dd->type != NULL)
- free (dd->type);
-
+ sfree (dd->type);
dd->type = strdup (ci->values[0].value.string);
if (dd->type == NULL)
return (-1);
@@ -204,6 +204,30 @@ static int csnmp_config_add_data_instance (data_definition_t *dd, oconfig_item_t
return (0);
} /* int csnmp_config_add_data_instance */
+static int csnmp_config_add_data_instance_prefix (data_definition_t *dd,
+ oconfig_item_t *ci)
+{
+ if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
+ {
+ WARNING ("snmp plugin: `InstancePrefix' needs exactly one string argument.");
+ return (-1);
+ }
+
+ if (!dd->is_table)
+ {
+ WARNING ("snmp plugin: data %s: InstancePrefix is ignored when `Table' "
+ "is set to `false'.", dd->name);
+ return (-1);
+ }
+
+ sfree (dd->instance_prefix);
+ dd->instance_prefix = strdup (ci->values[0].value.string);
+ if (dd->instance_prefix == NULL)
+ return (-1);
+
+ return (0);
+} /* int csnmp_config_add_data_instance_prefix */
+
static int csnmp_config_add_data_values (data_definition_t *dd, oconfig_item_t *ci)
{
int i;
@@ -221,8 +245,8 @@ static int csnmp_config_add_data_values (data_definition_t *dd, oconfig_item_t *
return (-1);
}
- if (dd->values != NULL)
- free (dd->values);
+ sfree (dd->values);
+ dd->values_len = 0;
dd->values = (oid_t *) malloc (sizeof (oid_t) * ci->values_num);
if (dd->values == NULL)
return (-1);
status = csnmp_config_add_data_table (dd, option);
else if (strcasecmp ("Instance", option->key) == 0)
status = csnmp_config_add_data_instance (dd, option);
+ else if (strcasecmp ("InstancePrefix", option->key) == 0)
+ status = csnmp_config_add_data_instance_prefix (dd, option);
else if (strcasecmp ("Values", option->key) == 0)
status = csnmp_config_add_data_values (dd, option);
else if (strcasecmp ("Shift", option->key) == 0)
if (status != 0)
{
sfree (dd->name);
+ sfree (dd->instance_prefix);
sfree (dd->values);
sfree (dd);
return (-1);
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))
{
@@ -501,10 +526,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 */
}
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++)
@@ -901,7 +925,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);
subid = 0;
@@ -962,13 +986,24 @@ static int csnmp_dispatch_table (host_definition_t *host, data_definition_t *dat
|| (instance_list_ptr->subid == value_table_ptr[0]->subid));
#endif
- if (instance_list_ptr == NULL)
- snprintf (vl.type_instance, sizeof (vl.type_instance), "%u",
- (uint32_t) subid);
- else
- strncpy (vl.type_instance, instance_list_ptr->instance,
- sizeof (vl.type_instance));
- vl.type_instance[sizeof (vl.type_instance) - 1] = '\0';
+ {
+ char temp[DATA_MAX_NAME_LEN];
+
+ if (instance_list_ptr == NULL)
+ snprintf (temp, sizeof (temp), "%u",
+ (uint32_t) subid);
+ else
+ strncpy (temp, instance_list_ptr->instance,
+ sizeof (temp));
+ temp[sizeof (temp) - 1] = '\0';
+
+ if (data->instance_prefix == NULL)
+ strncpy (vl.type_instance, temp, sizeof (vl.type_instance));
+ else
+ snprintf (vl.type_instance, sizeof (vl.type_instance), "%s%s",
+ data->instance_prefix, temp);
+ vl.type_instance[sizeof (vl.type_instance) - 1] = '\0';
+ }
for (i = 0; i < data->values_len; i++)
vl.values[i] = value_table_ptr[i]->value;
@@ -1267,7 +1302,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)
@@ -1298,10 +1333,12 @@ static int csnmp_read_value (host_definition_t *host, data_definition_t *data)
for (vb = res->variables; vb != NULL; vb = vb->next_variable)
{
+#if COLLECT_DEBUG
char buffer[1024];
snprint_variable (buffer, sizeof (buffer),
vb->name, vb->name_length, vb);
DEBUG ("snmp plugin: Got this variable: %s", buffer);
+#endif /* COLLECT_DEBUG */
for (i = 0; i < data->values_len; i++)
if (snmp_oid_compare (data->values[i].oid, data->values[i].oid_len,
@@ -1322,8 +1359,12 @@ static int csnmp_read_value (host_definition_t *host, data_definition_t *data)
static int csnmp_read_host (host_definition_t *host)
{
int i;
+ time_t time_start;
+ time_t time_end;
- DEBUG ("snmp plugin: csnmp_read_host (%s);", host->name);
+ time_start = time (NULL);
+ DEBUG ("snmp plugin: csnmp_read_host (%s) started at %u;", host->name,
+ (unsigned int) time_start);
if (host->sess_handle == NULL)
csnmp_host_open_session (host);
csnmp_read_value (host, data);
}
+ time_end = time (NULL);
+ DEBUG ("snmp plugin: csnmp_read_host (%s) finished at %u;", host->name,
+ (unsigned int) time_end);
+ 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->interval, time_end - time_start);
+ }
+
return (0);
} /* int csnmp_read_host */
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);
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);