From: Florian Forster Date: Mon, 28 Sep 2009 13:42:42 +0000 (+0200) Subject: netapp plugin: Refactor system statistics. X-Git-Tag: collectd-4.9.0~73^2~22 X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=e2bccaceb05a79592d33cf38b66a195e3ee5ec04;p=collectd.git netapp plugin: Refactor system statistics. Same procedure as before: Instead of using the “service handler”, create a cfg_system_t pointer if the user wants system statistics. Then call cna_query_system instead of the service handler. The “GetSystemPerfData” block has been renamed to “System” and the “Multiplier” option has been replaced by the “Interval” option. --- diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index 9030cffb..fa38b89c 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -1667,8 +1667,13 @@ Required capabilities are documented below. User "username" Password "aef4Aebe" Interval 30 - - + + Interval 30 + GetCPULoad true + GetInterfaces true + GetDiskOps true + GetDiskIO true + Interval 30 GetNameCache true @@ -1766,7 +1771,7 @@ Default: 1 =back -=head3 The GetSystemPerfData block +=head3 The System block This will collect various performance data about the whole system. @@ -1775,6 +1780,10 @@ B To get this data the collectd user needs the =over 4 +=item B I + +Collect disk statistics every I seconds. + =item B B|B If you set this option to true the current CPU usage will be read. This will be diff --git a/src/netapp.c b/src/netapp.c index 469fd107..c294f696 100644 --- a/src/netapp.c +++ b/src/netapp.c @@ -51,6 +51,8 @@ typedef struct cna_interval_s cna_interval_t; #define CFG_SYSTEM_ALL 0x0F typedef struct { uint32_t flags; + cna_interval_t interval; + na_elem_t *query; } cfg_system_t; /*! @@ -221,6 +223,7 @@ struct host_config_s { cfg_service_t *services; cfg_disk_t *cfg_disk; cfg_wafl_t *cfg_wafl; + cfg_system_t *cfg_system; volume_t *volumes; struct host_config_s *next; @@ -1193,24 +1196,45 @@ static void query_volume_perf_data(host_config_t *host, na_elem_t *out, void *da } /* for (volume) */ } /* }}} void query_volume_perf_data */ -/* Data corresponding to */ -static void collect_perf_system_data(host_config_t *host, na_elem_t *out, void *data) { /* {{{ */ +/* Data corresponding to */ +static int cna_handle_system_data (const char *hostname, /* {{{ */ + cfg_system_t *cfg_system, na_elem_t *data) +{ + na_elem_t *instances; + na_elem_t *counter; + na_elem_iter_t counter_iter; + counter_t disk_read = 0, disk_written = 0; counter_t net_recv = 0, net_sent = 0; counter_t cpu_busy = 0, cpu_total = 0; - unsigned int counter_flags = 0; + uint32_t counter_flags = 0; - cfg_system_t *cfg_system = data; const char *instance; time_t timestamp; - na_elem_t *counter; - timestamp = (time_t) na_child_get_uint64(out, "timestamp", 0); - out = na_elem_child(na_elem_child(out, "instances"), "instance-data"); - instance = na_child_get_string(out, "name"); + timestamp = (time_t) na_child_get_uint64 (data, "timestamp", 0); - na_elem_iter_t iter = na_child_iterator(na_elem_child(out, "counters")); - for (counter = na_iterator_next(&iter); counter; counter = na_iterator_next(&iter)) { + instances = na_elem_child(na_elem_child (data, "instances"), "instance-data"); + if (instances == NULL) + { + ERROR ("netapp plugin: cna_handle_system_data: " + "na_elem_child (\"instances\") failed."); + return (-1); + } + + instance = na_child_get_string (instances, "name"); + if (instance == NULL) + { + ERROR ("netapp plugin: cna_handle_system_data: " + "na_child_get_string (\"name\") failed."); + return (-1); + } + + counter_iter = na_child_iterator (na_elem_child (instances, "counters")); + for (counter = na_iterator_next (&counter_iter); + counter != NULL; + counter = na_iterator_next (&counter_iter)) + { const char *name; uint64_t value; @@ -1243,29 +1267,91 @@ static void collect_perf_system_data(host_config_t *host, na_elem_t *out, void * } else if ((cfg_system->flags & CFG_SYSTEM_OPS) && (value > 0) && (strlen(name) > 4) && (!strcmp(name + strlen(name) - 4, "_ops"))) { - submit_counter (host->name, instance, "disk_ops_complex", name, + submit_counter (hostname, instance, "disk_ops_complex", name, (counter_t) value, timestamp); } } /* for (counter) */ if ((cfg_system->flags & CFG_SYSTEM_DISK) - && ((counter_flags & 0x03) == 0x03)) - submit_two_counters (host->name, instance, "disk_octets", NULL, + && (HAS_ALL_FLAGS (counter_flags, 0x01 | 0x02))) + submit_two_counters (hostname, instance, "disk_octets", NULL, disk_read, disk_written, timestamp); if ((cfg_system->flags & CFG_SYSTEM_NET) - && ((counter_flags & 0x0c) == 0x0c)) - submit_two_counters (host->name, instance, "if_octets", NULL, + && (HAS_ALL_FLAGS (counter_flags, 0x04 | 0x08))) + submit_two_counters (hostname, instance, "if_octets", NULL, net_recv, net_sent, timestamp); if ((cfg_system->flags & CFG_SYSTEM_CPU) - && ((counter_flags & 0x30) == 0x30)) { - submit_counter (host->name, instance, "cpu", "system", + && (HAS_ALL_FLAGS (counter_flags, 0x10 | 0x20))) + { + submit_counter (hostname, instance, "cpu", "system", cpu_busy, timestamp); - submit_counter (host->name, instance, "cpu", "idle", + submit_counter (hostname, instance, "cpu", "idle", cpu_total - cpu_busy, timestamp); } -} /* }}} void collect_perf_system_data */ + + return (0); +} /* }}} int cna_handle_system_data */ + +static int cna_setup_system (cfg_system_t *cs) /* {{{ */ +{ + if (cs == NULL) + return (EINVAL); + + if (cs->query != NULL) + return (0); + + cs->query = na_elem_new ("perf-object-get-instances"); + if (cs->query == NULL) + { + ERROR ("netapp plugin: na_elem_new failed."); + return (-1); + } + na_child_add_string (cs->query, "objectname", "system"); + + return (0); +} /* }}} int cna_setup_system */ + +static int cna_query_system (host_config_t *host) /* {{{ */ +{ + na_elem_t *data; + int status; + time_t now; + + if (host == NULL) + return (EINVAL); + + /* If system statistics were not configured, return without doing anything. */ + if (host->cfg_system == NULL) + return (0); + + now = time (NULL); + if ((host->cfg_system->interval.interval + host->cfg_system->interval.last_read) > now) + return (0); + + status = cna_setup_system (host->cfg_system); + if (status != 0) + return (status); + assert (host->cfg_system->query != NULL); + + data = na_server_invoke_elem(host->srv, host->cfg_system->query); + if (na_results_status (data) != NA_OK) + { + ERROR ("netapp plugin: cna_query_system: na_server_invoke_elem failed: %s", + na_results_reason (data)); + na_elem_free (data); + return (-1); + } + + status = cna_handle_system_data (host->name, host->cfg_system, data); + + if (status == 0) + host->cfg_system->interval.last_read = now; + + na_elem_free (data); + return (status); +} /* }}} int cna_query_system */ /* * Configuration handling @@ -1609,35 +1695,36 @@ static int cna_config_wafl(host_config_t *host, oconfig_item_t *ci) /* {{{ */ return (0); } /* }}} int cna_config_wafl */ -/* Corresponds to a block */ +/* Corresponds to a block */ static int cna_config_system (host_config_t *host, /* {{{ */ oconfig_item_t *ci, const cfg_service_t *default_service) { - int i; - cfg_service_t *service; cfg_system_t *cfg_system; + int i; - service = malloc(sizeof(*service)); - if (service == NULL) - return (-1); - memset (service, 0, sizeof (*service)); - *service = *default_service; - service->handler = collect_perf_system_data; + if ((host == NULL) || (ci == NULL)) + return (EINVAL); - cfg_system = malloc(sizeof(*cfg_system)); - if (cfg_system == NULL) { - sfree (service); - return (-1); + if (host->cfg_system == NULL) + { + cfg_system = malloc (sizeof (*cfg_system)); + if (cfg_system == NULL) + return (ENOMEM); + memset (cfg_system, 0, sizeof (*cfg_system)); + + /* Set default flags */ + cfg_system->flags = CFG_SYSTEM_ALL; + cfg_system->query = NULL; + + host->cfg_system = cfg_system; } - memset (cfg_system, 0, sizeof (*cfg_system)); - cfg_system->flags = CFG_SYSTEM_ALL; - service->data = cfg_system; + cfg_system = host->cfg_system; for (i = 0; i < ci->children_num; ++i) { oconfig_item_t *item = ci->children + i; - if (!strcasecmp(item->key, "Multiplier")) { - cna_config_get_multiplier (item, service); + if (strcasecmp(item->key, "Interval") == 0) { + cna_config_get_interval (item, &cfg_system->interval); } else if (!strcasecmp(item->key, "GetCPULoad")) { cna_config_bool_to_flag (item, &cfg_system->flags, CFG_SYSTEM_CPU); } else if (!strcasecmp(item->key, "GetInterfaces")) { @@ -1648,13 +1735,10 @@ static int cna_config_system (host_config_t *host, /* {{{ */ cna_config_bool_to_flag (item, &cfg_system->flags, CFG_SYSTEM_DISK); } else { WARNING ("netapp plugin: The %s config option is not allowed within " - "`GetSystemPerfData' blocks.", item->key); + "`System' blocks.", item->key); } } - service->next = host->services; - host->services = service; - return (0); } /* }}} int cna_config_system */ @@ -1715,7 +1799,7 @@ static host_config_t *cna_config_host (const oconfig_item_t *ci, /* {{{ */ host->interval = item->values[0].value.number; } else if (!strcasecmp(item->key, "GetVolumePerfData")) { cna_config_volume_performance(host, item); - } else if (!strcasecmp(item->key, "GetSystemPerfData")) { + } else if (!strcasecmp(item->key, "System")) { cna_config_system(host, item, &default_service); } else if (!strcasecmp(item->key, "WAFL")) { cna_config_wafl(host, item); @@ -1801,10 +1885,7 @@ static int cna_init(void) { /* {{{ */ for (service = host->services; service; service = service->next) { service->interval = host->interval * service->multiplier; - if (service->handler == collect_perf_system_data) { - service->query = na_elem_new("perf-object-get-instances"); - na_child_add_string(service->query, "objectname", "system"); - } else if (service->handler == query_volume_perf_data) { + if (service->handler == query_volume_perf_data) { service->query = na_elem_new("perf-object-get-instances"); na_child_add_string(service->query, "objectname", "volume"); e = na_elem_new("counters"); @@ -1894,6 +1975,7 @@ static int cna_read(void) { /* {{{ */ cna_query_wafl (host); cna_query_disk (host); + cna_query_system (host); } return 0; } /* }}} int cna_read */