/* * This callback reads the user/system CPU time for each cgroup. */ static int read_cpuacct_procs(const char *dirname, char const *cgroup_name, void *user_data) { char abs_path[PATH_MAX]; struct stat statbuf; char buf[1024]; int status; FILE *fh; if (ignorelist_match(il_cgroup, cgroup_name)) return (0); ssnprintf(abs_path, sizeof(abs_path), "%s/%s", dirname, cgroup_name); status = lstat(abs_path, &statbuf); if (status != 0) { ERROR("cgroups plugin: stat (\"%s\") failed.", abs_path); return (-1); } /* We are only interested in directories, so skip everything else. */ if (!S_ISDIR(statbuf.st_mode)) return (0); ssnprintf(abs_path, sizeof(abs_path), "%s/%s/cpuacct.stat", dirname, cgroup_name); fh = fopen(abs_path, "r"); if (fh == NULL) { char errbuf[1024]; ERROR("cgroups plugin: fopen (\"%s\") failed: %s", abs_path, sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } while (fgets(buf, sizeof(buf), fh) != NULL) { char *fields[8]; int numfields = 0; char *key; size_t key_len; value_t value; /* Expected format: * * user: 12345 * system: 23456 * * Or: * * user 12345 * system 23456 */ strstripnewline(buf); numfields = strsplit(buf, fields, STATIC_ARRAY_SIZE(fields)); if (numfields != 2) continue; key = fields[0]; key_len = strlen(key); if (key_len < 2) continue; /* Strip colon off the first column, if found */ if (key[key_len - 1] == ':') key[key_len - 1] = 0; status = parse_value(fields[1], &value, DS_TYPE_DERIVE); if (status != 0) continue; cgroups_submit_one(cgroup_name, key, value); } fclose(fh); return (0); } /* int read_cpuacct_procs */
static int read_pmu (void) /* {{{ */ { int i; /* The upper limit here is just a safeguard. If there is a system with * more than 100 batteries, this can easily be increased. */ for (i = 0; i < 100; i++) { FILE *fh; char buffer[1024]; char filename[PATH_MAX]; char plugin_instance[DATA_MAX_NAME_LEN]; gauge_t current = NAN; gauge_t voltage = NAN; gauge_t charge = NAN; ssnprintf (filename, sizeof (filename), PROC_PMU_PATH_FORMAT, i); if (access (filename, R_OK) != 0) break; ssnprintf (plugin_instance, sizeof (plugin_instance), "%i", i); fh = fopen (filename, "r"); if (fh == NULL) { if (errno == ENOENT) break; else if ((errno == EAGAIN) || (errno == EINTR)) continue; else return (errno); } while (fgets (buffer, sizeof (buffer), fh) != NULL) { char *fields[8]; int numfields; numfields = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); if (numfields < 3) continue; if (strcmp ("current", fields[0]) == 0) strtogauge (fields[2], ¤t); else if (strcmp ("voltage", fields[0]) == 0) strtogauge (fields[2], &voltage); else if (strcmp ("charge", fields[0]) == 0) strtogauge (fields[2], &charge); } fclose (fh); fh = NULL; battery_submit (plugin_instance, "charge", charge / 1000.0); battery_submit (plugin_instance, "current", current / 1000.0); battery_submit (plugin_instance, "voltage", voltage / 1000.0); } if (i == 0) return (ENOENT); return (0); } /* }}} int read_pmu */
static int c_psql_write (const data_set_t *ds, const value_list_t *vl, user_data_t *ud) { c_psql_database_t *db; char time_str[32]; char values_name_str[1024]; char values_type_str[1024]; char values_str[1024]; const char *params[9]; int success = 0; int i; if ((ud == NULL) || (ud->data == NULL)) { log_err ("c_psql_write: Invalid user data."); return -1; } db = ud->data; assert (db->database != NULL); assert (db->writers != NULL); if (cdtime_to_iso8601 (time_str, sizeof (time_str), vl->time) == 0) { log_err ("c_psql_write: Failed to convert time to ISO 8601 format"); return -1; } if (values_name_to_sqlarray (ds, values_name_str, sizeof (values_name_str)) == NULL) return -1; #define VALUE_OR_NULL(v) ((((v) == NULL) || (*(v) == '\0')) ? NULL : (v)) params[0] = time_str; params[1] = vl->host; params[2] = vl->plugin; params[3] = VALUE_OR_NULL(vl->plugin_instance); params[4] = vl->type; params[5] = VALUE_OR_NULL(vl->type_instance); params[6] = values_name_str; #undef VALUE_OR_NULL pthread_mutex_lock (&db->db_lock); if (0 != c_psql_check_connection (db)) { pthread_mutex_unlock (&db->db_lock); return -1; } if ((db->commit_interval > 0) && (db->next_commit == 0)) c_psql_begin (db); for (i = 0; i < db->writers_num; ++i) { c_psql_writer_t *writer; PGresult *res; writer = db->writers[i]; if (values_type_to_sqlarray (ds, values_type_str, sizeof (values_type_str), writer->store_rates) == NULL) { pthread_mutex_unlock (&db->db_lock); return -1; } if (values_to_sqlarray (ds, vl, values_str, sizeof (values_str), writer->store_rates) == NULL) { pthread_mutex_unlock (&db->db_lock); return -1; } params[7] = values_type_str; params[8] = values_str; res = PQexecParams (db->conn, writer->statement, STATIC_ARRAY_SIZE (params), NULL, (const char *const *)params, NULL, NULL, /* return text data */ 0); if ((PGRES_COMMAND_OK != PQresultStatus (res)) && (PGRES_TUPLES_OK != PQresultStatus (res))) { PQclear (res); if ((CONNECTION_OK != PQstatus (db->conn)) && (0 == c_psql_check_connection (db))) { /* try again */ res = PQexecParams (db->conn, writer->statement, STATIC_ARRAY_SIZE (params), NULL, (const char *const *)params, NULL, NULL, /* return text data */ 0); if ((PGRES_COMMAND_OK == PQresultStatus (res)) || (PGRES_TUPLES_OK == PQresultStatus (res))) { PQclear (res); success = 1; continue; } } log_err ("Failed to execute SQL query: %s", PQerrorMessage (db->conn)); log_info ("SQL query was: '%s', " "params: %s, %s, %s, %s, %s, %s, %s, %s", writer->statement, params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7]); /* this will abort any current transaction -> restart */ if (db->next_commit > 0) c_psql_commit (db); pthread_mutex_unlock (&db->db_lock); return -1; } PQclear (res); success = 1; } if ((db->next_commit > 0) && (cdtime () > db->next_commit)) c_psql_commit (db); pthread_mutex_unlock (&db->db_lock); if (! success) return -1; return 0; } /* c_psql_write */
static int read_file(const char *path) { FILE *fh; char key_buffer[4096]; char value_buffer[4096]; char *key_ptr; char *value_ptr; char *key_fields[256]; char *value_fields[256]; int key_fields_num; int value_fields_num; int status; int i; fh = fopen(path, "r"); if (fh == NULL) { ERROR("protocols plugin: fopen (%s) failed: %s.", path, sstrerror(errno, key_buffer, sizeof(key_buffer))); return (-1); } status = -1; while (42) { clearerr(fh); key_ptr = fgets(key_buffer, sizeof(key_buffer), fh); if (key_ptr == NULL) { if (feof(fh) != 0) { status = 0; break; } else if (ferror(fh) != 0) { ERROR("protocols plugin: Reading from %s failed.", path); break; } else { ERROR("protocols plugin: fgets failed for an unknown reason."); break; } } /* if (key_ptr == NULL) */ value_ptr = fgets(value_buffer, sizeof(value_buffer), fh); if (value_ptr == NULL) { ERROR("protocols plugin: read_file (%s): Could not read values line.", path); break; } key_ptr = strchr(key_buffer, ':'); if (key_ptr == NULL) { ERROR("protocols plugin: Could not find protocol name in keys line."); break; } *key_ptr = 0; key_ptr++; value_ptr = strchr(value_buffer, ':'); if (value_ptr == NULL) { ERROR("protocols plugin: Could not find protocol name " "in values line."); break; } *value_ptr = 0; value_ptr++; if (strcmp(key_buffer, value_buffer) != 0) { ERROR("protocols plugin: Protocol names in keys and values lines " "don't match: `%s' vs. `%s'.", key_buffer, value_buffer); break; } key_fields_num = strsplit(key_ptr, key_fields, STATIC_ARRAY_SIZE(key_fields)); value_fields_num = strsplit(value_ptr, value_fields, STATIC_ARRAY_SIZE(value_fields)); if (key_fields_num != value_fields_num) { ERROR("protocols plugin: Number of fields in keys and values lines " "don't match: %i vs %i.", key_fields_num, value_fields_num); break; } for (i = 0; i < key_fields_num; i++) { if (values_list != NULL) { char match_name[2 * DATA_MAX_NAME_LEN]; ssnprintf(match_name, sizeof(match_name), "%s:%s", key_buffer, key_fields[i]); if (ignorelist_match(values_list, match_name)) continue; } /* if (values_list != NULL) */ submit(key_buffer, key_fields[i], value_fields[i]); } /* for (i = 0; i < key_fields_num; i++) */ } /* while (42) */ fclose(fh); return (status); } /* int read_file */
static int uptime_init (void) /* {{{ */ { /* * On most unix systems the uptime is calculated by looking at the boot * time (stored in unix time, since epoch) and the current one. We are * going to do the same, reading the boot time value while executing * the uptime_init function (there is no need to read, every time the * plugin_read is called, a value that won't change). However, since * uptime_init is run only once, if the function fails in retrieving * the boot time, the plugin is unregistered and there is no chance to * try again later. Nevertheless, this is very unlikely to happen. */ #if KERNEL_LINUX unsigned long starttime; char buffer[1024]; int ret; FILE *fh; ret = 0; fh = fopen (STAT_FILE, "r"); if (fh == NULL) { char errbuf[1024]; ERROR ("uptime plugin: Cannot open "STAT_FILE": %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } while (fgets (buffer, 1024, fh) != NULL) { /* look for the btime string and read the value */ ret = sscanf (buffer, "btime %lu", &starttime); /* avoid further loops if btime has been found and read * correctly (hopefully) */ if (ret == 1) break; } fclose (fh); /* loop done, check if no value has been found/read */ if (ret != 1) { ERROR ("uptime plugin: No value read from "STAT_FILE""); return (-1); } boottime = (time_t) starttime; if (boottime == 0) { ERROR ("uptime plugin: btime read from "STAT_FILE", " "but `boottime' is zero!"); return (-1); } /* #endif KERNEL_LINUX */ #elif HAVE_LIBKSTAT kstat_t *ksp; kstat_named_t *knp; ksp = NULL; knp = NULL; /* kstats chain already opened by update_kstat (using *kc), verify everything went fine. */ if (kc == NULL) { ERROR ("uptime plugin: kstat chain control structure not available."); return (-1); } ksp = kstat_lookup (kc, "unix", 0, "system_misc"); if (ksp == NULL) { ERROR ("uptime plugin: Cannot find unix:0:system_misc kstat."); return (-1); } if (kstat_read (kc, ksp, NULL) < 0) { ERROR ("uptime plugin: kstat_read failed."); return (-1); } knp = (kstat_named_t *) kstat_data_lookup (ksp, "boot_time"); if (knp == NULL) { ERROR ("uptime plugin: kstat_data_lookup (boot_time) failed."); return (-1); } boottime = (time_t) knp->value.ui32; if (boottime == 0) { ERROR ("uptime plugin: kstat_data_lookup returned success, " "but `boottime' is zero!"); return (-1); } /* #endif HAVE_LIBKSTAT */ # elif HAVE_SYS_SYSCTL_H struct timeval boottv = { 0 }; size_t boottv_len; int status; int mib[] = { CTL_KERN, KERN_BOOTTIME }; boottv_len = sizeof (boottv); status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &boottv, &boottv_len, /* new_value = */ NULL, /* new_length = */ 0); if (status != 0) { char errbuf[1024]; ERROR ("uptime plugin: No value read from sysctl interface: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } boottime = boottv.tv_sec; if (boottime == 0) { ERROR ("uptime plugin: sysctl(3) returned success, " "but `boottime' is zero!"); return (-1); } /* #endif HAVE_SYS_SYSCTL_H */ #elif HAVE_PERFSTAT int status; perfstat_cpu_total_t cputotal; int hertz; status = perfstat_cpu_total(NULL, &cputotal, sizeof(perfstat_cpu_total_t), 1); if (status < 0) { char errbuf[1024]; ERROR ("uptime plugin: perfstat_cpu_total: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } hertz = sysconf(_SC_CLK_TCK); if (hertz <= 0) hertz = HZ; boottime = time(NULL) - cputotal.lbolt / hertz; #endif /* HAVE_PERFSTAT */ return (0); } /* }}} int uptime_init */
int config_cores_parse(const oconfig_item_t *ci, core_groups_list_t *cgl) { if (ci == NULL || cgl == NULL) return -EINVAL; if (ci->values_num == 0 || ci->values_num > MAX_CORES) return -EINVAL; core_group_t cgroups[MAX_CORES] = {{0}}; size_t cg_idx = 0; /* index for cgroups array */ int ret = 0; for (int i = 0; i < ci->values_num; i++) { if (ci->values[i].type != OCONFIG_TYPE_STRING) { WARNING(UTIL_NAME ": The %s option requires string arguments.", ci->key); return -EINVAL; } } if (ci->values_num == 1 && ci->values[0].value.string && strlen(ci->values[0].value.string) == 0) return 0; for (int i = 0; i < ci->values_num; i++) { size_t n; _Bool grouped = 1; char str[DATA_MAX_NAME_LEN]; unsigned cores[MAX_CORES] = {0}; if (cg_idx >= STATIC_ARRAY_SIZE(cgroups)) { ERROR(UTIL_NAME ": Configuration exceeds maximum number of cores: %" PRIsz, STATIC_ARRAY_SIZE(cgroups)); ret = -EINVAL; goto parse_error; } if ((ci->values[i].value.string == NULL) || (strlen(ci->values[i].value.string) == 0)) { ERROR(UTIL_NAME ": Failed to parse parameters for %s option.", ci->key); ret = -EINVAL; goto parse_error; } ret = check_core_grouping(str, ci->values[i].value.string, sizeof(str), &grouped); if (ret != 0) { ERROR(UTIL_NAME ": Failed to parse config option [%d] %s.", i, ci->values[i].value.string); goto parse_error; } n = str_list_to_nums(str, cores, STATIC_ARRAY_SIZE(cores)); if (n == 0) { ERROR(UTIL_NAME ": Failed to parse config option [%d] %s.", i, ci->values[i].value.string); ret = -EINVAL; goto parse_error; } if (grouped) { cgroups[cg_idx].desc = strdup(ci->values[i].value.string); if (cgroups[cg_idx].desc == NULL) { ERROR(UTIL_NAME ": Failed to allocate description."); ret = -ENOMEM; goto parse_error; } cgroups[cg_idx].cores = calloc(n, sizeof(*cgroups[cg_idx].cores)); if (cgroups[cg_idx].cores == NULL) { ERROR(UTIL_NAME ": Failed to allocate cores for cgroup."); ret = -ENOMEM; goto parse_error; } for (size_t j = 0; j < n; j++) cgroups[cg_idx].cores[j] = cores[j]; cgroups[cg_idx].num_cores = n; cg_idx++; } else { for (size_t j = 0; j < n && cg_idx < STATIC_ARRAY_SIZE(cgroups); j++) { char desc[DATA_MAX_NAME_LEN]; snprintf(desc, sizeof(desc), "%u", cores[j]); cgroups[cg_idx].desc = strdup(desc); if (cgroups[cg_idx].desc == NULL) { ERROR(UTIL_NAME ": Failed to allocate desc for core %u.", cores[j]); ret = -ENOMEM; goto parse_error; } cgroups[cg_idx].cores = calloc(1, sizeof(*(cgroups[cg_idx].cores))); if (cgroups[cg_idx].cores == NULL) { ERROR(UTIL_NAME ": Failed to allocate cgroup for core %u.", cores[j]); ret = -ENOMEM; goto parse_error; } cgroups[cg_idx].num_cores = 1; cgroups[cg_idx].cores[0] = cores[j]; cg_idx++; } } } cgl->cgroups = calloc(cg_idx, sizeof(*cgl->cgroups)); if (cgl->cgroups == NULL) { ERROR(UTIL_NAME ": Failed to allocate core groups."); ret = -ENOMEM; goto parse_error; } cgl->num_cgroups = cg_idx; for (size_t i = 0; i < cg_idx; i++) cgl->cgroups[i] = cgroups[i]; return 0; parse_error: cg_idx = 0; while (cg_idx < STATIC_ARRAY_SIZE(cgroups) && cgroups[cg_idx].desc != NULL) { sfree(cgroups[cg_idx].desc); sfree(cgroups[cg_idx].cores); cg_idx++; } return ret; }
#include <pthread.h> #include <rrd.h> /* * Private variables */ static int rra_timespans[] = { 3600, 86400, 604800, 2678400, 31622400 }; static int rra_timespans_num = STATIC_ARRAY_SIZE (rra_timespans); static char *rra_types[] = { "AVERAGE", "MIN", "MAX" }; static int rra_types_num = STATIC_ARRAY_SIZE (rra_types); #if !defined(HAVE_THREADSAFE_LIBRRD) || !HAVE_THREADSAFE_LIBRRD static pthread_mutex_t librrd_lock = PTHREAD_MUTEX_INITIALIZER; #endif /* * Private functions
{"load_fifteen", "load", "", "longterm", -1, -1}, {"cpu_user", "cpu", "user", "value", -1, -1}, {"cpu_system", "cpu", "system", "value", -1, -1}, {"cpu_idle", "cpu", "idle", "value", -1, -1}, {"cpu_nice", "cpu", "nice", "value", -1, -1}, {"cpu_wio", "cpu", "wait", "value", -1, -1}, {"mem_free", "memory", "free", "value", -1, -1}, {"mem_shared", "memory", "shared", "value", -1, -1}, {"mem_buffers", "memory", "buffered", "value", -1, -1}, {"mem_cached", "memory", "cached", "value", -1, -1}, {"mem_total", "memory", "total", "value", -1, -1}, {"bytes_in", "if_octets", "", "rx", -1, -1}, {"bytes_out", "if_octets", "", "tx", -1, -1}, {"pkts_in", "if_packets", "", "rx", -1, -1}, {"pkts_out", "if_packets", "", "tx", -1, -1}}; static size_t metric_map_len_default = STATIC_ARRAY_SIZE(metric_map_default); static metric_map_t *metric_map = NULL; static size_t metric_map_len = 0; static c_avl_tree_t *staging_tree; static pthread_mutex_t staging_lock = PTHREAD_MUTEX_INITIALIZER; static metric_map_t *metric_lookup(const char *key) /* {{{ */ { metric_map_t *map; size_t map_len; size_t i; /* Search the user-supplied table first.. */ map = metric_map;
static inline int item_watched(int i) { assert (i >= 0); assert (i < ((STATIC_ARRAY_SIZE (watch_items) + 1) * 32)); return watch_items[i / 32] & FLAG (i); }
/* for reading status version 4 */ static int multi4_read (const char *name, FILE *fh) { char buffer[1024]; char *fields[11]; const int max_fields = STATIC_ARRAY_SIZE (fields); int fields_num, read = 0; long long sum_users = 0; while (fgets (buffer, sizeof (buffer), fh) != NULL) { fields_num = openvpn_strsplit (buffer, fields, max_fields); /* status file is generated by openvpn/multi.c:multi_print_status() * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/multi.c * * The line we're expecting has 9 fields. We ignore all lines * with more or less fields. */ if (fields_num != 9) continue; if (strcmp (fields[0], "CLIENT_LIST") != 0) continue; if (collect_user_count) /* If so, sum all users, ignore the individuals*/ { sum_users += 1; } if (collect_individual_users) { if (new_naming_schema) { /* plugin inst = file name, type inst = fields[1] */ iostats_submit (name, /* vpn instance */ fields[1], /* "Common Name" */ atoll (fields[4]), /* "Bytes Received" */ atoll (fields[5])); /* "Bytes Sent" */ } else { /* plugin inst = fields[1], type inst = "" */ iostats_submit (fields[1], /* "Common Name" */ NULL, /* unused when in multimode */ atoll (fields[4]), /* "Bytes Received" */ atoll (fields[5])); /* "Bytes Sent" */ } } read = 1; } if (collect_user_count) { numusers_submit(name, name, sum_users); read = 1; } return (read); } /* int multi4_read */
static int read_acpi_callback(char const *dir, /* {{{ */ char const *power_supply, void *user_data) { int *battery_index = user_data; gauge_t power = NAN; gauge_t voltage = NAN; gauge_t capacity_charged = NAN; gauge_t capacity_full = NAN; gauge_t capacity_design = NAN; _Bool charging = 0; _Bool is_current = 0; char const *plugin_instance; char filename[PATH_MAX]; char buffer[1024]; FILE *fh; ssnprintf(filename, sizeof(filename), "%s/%s/state", dir, power_supply); fh = fopen(filename, "r"); if (fh == NULL) { if ((errno == EAGAIN) || (errno == EINTR) || (errno == ENOENT)) return (0); else return (errno); } /* * [11:00] <@tokkee> $ cat /proc/acpi/battery/BAT1/state * [11:00] <@tokkee> present: yes * [11:00] <@tokkee> capacity state: ok * [11:00] <@tokkee> charging state: charging * [11:00] <@tokkee> present rate: 1724 mA * [11:00] <@tokkee> remaining capacity: 4136 mAh * [11:00] <@tokkee> present voltage: 12428 mV */ while (fgets(buffer, sizeof(buffer), fh) != NULL) { char *fields[8]; int numfields; numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); if (numfields < 3) continue; if ((strcmp(fields[0], "charging") == 0) && (strcmp(fields[1], "state:") == 0)) { if (strcmp(fields[2], "charging") == 0) charging = 1; else charging = 0; continue; } /* The unit of "present rate" depends on the battery. Modern * batteries export power (watts), older batteries (used to) * export current (amperes). We check the fourth column and try * to find old batteries this way. */ if ((strcmp(fields[0], "present") == 0) && (strcmp(fields[1], "rate:") == 0)) { strtogauge(fields[2], &power); if ((numfields >= 4) && (strcmp("mA", fields[3]) == 0)) is_current = 1; } else if ((strcmp(fields[0], "remaining") == 0) && (strcmp(fields[1], "capacity:") == 0)) strtogauge(fields[2], &capacity_charged); else if ((strcmp(fields[0], "present") == 0) && (strcmp(fields[1], "voltage:") == 0)) strtogauge(fields[2], &voltage); } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */ fclose(fh); if (!charging) power *= -1.0; /* FIXME: This is a dirty hack for backwards compatibility: The battery * plugin, for a very long time, has had the plugin_instance * hard-coded to "0". So, to keep backwards compatibility, we'll use * "0" for the first battery we find and the power_supply name for all * following. This should be reverted in a future major version. */ plugin_instance = (*battery_index == 0) ? "0" : power_supply; (*battery_index)++; read_acpi_full_capacity(dir, power_supply, &capacity_full, &capacity_design); submit_capacity(plugin_instance, capacity_charged * PROC_ACPI_FACTOR, capacity_full * PROC_ACPI_FACTOR, capacity_design * PROC_ACPI_FACTOR); battery_submit(plugin_instance, is_current ? "current" : "power", power * PROC_ACPI_FACTOR); battery_submit(plugin_instance, "voltage", voltage * PROC_ACPI_FACTOR); return 0; } /* }}} int read_acpi_callback */
/* for reading status version 1 */ static int multi1_read (const char *name, FILE *fh) { char buffer[1024]; char *fields[10]; int fields_num, found_header = 0; long long sum_users = 0; /* read the file until the "ROUTING TABLE" line is found (no more info after) */ while (fgets (buffer, sizeof (buffer), fh) != NULL) { if (strcmp (buffer, "ROUTING TABLE\n") == 0) break; if (strcmp (buffer, V1STRING) == 0) { found_header = 1; continue; } /* skip the first lines until the client list section is found */ if (found_header == 0) /* we can't start reading data until this string is found */ continue; fields_num = openvpn_strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); if (fields_num < 4) continue; if (collect_user_count) /* If so, sum all users, ignore the individuals*/ { sum_users += 1; } if (collect_individual_users) { if (new_naming_schema) { iostats_submit (name, /* vpn instance */ fields[0], /* "Common Name" */ atoll (fields[2]), /* "Bytes Received" */ atoll (fields[3])); /* "Bytes Sent" */ } else { iostats_submit (fields[0], /* "Common Name" */ NULL, /* unused when in multimode */ atoll (fields[2]), /* "Bytes Received" */ atoll (fields[3])); /* "Bytes Sent" */ } } } if (ferror (fh)) return (0); if (collect_user_count) numusers_submit(name, name, sum_users); return (1); } /* int multi1_read */
static int single_read (const char *name, FILE *fh) { char buffer[1024]; char *fields[4]; const int max_fields = STATIC_ARRAY_SIZE (fields); int fields_num, read = 0; derive_t link_rx, link_tx; derive_t tun_rx, tun_tx; derive_t pre_compress, post_compress; derive_t pre_decompress, post_decompress; derive_t overhead_rx, overhead_tx; link_rx = 0; link_tx = 0; tun_rx = 0; tun_tx = 0; pre_compress = 0; post_compress = 0; pre_decompress = 0; post_decompress = 0; while (fgets (buffer, sizeof (buffer), fh) != NULL) { fields_num = openvpn_strsplit (buffer, fields, max_fields); /* status file is generated by openvpn/sig.c:print_status() * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/sig.c * * The line we're expecting has 2 fields. We ignore all lines * with more or less fields. */ if (fields_num != 2) { continue; } if (strcmp (fields[0], "TUN/TAP read bytes") == 0) { /* read from the system and sent over the tunnel */ tun_tx = atoll (fields[1]); } else if (strcmp (fields[0], "TUN/TAP write bytes") == 0) { /* read from the tunnel and written in the system */ tun_rx = atoll (fields[1]); } else if (strcmp (fields[0], "TCP/UDP read bytes") == 0) { link_rx = atoll (fields[1]); } else if (strcmp (fields[0], "TCP/UDP write bytes") == 0) { link_tx = atoll (fields[1]); } else if (strcmp (fields[0], "pre-compress bytes") == 0) { pre_compress = atoll (fields[1]); } else if (strcmp (fields[0], "post-compress bytes") == 0) { post_compress = atoll (fields[1]); } else if (strcmp (fields[0], "pre-decompress bytes") == 0) { pre_decompress = atoll (fields[1]); } else if (strcmp (fields[0], "post-decompress bytes") == 0) { post_decompress = atoll (fields[1]); } } iostats_submit (name, "traffic", link_rx, link_tx); /* we need to force this order to avoid negative values with these unsigned */ overhead_rx = (((link_rx - pre_decompress) + post_decompress) - tun_rx); overhead_tx = (((link_tx - post_compress) + pre_compress) - tun_tx); iostats_submit (name, "overhead", overhead_rx, overhead_tx); if (collect_compression) { compression_submit (name, "data_in", post_decompress, pre_decompress); compression_submit (name, "data_out", pre_compress, post_compress); } read = 1; return (read); } /* int single_read */
static int memory_read_internal(value_list_t *vl) { #if HAVE_HOST_STATISTICS kern_return_t status; vm_statistics_data_t vm_data; mach_msg_type_number_t vm_data_len; gauge_t wired; gauge_t active; gauge_t inactive; gauge_t free; if (!port_host || !pagesize) return -1; vm_data_len = sizeof(vm_data) / sizeof(natural_t); if ((status = host_statistics(port_host, HOST_VM_INFO, (host_info_t)&vm_data, &vm_data_len)) != KERN_SUCCESS) { ERROR("memory-plugin: host_statistics failed and returned the value %i", (int)status); return -1; } /* * From <http://docs.info.apple.com/article.html?artnum=107918>: * * Wired memory * This information can't be cached to disk, so it must stay in RAM. * The amount depends on what applications you are using. * * Active memory * This information is currently in RAM and actively being used. * * Inactive memory * This information is no longer being used and has been cached to * disk, but it will remain in RAM until another application needs * the space. Leaving this information in RAM is to your advantage if * you (or a client of your computer) come back to it later. * * Free memory * This memory is not being used. */ wired = (gauge_t)(((uint64_t)vm_data.wire_count) * ((uint64_t)pagesize)); active = (gauge_t)(((uint64_t)vm_data.active_count) * ((uint64_t)pagesize)); inactive = (gauge_t)(((uint64_t)vm_data.inactive_count) * ((uint64_t)pagesize)); free = (gauge_t)(((uint64_t)vm_data.free_count) * ((uint64_t)pagesize)); MEMORY_SUBMIT("wired", wired, "active", active, "inactive", inactive, "free", free); /* #endif HAVE_HOST_STATISTICS */ #elif HAVE_SYSCTLBYNAME /* * vm.stats.vm.v_page_size: 4096 * vm.stats.vm.v_page_count: 246178 * vm.stats.vm.v_free_count: 28760 * vm.stats.vm.v_wire_count: 37526 * vm.stats.vm.v_active_count: 55239 * vm.stats.vm.v_inactive_count: 113730 * vm.stats.vm.v_cache_count: 10809 */ const char *sysctl_keys[8] = { "vm.stats.vm.v_page_size", "vm.stats.vm.v_page_count", "vm.stats.vm.v_free_count", "vm.stats.vm.v_wire_count", "vm.stats.vm.v_active_count", "vm.stats.vm.v_inactive_count", "vm.stats.vm.v_cache_count", NULL}; double sysctl_vals[8]; for (int i = 0; sysctl_keys[i] != NULL; i++) { int value; size_t value_len = sizeof(value); if (sysctlbyname(sysctl_keys[i], (void *)&value, &value_len, NULL, 0) == 0) { sysctl_vals[i] = value; DEBUG("memory plugin: %26s: %g", sysctl_keys[i], sysctl_vals[i]); } else { sysctl_vals[i] = NAN; } } /* for (sysctl_keys) */ /* multiply all all page counts with the pagesize */ for (int i = 1; sysctl_keys[i] != NULL; i++) if (!isnan(sysctl_vals[i])) sysctl_vals[i] *= sysctl_vals[0]; MEMORY_SUBMIT("free", (gauge_t)sysctl_vals[2], "wired", (gauge_t)sysctl_vals[3], "active", (gauge_t)sysctl_vals[4], "inactive", (gauge_t)sysctl_vals[5], "cache", (gauge_t)sysctl_vals[6]); /* #endif HAVE_SYSCTLBYNAME */ #elif KERNEL_LINUX FILE *fh; char buffer[1024]; char *fields[8]; int numfields; bool detailed_slab_info = false; gauge_t mem_total = 0; gauge_t mem_used = 0; gauge_t mem_buffered = 0; gauge_t mem_cached = 0; gauge_t mem_free = 0; gauge_t mem_slab_total = 0; gauge_t mem_slab_reclaimable = 0; gauge_t mem_slab_unreclaimable = 0; if ((fh = fopen("/proc/meminfo", "r")) == NULL) { WARNING("memory: fopen: %s", STRERRNO); return -1; } while (fgets(buffer, sizeof(buffer), fh) != NULL) { gauge_t *val = NULL; if (strncasecmp(buffer, "MemTotal:", 9) == 0) val = &mem_total; else if (strncasecmp(buffer, "MemFree:", 8) == 0) val = &mem_free; else if (strncasecmp(buffer, "Buffers:", 8) == 0) val = &mem_buffered; else if (strncasecmp(buffer, "Cached:", 7) == 0) val = &mem_cached; else if (strncasecmp(buffer, "Slab:", 5) == 0) val = &mem_slab_total; else if (strncasecmp(buffer, "SReclaimable:", 13) == 0) { val = &mem_slab_reclaimable; detailed_slab_info = true; } else if (strncasecmp(buffer, "SUnreclaim:", 11) == 0) { val = &mem_slab_unreclaimable; detailed_slab_info = true; } else continue; numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); if (numfields < 2) continue; *val = 1024.0 * atof(fields[1]); } if (fclose(fh)) { WARNING("memory: fclose: %s", STRERRNO); } if (mem_total < (mem_free + mem_buffered + mem_cached + mem_slab_total)) return -1; mem_used = mem_total - (mem_free + mem_buffered + mem_cached + mem_slab_total); /* SReclaimable and SUnreclaim were introduced in kernel 2.6.19 * They sum up to the value of Slab, which is available on older & newer * kernels. So SReclaimable/SUnreclaim are submitted if available, and Slab * if not. */ if (detailed_slab_info) MEMORY_SUBMIT("used", mem_used, "buffered", mem_buffered, "cached", mem_cached, "free", mem_free, "slab_unrecl", mem_slab_unreclaimable, "slab_recl", mem_slab_reclaimable); else MEMORY_SUBMIT("used", mem_used, "buffered", mem_buffered, "cached", mem_cached, "free", mem_free, "slab", mem_slab_total); /* #endif KERNEL_LINUX */ #elif HAVE_LIBKSTAT /* Most of the additions here were taken as-is from the k9toolkit from * Brendan Gregg and are subject to change I guess */ long long mem_used; long long mem_free; long long mem_lock; long long mem_kern; long long mem_unus; long long arcsize; long long pp_kernel; long long physmem; long long availrmem; if (ksp == NULL) return -1; if (ksz == NULL) return -1; mem_used = get_kstat_value(ksp, "pagestotal"); mem_free = get_kstat_value(ksp, "pagesfree"); mem_lock = get_kstat_value(ksp, "pageslocked"); arcsize = get_kstat_value(ksz, "size"); pp_kernel = get_kstat_value(ksp, "pp_kernel"); physmem = get_kstat_value(ksp, "physmem"); availrmem = get_kstat_value(ksp, "availrmem"); mem_kern = 0; mem_unus = 0; if ((mem_used < 0LL) || (mem_free < 0LL) || (mem_lock < 0LL)) { WARNING("memory plugin: one of used, free or locked is negative."); return -1; } mem_unus = physmem - mem_used; if (mem_used < (mem_free + mem_lock)) { /* source: http://wesunsolve.net/bugid/id/4909199 * this seems to happen when swap space is small, e.g. 2G on a 32G system * we will make some assumptions here * educated solaris internals help welcome here */ DEBUG("memory plugin: pages total is smaller than \"free\" " "+ \"locked\". This is probably due to small " "swap space"); mem_free = availrmem; mem_used = 0; } else { mem_used -= mem_free + mem_lock; } /* mem_kern is accounted for in mem_lock */ if (pp_kernel < mem_lock) { mem_kern = pp_kernel; mem_lock -= pp_kernel; } else { mem_kern = mem_lock; mem_lock = 0; } mem_used *= pagesize; /* If this overflows you have some serious */ mem_free *= pagesize; /* memory.. Why not call me up and give me */ mem_lock *= pagesize; /* some? ;) */ mem_kern *= pagesize; /* it's 2011 RAM is cheap */ mem_unus *= pagesize; mem_kern -= arcsize; MEMORY_SUBMIT("used", (gauge_t)mem_used, "free", (gauge_t)mem_free, "locked", (gauge_t)mem_lock, "kernel", (gauge_t)mem_kern, "arc", (gauge_t)arcsize, "unusable", (gauge_t)mem_unus); /* #endif HAVE_LIBKSTAT */ #elif HAVE_SYSCTL int mib[] = {CTL_VM, VM_METER}; struct vmtotal vmtotal = {0}; gauge_t mem_active; gauge_t mem_inactive; gauge_t mem_free; size_t size; size = sizeof(vmtotal); if (sysctl(mib, 2, &vmtotal, &size, NULL, 0) < 0) { WARNING("memory plugin: sysctl failed: %s", STRERRNO); return -1; } assert(pagesize > 0); mem_active = (gauge_t)(vmtotal.t_arm * pagesize); mem_inactive = (gauge_t)((vmtotal.t_rm - vmtotal.t_arm) * pagesize); mem_free = (gauge_t)(vmtotal.t_free * pagesize); MEMORY_SUBMIT("active", mem_active, "inactive", mem_inactive, "free", mem_free); /* #endif HAVE_SYSCTL */ #elif HAVE_LIBSTATGRAB sg_mem_stats *ios; ios = sg_get_mem_stats(); if (ios == NULL) return -1; MEMORY_SUBMIT("used", (gauge_t)ios->used, "cached", (gauge_t)ios->cache, "free", (gauge_t)ios->free); /* #endif HAVE_LIBSTATGRAB */ #elif HAVE_PERFSTAT perfstat_memory_total_t pmemory = {0}; if (perfstat_memory_total(NULL, &pmemory, sizeof(pmemory), 1) < 0) { WARNING("memory plugin: perfstat_memory_total failed: %s", STRERRNO); return -1; } /* Unfortunately, the AIX documentation is not very clear on how these * numbers relate to one another. The only thing is states explcitly * is: * real_total = real_process + real_free + numperm + real_system * * Another segmentation, which would be closer to the numbers reported * by the "svmon" utility, would be: * real_total = real_free + real_inuse * real_inuse = "active" + real_pinned + numperm */ MEMORY_SUBMIT("free", (gauge_t)(pmemory.real_free * pagesize), "cached", (gauge_t)(pmemory.numperm * pagesize), "system", (gauge_t)(pmemory.real_system * pagesize), "user", (gauge_t)(pmemory.real_process * pagesize)); #endif /* HAVE_PERFSTAT */ return 0; } /* }}} int memory_read_internal */
static int init (void) { #if PROCESSOR_CPU_LOAD_INFO kern_return_t status; port_host = mach_host_self (); status = host_processors (port_host, &cpu_list, &cpu_list_len); if (status == KERN_INVALID_ARGUMENT) { ERROR ("cpu plugin: Don't have a privileged host control port. " "The most common cause for this problem is " "that collectd is running without root " "privileges, which are required to read CPU " "load information. " "<https://collectd.org/bugs/22>"); cpu_list_len = 0; return (-1); } if (status != KERN_SUCCESS) { ERROR ("cpu plugin: host_processors() failed with status %d.", (int) status); cpu_list_len = 0; return (-1); } INFO ("cpu plugin: Found %i processor%s.", (int) cpu_list_len, cpu_list_len == 1 ? "" : "s"); /* #endif PROCESSOR_CPU_LOAD_INFO */ #elif defined(HAVE_LIBKSTAT) kstat_t *ksp_chain; numcpu = 0; if (kc == NULL) return (-1); /* Solaris doesn't count linear.. *sigh* */ for (numcpu = 0, ksp_chain = kc->kc_chain; (numcpu < MAX_NUMCPU) && (ksp_chain != NULL); ksp_chain = ksp_chain->ks_next) if (strncmp (ksp_chain->ks_module, "cpu_stat", 8) == 0) ksp[numcpu++] = ksp_chain; /* #endif HAVE_LIBKSTAT */ #elif CAN_USE_SYSCTL size_t numcpu_size; int mib[2] = {CTL_HW, HW_NCPU}; int status; numcpu = 0; numcpu_size = sizeof (numcpu); status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &numcpu, &numcpu_size, NULL, 0); if (status == -1) { char errbuf[1024]; WARNING ("cpu plugin: sysctl: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } /* #endif CAN_USE_SYSCTL */ #elif defined (HAVE_SYSCTLBYNAME) size_t numcpu_size; numcpu_size = sizeof (numcpu); if (sysctlbyname ("hw.ncpu", &numcpu, &numcpu_size, NULL, 0) < 0) { char errbuf[1024]; WARNING ("cpu plugin: sysctlbyname(hw.ncpu): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } #ifdef HAVE_SYSCTL_KERN_CP_TIMES numcpu_size = sizeof (maxcpu); if (sysctlbyname("kern.smp.maxcpus", &maxcpu, &numcpu_size, NULL, 0) < 0) { char errbuf[1024]; WARNING ("cpu plugin: sysctlbyname(kern.smp.maxcpus): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } #else if (numcpu != 1) NOTICE ("cpu: Only one processor supported when using `sysctlbyname' (found %i)", numcpu); #endif /* #endif HAVE_SYSCTLBYNAME */ #elif defined(HAVE_LIBSTATGRAB) /* nothing to initialize */ /* #endif HAVE_LIBSTATGRAB */ #elif defined(HAVE_PERFSTAT) /* nothing to initialize */ #endif /* HAVE_PERFSTAT */ return (0); } /* int init */
static inline int item_summed(int i) { assert (i >= 0); assert (i < ((STATIC_ARRAY_SIZE (misc_items) + 1) * 32)); return misc_items[i / 32] & FLAG (i); }
/* Returns zero on success, less than zero on socket error and greater than * zero on other errors. */ static int conn_read_netlink(void) { #if HAVE_STRUCT_LINUX_INET_DIAG_REQ int fd; struct inet_diag_msg *r; char buf[8192]; /* If this fails, it's likely a permission problem. We'll fall back to * reading this information from files below. */ fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_INET_DIAG); if (fd < 0) { ERROR("tcpconns plugin: conn_read_netlink: socket(AF_NETLINK, SOCK_RAW, " "NETLINK_INET_DIAG) failed: %s", sstrerror(errno, buf, sizeof(buf))); return (-1); } struct sockaddr_nl nladdr = {.nl_family = AF_NETLINK}; struct nlreq req = { .nlh.nlmsg_len = sizeof(req), .nlh.nlmsg_type = TCPDIAG_GETSOCK, /* NLM_F_ROOT: return the complete table instead of a single entry. * NLM_F_MATCH: return all entries matching criteria (not implemented) * NLM_F_REQUEST: must be set on all request messages */ .nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST, .nlh.nlmsg_pid = 0, /* The sequence_number is used to track our messages. Since netlink is not * reliable, we don't want to end up with a corrupt or incomplete old * message in case the system is/was out of memory. */ .nlh.nlmsg_seq = ++sequence_number, .r.idiag_family = AF_INET, .r.idiag_states = 0xfff, .r.idiag_ext = 0}; struct iovec iov = {.iov_base = &req, .iov_len = sizeof(req)}; struct msghdr msg = {.msg_name = (void *)&nladdr, .msg_namelen = sizeof(nladdr), .msg_iov = &iov, .msg_iovlen = 1}; if (sendmsg(fd, &msg, 0) < 0) { ERROR("tcpconns plugin: conn_read_netlink: sendmsg(2) failed: %s", sstrerror(errno, buf, sizeof(buf))); close(fd); return (-1); } iov.iov_base = buf; iov.iov_len = sizeof(buf); while (1) { int status; struct nlmsghdr *h; memset(&msg, 0, sizeof(msg)); msg.msg_name = (void *)&nladdr; msg.msg_namelen = sizeof(nladdr); msg.msg_iov = &iov; msg.msg_iovlen = 1; status = recvmsg(fd, (void *)&msg, /* flags = */ 0); if (status < 0) { if ((errno == EINTR) || (errno == EAGAIN)) continue; ERROR("tcpconns plugin: conn_read_netlink: recvmsg(2) failed: %s", sstrerror(errno, buf, sizeof(buf))); close(fd); return (-1); } else if (status == 0) { close(fd); DEBUG("tcpconns plugin: conn_read_netlink: Unexpected zero-sized " "reply from netlink socket."); return (0); } h = (struct nlmsghdr *)buf; while (NLMSG_OK(h, status)) { if (h->nlmsg_seq != sequence_number) { h = NLMSG_NEXT(h, status); continue; } if (h->nlmsg_type == NLMSG_DONE) { close(fd); return (0); } else if (h->nlmsg_type == NLMSG_ERROR) { struct nlmsgerr *msg_error; msg_error = NLMSG_DATA(h); WARNING("tcpconns plugin: conn_read_netlink: Received error %i.", msg_error->error); close(fd); return (1); } r = NLMSG_DATA(h); /* This code does not (need to) distinguish between IPv4 and IPv6. */ conn_handle_ports(ntohs(r->id.idiag_sport), ntohs(r->id.idiag_dport), r->idiag_state); h = NLMSG_NEXT(h, status); } /* while (NLMSG_OK) */ } /* while (1) */ /* Not reached because the while() loop above handles the exit condition. */ return (0); #else return (1); #endif /* HAVE_STRUCT_LINUX_INET_DIAG_REQ */ } /* int conn_read_netlink */ static int conn_handle_line(char *buffer) { char *fields[32]; int fields_len; char *endptr; char *port_local_str; char *port_remote_str; uint16_t port_local; uint16_t port_remote; uint8_t state; int buffer_len = strlen(buffer); while ((buffer_len > 0) && (buffer[buffer_len - 1] < 32)) buffer[--buffer_len] = '\0'; if (buffer_len <= 0) return (-1); fields_len = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); if (fields_len < 12) { DEBUG("tcpconns plugin: Got %i fields, expected at least 12.", fields_len); return (-1); } port_local_str = strchr(fields[1], ':'); port_remote_str = strchr(fields[2], ':'); if ((port_local_str == NULL) || (port_remote_str == NULL)) return (-1); port_local_str++; port_remote_str++; if ((*port_local_str == '\0') || (*port_remote_str == '\0')) return (-1); endptr = NULL; port_local = (uint16_t)strtol(port_local_str, &endptr, 16); if ((endptr == NULL) || (*endptr != '\0')) return (-1); endptr = NULL; port_remote = (uint16_t)strtol(port_remote_str, &endptr, 16); if ((endptr == NULL) || (*endptr != '\0')) return (-1); endptr = NULL; state = (uint8_t)strtol(fields[3], &endptr, 16); if ((endptr == NULL) || (*endptr != '\0')) return (-1); return (conn_handle_ports(port_local, port_remote, state)); } /* int conn_handle_line */ static int conn_read_file(const char *file) { FILE *fh; char buffer[1024]; fh = fopen(file, "r"); if (fh == NULL) return (-1); while (fgets(buffer, sizeof(buffer), fh) != NULL) { conn_handle_line(buffer); } /* while (fgets) */ fclose(fh); return (0); } /* int conn_read_file */ /* #endif KERNEL_LINUX */ #elif HAVE_SYSCTLBYNAME /* #endif HAVE_SYSCTLBYNAME */ #elif HAVE_LIBKVM_NLIST #endif /* HAVE_LIBKVM_NLIST */ static int conn_config(const char *key, const char *value) { if (strcasecmp(key, "ListeningPorts") == 0) { if (IS_TRUE(value)) port_collect_listening = 1; else port_collect_listening = 0; } else if ((strcasecmp(key, "LocalPort") == 0) || (strcasecmp(key, "RemotePort") == 0)) { port_entry_t *pe; int port = atoi(value); if ((port < 1) || (port > 65535)) { ERROR("tcpconns plugin: Invalid port: %i", port); return (1); } pe = conn_get_port_entry((uint16_t)port, 1 /* create */); if (pe == NULL) { ERROR("tcpconns plugin: conn_get_port_entry failed."); return (1); } if (strcasecmp(key, "LocalPort") == 0) pe->flags |= PORT_COLLECT_LOCAL; else pe->flags |= PORT_COLLECT_REMOTE; } else if (strcasecmp(key, "AllPortsSummary") == 0) { if (IS_TRUE(value)) port_collect_total = 1; else port_collect_total = 0; } else { return (-1); } return (0); } /* int conn_config */ #if KERNEL_LINUX static int conn_init(void) { if (port_collect_total == 0 && port_list_head == NULL) port_collect_listening = 1; return (0); } /* int conn_init */ static int conn_read(void) { int status; conn_reset_port_entry(); if (linux_source == SRC_NETLINK) { status = conn_read_netlink(); } else if (linux_source == SRC_PROC) { int errors_num = 0; if (conn_read_file("/proc/net/tcp") != 0) errors_num++; if (conn_read_file("/proc/net/tcp6") != 0) errors_num++; if (errors_num < 2) status = 0; else status = ENOENT; } else /* if (linux_source == SRC_DUNNO) */ { /* Try to use netlink for getting this data, it is _much_ faster on systems * with a large amount of connections. */ status = conn_read_netlink(); if (status == 0) { INFO("tcpconns plugin: Reading from netlink succeeded. " "Will use the netlink method from now on."); linux_source = SRC_NETLINK; } else { INFO("tcpconns plugin: Reading from netlink failed. " "Will read from /proc from now on."); linux_source = SRC_PROC; /* return success here to avoid the "plugin failed" message. */ return (0); } } if (status == 0) conn_submit_all(); else return (status); return (0); } /* int conn_read */
static _Bool new_naming_schema = 0; static _Bool collect_compression = 1; static _Bool collect_user_count = 0; static _Bool collect_individual_users = 1; static const char *config_keys[] = { "StatusFile", "Compression", /* old, deprecated name */ "ImprovedNamingSchema", "CollectCompression", "CollectUserCount", "CollectIndividualUsers" }; static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); /* Helper function * copy-n-pasted from common.c - changed delim to "," */ static int openvpn_strsplit (char *string, char **fields, size_t size) { size_t i; char *ptr; char *saveptr; i = 0; ptr = string; saveptr = NULL; while ((fields[i] = strtok_r (ptr, ",", &saveptr)) != NULL) {
int main(int argc, char **argv) { riemann_message_t msg = RIEMANN_MSG_INIT; riemann_message_t *resp = NULL; size_t n_events = STATIC_ARRAY_SIZE(cpus); riemann_event_t *events[n_events]; /* using stack space */ size_t n_attrs = STATIC_ARRAY_SIZE(attrs); int i; int error; riemann_client_t cli; if (argc != 3) { fprintf(stderr, "%s <IP> <PORT>\n", argv[0]); exit(EXIT_FAILURE); } for (i = 0; i < n_events; i++) { events[i] = alloca(sizeof (riemann_event_t)); riemann_event_init(events[i]); riemann_event_set_host(events[i], "gentoo-x86"); riemann_event_set_service(events[i], cpus[i]); riemann_event_set_metric_f(events[i], 100); /* 100% idle */ riemann_event_set_state(events[i], "ok"); riemann_event_set_tags(events[i], tags, STATIC_ARRAY_SIZE(tags)); riemann_event_set_attributes(events[i], attrs, STATIC_ARRAY_SIZE(attrs)); } riemann_message_set_events(&msg, events, n_events); error = riemann_client_init(&cli); if (error) { fprintf(stderr, "Can't initialize client: strerror(%s)\n", strerror(errno)); exit(EXIT_FAILURE); } error = riemann_client_connect(&cli, TCP, argv[1], atoi(argv[2])); /* functions that returns ints returns 0 on success */ if (error) { fprintf(stderr, "Can't connectd: strerror(%s) gai_strerrror(%s)\n", strerror(errno), gai_strerror(error)); exit(EXIT_FAILURE); } error = riemann_client_send_message(&cli, &msg, 0, NULL); if (error) { fprintf(stderr, "Can't send message: %s\n", strerror(errno)); exit(EXIT_FAILURE); } resp = riemann_client_recv_message(&cli, 0, NULL); /* functions that returns pointers rertuns NULL on failure */ assert(resp); if (!resp->ok) { fprintf(stderr, "Message error %s\n", resp->error); exit(EXIT_FAILURE); } else { puts("Sucess"); } for (i = 0; i < n_events; i++) /* freeing events fields */ riemann_event_free(events[i]); /* Since events are on * stack the may not be * freed. */ riemann_message_free(resp); /* responses should be freed */ riemann_client_free(&cli); return 0; }
static int init (void) { #if PROCESSOR_CPU_LOAD_INFO || PROCESSOR_TEMPERATURE kern_return_t status; port_host = mach_host_self (); /* FIXME: Free `cpu_list' if it's not NULL */ if ((status = host_processors (port_host, &cpu_list, &cpu_list_len)) != KERN_SUCCESS) { ERROR ("cpu plugin: host_processors returned %i", (int) status); cpu_list_len = 0; return (-1); } DEBUG ("host_processors returned %i %s", (int) cpu_list_len, cpu_list_len == 1 ? "processor" : "processors"); INFO ("cpu plugin: Found %i processor%s.", (int) cpu_list_len, cpu_list_len == 1 ? "" : "s"); cpu_temp_retry_max = 86400 / CDTIME_T_TO_TIME_T (plugin_get_interval ()); /* #endif PROCESSOR_CPU_LOAD_INFO */ #elif defined(HAVE_LIBKSTAT) kstat_t *ksp_chain; numcpu = 0; if (kc == NULL) return (-1); /* Solaris doesn't count linear.. *sigh* */ for (numcpu = 0, ksp_chain = kc->kc_chain; (numcpu < MAX_NUMCPU) && (ksp_chain != NULL); ksp_chain = ksp_chain->ks_next) if (strncmp (ksp_chain->ks_module, "cpu_stat", 8) == 0) ksp[numcpu++] = ksp_chain; /* #endif HAVE_LIBKSTAT */ #elif CAN_USE_SYSCTL size_t numcpu_size; int mib[2] = {CTL_HW, HW_NCPU}; int status; numcpu = 0; numcpu_size = sizeof (numcpu); status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &numcpu, &numcpu_size, NULL, 0); if (status == -1) { char errbuf[1024]; WARNING ("cpu plugin: sysctl: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } /* #endif CAN_USE_SYSCTL */ #elif defined (HAVE_SYSCTLBYNAME) size_t numcpu_size; numcpu_size = sizeof (numcpu); if (sysctlbyname ("hw.ncpu", &numcpu, &numcpu_size, NULL, 0) < 0) { char errbuf[1024]; WARNING ("cpu plugin: sysctlbyname(hw.ncpu): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } #ifdef HAVE_SYSCTL_KERN_CP_TIMES numcpu_size = sizeof (maxcpu); if (sysctlbyname("kern.smp.maxcpus", &maxcpu, &numcpu_size, NULL, 0) < 0) { char errbuf[1024]; WARNING ("cpu plugin: sysctlbyname(kern.smp.maxcpus): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } #else if (numcpu != 1) NOTICE ("cpu: Only one processor supported when using `sysctlbyname' (found %i)", numcpu); #endif /* #endif HAVE_SYSCTLBYNAME */ #elif defined(HAVE_LIBSTATGRAB) /* nothing to initialize */ /* #endif HAVE_LIBSTATGRAB */ #elif defined(HAVE_PERFSTAT) /* nothing to initialize */ #endif /* HAVE_PERFSTAT */ return (0); } /* int init */
const char* const default_server_fields[] = /* {{{ */ { "latency" "packetcache-hit", "packetcache-miss", "packetcache-size", "query-cache-hit", "query-cache-miss", "recursing-answers", "recursing-questions", "tcp-answers", "tcp-queries", "udp-answers", "udp-queries", }; /* }}} */ int default_server_fields_num = STATIC_ARRAY_SIZE (default_server_fields); statname_lookup_t lookup_table[] = /* {{{ */ { /********************* * Server statistics * *********************/ /* Questions */ {"recursing-questions", "dns_question", "recurse"}, {"tcp-queries", "dns_question", "tcp"}, {"udp-queries", "dns_question", "udp"}, /* Answers */ {"recursing-answers", "dns_answer", "recurse"}, {"tcp-answers", "dns_answer", "tcp"}, {"udp-answers", "dns_answer", "udp"},
static int cpu_read (void) { #if PROCESSOR_CPU_LOAD_INFO || PROCESSOR_TEMPERATURE int cpu; kern_return_t status; #if PROCESSOR_CPU_LOAD_INFO processor_cpu_load_info_data_t cpu_info; mach_msg_type_number_t cpu_info_len; #endif #if PROCESSOR_TEMPERATURE processor_info_data_t cpu_temp; mach_msg_type_number_t cpu_temp_len; #endif host_t cpu_host; for (cpu = 0; cpu < cpu_list_len; cpu++) { #if PROCESSOR_CPU_LOAD_INFO derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; memset(derives, -1, sizeof(derives)); cpu_host = 0; cpu_info_len = PROCESSOR_BASIC_INFO_COUNT; if ((status = processor_info (cpu_list[cpu], PROCESSOR_CPU_LOAD_INFO, &cpu_host, (processor_info_t) &cpu_info, &cpu_info_len)) != KERN_SUCCESS) { ERROR ("cpu plugin: processor_info failed with status %i", (int) status); continue; } if (cpu_info_len < CPU_STATE_MAX) { ERROR ("cpu plugin: processor_info returned only %i elements..", cpu_info_len); continue; } derives[CPU_SUBMIT_USER] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_USER]; derives[CPU_SUBMIT_NICE] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_NICE]; derives[CPU_SUBMIT_SYSTEM] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_SYSTEM]; derives[CPU_SUBMIT_IDLE] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_IDLE]; submit (cpu, derives); #endif /* PROCESSOR_CPU_LOAD_INFO */ #if PROCESSOR_TEMPERATURE /* * Not all Apple computers do have this ability. To minimize * the messages sent to the syslog we do an exponential * stepback if `processor_info' fails. We still try ~once a day * though.. */ if (cpu_temp_retry_counter > 0) { cpu_temp_retry_counter--; continue; } cpu_temp_len = PROCESSOR_INFO_MAX; status = processor_info (cpu_list[cpu], PROCESSOR_TEMPERATURE, &cpu_host, cpu_temp, &cpu_temp_len); if (status != KERN_SUCCESS) { ERROR ("cpu plugin: processor_info failed: %s", mach_error_string (status)); cpu_temp_retry_counter = cpu_temp_retry_step; cpu_temp_retry_step *= 2; if (cpu_temp_retry_step > cpu_temp_retry_max) cpu_temp_retry_step = cpu_temp_retry_max; continue; } if (cpu_temp_len != 1) { DEBUG ("processor_info (PROCESSOR_TEMPERATURE) returned %i elements..?", (int) cpu_temp_len); continue; } cpu_temp_retry_counter = 0; cpu_temp_retry_step = 1; #endif /* PROCESSOR_TEMPERATURE */ } submit_flush (); /* #endif PROCESSOR_CPU_LOAD_INFO */ #elif defined(KERNEL_LINUX) int cpu; FILE *fh; char buf[1024]; char *fields[9]; int numfields; if ((fh = fopen ("/proc/stat", "r")) == NULL) { char errbuf[1024]; ERROR ("cpu plugin: fopen (/proc/stat) failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } while (fgets (buf, 1024, fh) != NULL) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; if (strncmp (buf, "cpu", 3)) continue; if ((buf[3] < '0') || (buf[3] > '9')) continue; numfields = strsplit (buf, fields, 9); if (numfields < 5) continue; cpu = atoi (fields[0] + 3); derives[CPU_SUBMIT_USER] = atoll(fields[1]); derives[CPU_SUBMIT_NICE] = atoll(fields[2]); derives[CPU_SUBMIT_SYSTEM] = atoll(fields[3]); derives[CPU_SUBMIT_IDLE] = atoll(fields[4]); if (numfields >= 8) { derives[CPU_SUBMIT_WAIT] = atoll(fields[5]); derives[CPU_SUBMIT_INTERRUPT] = atoll(fields[6]); derives[CPU_SUBMIT_SOFTIRQ] = atoll(fields[6]); if (numfields >= 9) derives[CPU_SUBMIT_STEAL] = atoll(fields[8]); } submit(cpu, derives); } submit_flush(); fclose (fh); /* #endif defined(KERNEL_LINUX) */ #elif defined(HAVE_LIBKSTAT) int cpu; static cpu_stat_t cs; if (kc == NULL) return (-1); for (cpu = 0; cpu < numcpu; cpu++) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; if (kstat_read (kc, ksp[cpu], &cs) == -1) continue; /* error message? */ memset(derives, -1, sizeof(derives)); derives[CPU_SUBMIT_IDLE] = cs.cpu_sysinfo.cpu[CPU_IDLE]; derives[CPU_SUBMIT_USER] = cs.cpu_sysinfo.cpu[CPU_USER]; derives[CPU_SUBMIT_SYSTEM] = cs.cpu_sysinfo.cpu[CPU_KERNEL]; derives[CPU_SUBMIT_WAIT] = cs.cpu_sysinfo.cpu[CPU_WAIT]; submit (ksp[cpu]->ks_instance, derives); } submit_flush (); /* #endif defined(HAVE_LIBKSTAT) */ #elif CAN_USE_SYSCTL uint64_t cpuinfo[numcpu][CPUSTATES]; size_t cpuinfo_size; int status; int i; if (numcpu < 1) { ERROR ("cpu plugin: Could not determine number of " "installed CPUs using sysctl(3)."); return (-1); } memset (cpuinfo, 0, sizeof (cpuinfo)); #if defined(KERN_CPTIME2) if (numcpu > 1) { for (i = 0; i < numcpu; i++) { int mib[] = {CTL_KERN, KERN_CPTIME2, i}; cpuinfo_size = sizeof (cpuinfo[0]); status = sysctl (mib, STATIC_ARRAY_SIZE (mib), cpuinfo[i], &cpuinfo_size, NULL, 0); if (status == -1) { char errbuf[1024]; ERROR ("cpu plugin: sysctl failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } } } else #endif /* defined(KERN_CPTIME2) */ { int mib[] = {CTL_KERN, KERN_CPTIME}; long cpuinfo_tmp[CPUSTATES]; cpuinfo_size = sizeof(cpuinfo_tmp); status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &cpuinfo_tmp, &cpuinfo_size, NULL, 0); if (status == -1) { char errbuf[1024]; ERROR ("cpu plugin: sysctl failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } for(i = 0; i < CPUSTATES; i++) { cpuinfo[0][i] = cpuinfo_tmp[i]; } } for (i = 0; i < numcpu; i++) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; derives[CPU_SUBMIT_USER] = cpuinfo[i][CP_USER]; derives[CPU_SUBMIT_NICE] = cpuinfo[i][CP_NICE]; derives[CPU_SUBMIT_SYSTEM] = cpuinfo[i][CP_SYS]; derives[CPU_SUBMIT_IDLE] = cpuinfo[i][CP_IDLE]; derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[i][CP_INTR]; submit(i, derives); } submit_flush(); /* #endif CAN_USE_SYSCTL */ #elif defined(HAVE_SYSCTLBYNAME) && defined(HAVE_SYSCTL_KERN_CP_TIMES) long cpuinfo[maxcpu][CPUSTATES]; size_t cpuinfo_size; int i; memset (cpuinfo, 0, sizeof (cpuinfo)); cpuinfo_size = sizeof (cpuinfo); if (sysctlbyname("kern.cp_times", &cpuinfo, &cpuinfo_size, NULL, 0) < 0) { char errbuf[1024]; ERROR ("cpu plugin: sysctlbyname failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } for (i = 0; i < numcpu; i++) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; derives[CPU_SUBMIT_USER] = cpuinfo[i][CP_USER]; derives[CPU_SUBMIT_NICE] = cpuinfo[i][CP_NICE]; derives[CPU_SUBMIT_SYSTEM] = cpuinfo[i][CP_SYS]; derives[CPU_SUBMIT_IDLE] = cpuinfo[i][CP_IDLE]; derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[i][CP_INTR]; submit(i, derives); } submit_flush(); /* #endif HAVE_SYSCTL_KERN_CP_TIMES */ #elif defined(HAVE_SYSCTLBYNAME) long cpuinfo[CPUSTATES]; size_t cpuinfo_size; derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; cpuinfo_size = sizeof (cpuinfo); if (sysctlbyname("kern.cp_time", &cpuinfo, &cpuinfo_size, NULL, 0) < 0) { char errbuf[1024]; ERROR ("cpu plugin: sysctlbyname failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } derives[CPU_SUBMIT_USER] = cpuinfo[CP_USER]; derives[CPU_SUBMIT_SYSTEM] = cpuinfo[CP_SYS]; derives[CPU_SUBMIT_NICE] = cpuinfo[CP_NICE]; derives[CPU_SUBMIT_IDLE] = cpuinfo[CP_IDLE]; derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[CP_INTR]; submit(0, derives); submit_flush(); /* #endif HAVE_SYSCTLBYNAME */ #elif defined(HAVE_LIBSTATGRAB) sg_cpu_stats *cs; derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; cs = sg_get_cpu_stats (); if (cs == NULL) { ERROR ("cpu plugin: sg_get_cpu_stats failed."); return (-1); } derives[CPU_SUBMIT_IDLE] = (derive_t) cs->idle; derives[CPU_SUBMIT_NICE] = (derive_t) cs->nice; derives[CPU_SUBMIT_SWAP] = (derive_t) cs->swap; derives[CPU_SUBMIT_SYSTEM] = (derive_t) cs->kernel; derives[CPU_SUBMIT_USER] = (derive_t) cs->user; derives[CPU_SUBMIT_WAIT] = (derive_t) cs->iowait; submit(0, derives); submit_flush(); /* #endif HAVE_LIBSTATGRAB */ #elif defined(HAVE_PERFSTAT) perfstat_id_t id; int i, cpus; numcpu = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0); if(numcpu == -1) { char errbuf[1024]; WARNING ("cpu plugin: perfstat_cpu: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } if (pnumcpu != numcpu || perfcpu == NULL) { if (perfcpu != NULL) free(perfcpu); perfcpu = malloc(numcpu * sizeof(perfstat_cpu_t)); } pnumcpu = numcpu; id.name[0] = '\0'; if ((cpus = perfstat_cpu(&id, perfcpu, sizeof(perfstat_cpu_t), numcpu)) < 0) { char errbuf[1024]; WARNING ("cpu plugin: perfstat_cpu: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } for (i = 0; i < cpus; i++) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; derives[CPU_SUBMIT_IDLE] = perfcpu[i].idle; derives[CPU_SUBMIT_SYSTEM] = perfcpu[i].sys; derives[CPU_SUBMIT_USER] = perfcpu[i].user; derives[CPU_SUBMIT_WAIT] = perfcpu[i].wait; submit(i, derives); } submit_flush(); #endif /* HAVE_PERFSTAT */ return (0); }
static int tbl_result_dispatch (tbl_t *tbl, tbl_result_t *res, char **fields, size_t fields_num) { value_list_t vl = VALUE_LIST_INIT; value_t values[res->values_num]; size_t i; assert (NULL != res->ds); assert (res->values_num == res->ds->ds_num); for (i = 0; i < res->values_num; ++i) { char *value; assert (res->values[i] < fields_num); value = fields[res->values[i]]; if (0 != parse_value (value, &values[i], res->ds->ds[i].type)) return -1; } vl.values = values; vl.values_len = STATIC_ARRAY_SIZE (values); sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "table", sizeof (vl.plugin)); sstrncpy (vl.plugin_instance, tbl->instance, sizeof (vl.plugin_instance)); sstrncpy (vl.type, res->type, sizeof (vl.type)); if (0 == res->instances_num) { if (NULL != res->instance_prefix) sstrncpy (vl.type_instance, res->instance_prefix, sizeof (vl.type_instance)); } else { char *instances[res->instances_num]; char instances_str[DATA_MAX_NAME_LEN]; for (i = 0; i < res->instances_num; ++i) { assert (res->instances[i] < fields_num); instances[i] = fields[res->instances[i]]; } strjoin (instances_str, sizeof (instances_str), instances, STATIC_ARRAY_SIZE (instances), "-"); instances_str[sizeof (instances_str) - 1] = '\0'; vl.type_instance[sizeof (vl.type_instance) - 1] = '\0'; if (NULL == res->instance_prefix) strncpy (vl.type_instance, instances_str, sizeof (vl.type_instance)); else snprintf (vl.type_instance, sizeof (vl.type_instance), "%s-%s", res->instance_prefix, instances_str); if ('\0' != vl.type_instance[sizeof (vl.type_instance) - 1]) { vl.type_instance[sizeof (vl.type_instance) - 1] = '\0'; log_warn ("Truncated type instance: %s.", vl.type_instance); } } plugin_dispatch_values (&vl); return 0; } /* tbl_result_dispatch */
* Kim-Marie Jones <*****@*****.**> */ #include "collectd.h" #include "common.h" /* auxiliary functions */ #include "plugin.h" /* plugin_register_*, plugin_dispatch_values */ static const char g_plugin_name[] = "hugepages"; static const char g_cfg_rpt_numa[] = "ReportPerNodeHP"; static const char g_cfg_rpt_mm[] = "ReportRootHP"; static const char *g_config_keys[] = { g_cfg_rpt_numa, g_cfg_rpt_mm, }; static size_t g_config_keys_num = STATIC_ARRAY_SIZE(g_config_keys); static int g_flag_rpt_numa = 1; static int g_flag_rpt_mm = 1; struct entry_info { char *d_name; const char *node; }; static int huge_config_callback(const char *key, const char *val) { DEBUG("%s: HugePages config key='%s', val='%s'", g_plugin_name, key, val); if (strcasecmp(key, g_cfg_rpt_numa) == 0) { g_flag_rpt_numa = IS_TRUE(val); return 0;
static int read_acpi_callback (char const *dir, /* {{{ */ char const *power_supply, void *user_data) { int *battery_index = user_data; gauge_t current = NAN; gauge_t voltage = NAN; gauge_t charge = NAN; _Bool charging = 0; char const *plugin_instance; char filename[PATH_MAX]; char buffer[1024]; FILE *fh; ssnprintf (filename, sizeof (filename), "%s/%s/state", dir, power_supply); fh = fopen (filename, "r"); if ((fh = fopen (filename, "r")) == NULL) { if ((errno == EAGAIN) || (errno == EINTR) || (errno == ENOENT)) return (0); else return (errno); } /* * [11:00] <@tokkee> $ cat /proc/acpi/battery/BAT1/state * [11:00] <@tokkee> present: yes * [11:00] <@tokkee> capacity state: ok * [11:00] <@tokkee> charging state: charging * [11:00] <@tokkee> present rate: 1724 mA * [11:00] <@tokkee> remaining capacity: 4136 mAh * [11:00] <@tokkee> present voltage: 12428 mV */ while (fgets (buffer, sizeof (buffer), fh) != NULL) { char *fields[8]; int numfields; numfields = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); if (numfields < 3) continue; if ((strcmp (fields[0], "charging") == 0) && (strcmp (fields[1], "state:") == 0)) { if (strcmp (fields[2], "charging") == 0) charging = 1; else charging = 0; continue; } /* FIXME: The unit of "present rate" depends on the battery. * Modern batteries export watts, not amperes, i.e. it's not a * current anymore. We should check if the fourth column * contains "mA" and only use a current then. Otherwise, export * a power. */ if ((strcmp (fields[0], "present") == 0) && (strcmp (fields[1], "rate:") == 0)) strtogauge (fields[2], ¤t); else if ((strcmp (fields[0], "remaining") == 0) && (strcmp (fields[1], "capacity:") == 0)) strtogauge (fields[2], &charge); else if ((strcmp (fields[0], "present") == 0) && (strcmp (fields[1], "voltage:") == 0)) strtogauge (fields[2], &voltage); } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */ fclose (fh); if (!charging) current *= -1.0; /* FIXME: This is a dirty hack for backwards compatibility: The battery * plugin, for a very long time, has had the plugin_instance * hard-coded to "0". So, to keep backwards compatibility, we'll use * "0" for the first battery we find and the power_supply name for all * following. This should be reverted in a future major version. */ plugin_instance = (*battery_index == 0) ? "0" : power_supply; (*battery_index)++; battery_submit (plugin_instance, "charge", charge / 1000.0); battery_submit (plugin_instance, "current", current / 1000.0); battery_submit (plugin_instance, "voltage", voltage / 1000.0); return 0; } /* }}} int read_acpi_callback */
static void fscache_read_stats_file(FILE *fh) { char section[DATA_MAX_NAME_LEN]; size_t section_len; char linebuffer[BUFSIZE]; /* * cat /proc/fs/fscache/stats * FS-Cache statistics * Cookies: idx=2 dat=0 spc=0 * Objects: alc=0 nal=0 avl=0 ded=0 * ChkAux : non=0 ok=0 upd=0 obs=0 * Pages : mrk=0 unc=0 * Acquire: n=2 nul=0 noc=0 ok=2 nbf=0 oom=0 * Lookups: n=0 neg=0 pos=0 crt=0 * Updates: n=0 nul=0 run=0 * Relinqs: n=0 nul=0 wcr=0 * AttrChg: n=0 ok=0 nbf=0 oom=0 run=0 * Allocs : n=0 ok=0 wt=0 nbf=0 * Allocs : ops=0 owt=0 * Retrvls: n=0 ok=0 wt=0 nod=0 nbf=0 int=0 oom=0 * Retrvls: ops=0 owt=0 * Stores : n=0 ok=0 agn=0 nbf=0 oom=0 * Stores : ops=0 run=0 * Ops : pend=0 run=0 enq=0 * Ops : dfr=0 rel=0 gc=0 */ /* Read file line by line */ while (fgets(linebuffer, sizeof(linebuffer), fh) != NULL) { char *lineptr; char *fields[32]; int fields_num; /* Find the colon and replace it with a null byte */ lineptr = strchr(linebuffer, ':'); if (lineptr == NULL) continue; *lineptr = 0; lineptr++; /* Copy and clean up the section name */ sstrncpy(section, linebuffer, sizeof(section)); section_len = strlen(section); while ((section_len > 0) && isspace((int)section[section_len - 1])) { section_len--; section[section_len] = 0; } if (section_len == 0) continue; fields_num = strsplit(lineptr, fields, STATIC_ARRAY_SIZE(fields)); if (fields_num <= 0) continue; for (int i = 0; i < fields_num; i++) { char *field_name; char *field_value_str; value_t field_value_cnt; int status; field_name = fields[i]; assert(field_name != NULL); field_value_str = strchr(field_name, '='); if (field_value_str == NULL) continue; *field_value_str = 0; field_value_str++; status = parse_value(field_value_str, &field_value_cnt, DS_TYPE_DERIVE); if (status != 0) continue; fscache_submit(section, field_name, field_value_cnt); } } /* while (fgets) */ } /* void fscache_read_stats_file */
char *service; int ref_cnt; } c_psql_database_t; static char *def_queries[] = { "backends", "transactions", "queries", "query_plans", "table_states", "disk_io", "disk_usage" }; static int def_queries_num = STATIC_ARRAY_SIZE (def_queries); static c_psql_database_t **databases = NULL; static size_t databases_num = 0; static udb_query_t **queries = NULL; static size_t queries_num = 0; static c_psql_writer_t *writers = NULL; static size_t writers_num = 0; static int c_psql_begin (c_psql_database_t *db) { PGresult *r = PQexec (db->conn, "BEGIN"); int status = 1;
static int tr_action_invoke (tr_action_t *act_head, /* {{{ */ char *buffer_in, size_t buffer_in_size, int may_be_empty) { tr_action_t *act; int status; char buffer[DATA_MAX_NAME_LEN]; regmatch_t matches[8]; if (act_head == NULL) return (-EINVAL); sstrncpy (buffer, buffer_in, sizeof (buffer)); memset (matches, 0, sizeof (matches)); DEBUG ("target_replace plugin: tr_action_invoke: <- buffer = %s;", buffer); for (act = act_head; act != NULL; act = act->next) { char temp[DATA_MAX_NAME_LEN]; char *subst_status; status = regexec (&act->re, buffer, STATIC_ARRAY_SIZE (matches), matches, /* flags = */ 0); if (status == REG_NOMATCH) continue; else if (status != 0) { char errbuf[1024] = ""; regerror (status, &act->re, errbuf, sizeof (errbuf)); ERROR ("Target `replace': Executing a regular expression failed: %s.", errbuf); continue; } subst_status = subst (temp, sizeof (temp), buffer, matches[0].rm_so, matches[0].rm_eo, act->replacement); if (subst_status == NULL) { ERROR ("Target `replace': subst (buffer = %s, start = %zu, end = %zu, " "replacement = %s) failed.", buffer, (size_t) matches[0].rm_so, (size_t) matches[0].rm_eo, act->replacement); continue; } sstrncpy (buffer, temp, sizeof (buffer)); DEBUG ("target_replace plugin: tr_action_invoke: -- buffer = %s;", buffer); } /* for (act = act_head; act != NULL; act = act->next) */ if ((may_be_empty == 0) && (buffer[0] == 0)) { WARNING ("Target `replace': Replacement resulted in an empty string, " "which is not allowed for this buffer (`host' or `plugin')."); return (0); } DEBUG ("target_replace plugin: tr_action_invoke: -> buffer = %s;", buffer); sstrncpy (buffer_in, buffer, buffer_in_size); return (0); } /* }}} int tr_action_invoke */
#elif HAVE_PERFSTAT static int pagesize; static perfstat_memory_total_t pmemory; /*# endif HAVE_PERFSTAT */ #else # error "No applicable input method." #endif /* HAVE_LIBSTATGRAB */ static const char *config_keys[] = { "ReportBytes", "ReportByDevice" }; static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); static int swap_config (const char *key, const char *value) /* {{{ */ { if (strcasecmp ("ReportBytes", key) == 0) { #if KERNEL_LINUX report_bytes = IS_TRUE (value) ? 1 : 0; #else WARNING ("swap plugin: The \"ReportBytes\" option is only " "valid under Linux. " "The option is going to be ignored."); #endif } else if (strcasecmp ("ReportByDevice", key) == 0) {
}, /* features_num = */ 1 }, { /* DS2438 Volts/Temp */ /* family = */ "26.", { { /* filename = */ "temperature", /* type = */ "temperature", /* type_instance = */ "" } }, /* features_num = */ 1 } }; static int ow_family_features_num = STATIC_ARRAY_SIZE (ow_family_features); static char *device_g = NULL; static cdtime_t ow_interval = 0; static _Bool direct_access = 0; static const char *config_keys[] = { "Device", "IgnoreSelected", "Sensor", "Interval" }; static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); static ignorelist_t *sensor_list;