Merge remote-tracking branch 'github/pr/1929'
authorFlorian Forster <octo@collectd.org>
Tue, 13 Sep 2016 08:50:40 +0000 (10:50 +0200)
committerFlorian Forster <octo@collectd.org>
Tue, 13 Sep 2016 08:50:40 +0000 (10:50 +0200)
src/battery_statefs.c
src/conntrack.c
src/cpufreq.c
src/daemon/common.c
src/daemon/common.h
src/entropy.c
src/thermal.c
src/turbostat.c

index 53730ed..ee739bf 100644 (file)
@@ -51,9 +51,6 @@ SOFTWARE.
 #include <stdio.h>
 
 #define STATEFS_ROOT "/run/state/namespaces/Battery/"
-#define BUFFER_SIZE 512
-
-static int submitted_this_run = 0;
 
 static void battery_submit(const char *type, gauge_t value,
                            const char *type_instance) {
@@ -72,67 +69,52 @@ static void battery_submit(const char *type, gauge_t value,
   if (type_instance != NULL)
     sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
   plugin_dispatch_values(&vl);
-
-  submitted_this_run++;
-}
-
-static _Bool getvalue(const char *fname, gauge_t *value) {
-  FILE *fh;
-  char buffer[BUFFER_SIZE];
-
-  if ((fh = fopen(fname, "r")) == NULL) {
-    WARNING("battery plugin: cannot open StateFS file %s", fname);
-    return (0);
-  }
-
-  if (fgets(buffer, STATIC_ARRAY_SIZE(buffer), fh) == NULL) {
-    fclose(fh);
-    return (0); // empty file
-  }
-
-  (*value) = atof(buffer);
-
-  fclose(fh);
-
-  return (1);
 }
 
 /* cannot be static, is referred to from battery.c */
 int battery_read_statefs(void) {
-  gauge_t value = NAN;
-
-  submitted_this_run = 0;
-
-  if (getvalue(STATEFS_ROOT "ChargePercentage", &value))
-    battery_submit("charge", value, NULL);
-  // Use capacity as a charge estimate if ChargePercentage is not available
-  else if (getvalue(STATEFS_ROOT "Capacity", &value))
-    battery_submit("charge", value, NULL);
-
-  if (getvalue(STATEFS_ROOT "Current", &value))
-    battery_submit("current", value * 1e-6, NULL); // from uA to A
-
-  if (getvalue(STATEFS_ROOT "Energy", &value))
-    battery_submit("energy_wh", value * 1e-6, NULL); // from uWh to Wh
-
-  if (getvalue(STATEFS_ROOT "Power", &value))
-    battery_submit("power", value * 1e-6, NULL); // from uW to W
-
-  if (getvalue(STATEFS_ROOT "Temperature", &value))
-    battery_submit("temperature", value * 0.1, NULL); // from 10xC to C
-
-  if (getvalue(STATEFS_ROOT "TimeUntilFull", &value))
-    battery_submit("duration", value, "full");
-
-  if (getvalue(STATEFS_ROOT "TimeUntilLow", &value))
-    battery_submit("duration", value, "low");
+  value_t v;
+  int success = 0;
+
+  if (parse_value_file(STATEFS_ROOT "ChargePercentage", &v, DS_TYPE_GAUGE) == 0) {
+    battery_submit("charge", v.gauge, NULL);
+    success++;
+  } else if (parse_value_file(STATEFS_ROOT "Capacity", &v, DS_TYPE_GAUGE) == 0) {
+    // Use capacity as a charge estimate if ChargePercentage is not available
+    battery_submit("charge", v.gauge, NULL);
+    success++;
+  } else {
+    WARNING("battery plugin: Neither \""STATEFS_ROOT"ChargePercentage\" "
+            "nor \""STATEFS_ROOT"Capacity\" could be read.");
+  }
 
-  if (getvalue(STATEFS_ROOT "Voltage", &value))
-    battery_submit("voltage", value * 1e-6, NULL); // from uV to V
+  struct {
+    char *path;
+    char *type;
+    char *type_instance;
+    gauge_t factor;
+  } metrics[] = {
+    {STATEFS_ROOT "Current",       "current",     NULL,  1e-6}, // from uA to A
+    {STATEFS_ROOT "Energy",        "energy_wh",   NULL,  1e-6}, // from uWh to Wh
+    {STATEFS_ROOT "Power",         "power",       NULL,  1e-6}, // from uW to W
+    {STATEFS_ROOT "Temperature",   "temperature", NULL,   0.1}, // from 10xC to C
+    {STATEFS_ROOT "TimeUntilFull", "duration",    "full", 1.0},
+    {STATEFS_ROOT "TimeUntilLow",  "duration",    "low",  1.0},
+    {STATEFS_ROOT "Voltage",       "voltage",     NULL,  1e-6}, // from uV to V
+  };
+
+  for (size_t i = 0; i < STATIC_ARRAY_SIZE(metrics); i++) {
+    if (parse_value_file(metrics[i].path, &v, DS_TYPE_GAUGE) != 0) {
+      WARNING("battery plugin: Reading \"%s\" failed.", metrics[i].path);
+      continue;
+    }
+
+    battery_submit(metrics[i].type, v.gauge * metrics[i].factor, metrics[i].type_instance);
+    success++;
+  }
 
-  if (submitted_this_run == 0) {
-    ERROR("battery plugin: statefs backend: none of the statistics are "
-          "available");
+  if (success == 0) {
+    ERROR("battery plugin: statefs backend: none of the statistics are available");
     return (-1);
   }
 
index ce90ede..4a72b2f 100644 (file)
@@ -74,61 +74,26 @@ static void conntrack_submit (const char *type, const char *type_instance,
 static int conntrack_read (void)
 {
        value_t conntrack, conntrack_max, conntrack_pct;
-       FILE *fh;
-       char buffer[64] = { 0 };
-       size_t buffer_len;
 
-       fh = fopen (old_files?CONNTRACK_FILE_OLD:CONNTRACK_FILE, "r");
-       if (fh == NULL)
-               return (-1);
-
-       if (fgets (buffer, sizeof (buffer), fh) == NULL)
+       char const *path = old_files ? CONNTRACK_FILE_OLD : CONNTRACK_FILE;
+       if (parse_value_file (path, &conntrack, DS_TYPE_GAUGE) != 0)
        {
-               fclose (fh);
+               ERROR ("conntrack plugin: Reading \"%s\" failed.", path);
                return (-1);
        }
-       fclose (fh);
 
-       /* strip trailing newline. */
-       buffer_len = strlen (buffer);
-       while ((buffer_len > 0) && isspace ((int) buffer[buffer_len - 1]))
+       path = old_files ? CONNTRACK_MAX_FILE_OLD : CONNTRACK_MAX_FILE;
+       if (parse_value_file (path, &conntrack_max, DS_TYPE_GAUGE) != 0)
        {
-               buffer[buffer_len - 1] = 0;
-               buffer_len--;
-       }
-
-       if (parse_value (buffer, &conntrack, DS_TYPE_GAUGE) != 0)
-               return (-1);
-
-       conntrack_submit ("conntrack", NULL, conntrack);
-
-       fh = fopen (old_files?CONNTRACK_MAX_FILE_OLD:CONNTRACK_MAX_FILE, "r");
-       if (fh == NULL)
-               return (-1);
-
-       memset (buffer, 0, sizeof (buffer));
-       if (fgets (buffer, sizeof (buffer), fh) == NULL)
-       {
-               fclose (fh);
+               ERROR ("conntrack plugin: Reading \"%s\" failed.", path);
                return (-1);
        }
-       fclose (fh);
-
-       /* strip trailing newline. */
-       buffer_len = strlen (buffer);
-       while ((buffer_len > 0) && isspace ((int) buffer[buffer_len - 1]))
-       {
-               buffer[buffer_len - 1] = 0;
-               buffer_len--;
-       }
-
-       if (parse_value (buffer, &conntrack_max, DS_TYPE_GAUGE) != 0)
-               return (-1);
 
-       conntrack_submit ("conntrack", "max", conntrack_max);
        conntrack_pct.gauge = (conntrack.gauge / conntrack_max.gauge) * 100;
-       conntrack_submit ("percent", "used", conntrack_pct);
 
+       conntrack_submit ("conntrack", NULL,   conntrack);
+       conntrack_submit ("conntrack", "max",  conntrack_max);
+       conntrack_submit ("percent",   "used", conntrack_pct);
 
        return (0);
 } /* static int conntrack_read */
index 1e9e857..a2cc3ad 100644 (file)
@@ -25,8 +25,6 @@
 #include "common.h"
 #include "plugin.h"
 
-#define MODULE_NAME "cpufreq"
-
 static int num_cpu = 0;
 
 static int cpufreq_init (void)
@@ -59,72 +57,39 @@ static int cpufreq_init (void)
        return (0);
 } /* int cpufreq_init */
 
-static void cpufreq_submit (int cpu_num, double value)
+static void cpufreq_submit (int cpu_num, value_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = value;
-
-       vl.values = values;
+       vl.values = &value;
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "cpufreq", sizeof (vl.plugin));
        sstrncpy (vl.type, "cpufreq", sizeof (vl.type));
-       ssnprintf (vl.type_instance, sizeof (vl.type_instance),
-                       "%i", cpu_num);
+       ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%i", cpu_num);
 
        plugin_dispatch_values (&vl);
 }
 
 static int cpufreq_read (void)
 {
-        int status;
-       unsigned long long val;
-       FILE *fp;
-       char filename[256];
-       char buffer[16];
-
        for (int i = 0; i < num_cpu; i++)
        {
-               status = ssnprintf (filename, sizeof (filename),
-                               "/sys/devices/system/cpu/cpu%d/cpufreq/"
-                               "scaling_cur_freq", i);
-               if ((status < 1) || ((unsigned int)status >= sizeof (filename)))
-                       return (-1);
+               char filename[PATH_MAX];
+               ssnprintf (filename, sizeof (filename),
+                               "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq", i);
 
-               if ((fp = fopen (filename, "r")) == NULL)
+               value_t v;
+               if (parse_value_file (filename, &v, DS_TYPE_GAUGE) != 0)
                {
-                       char errbuf[1024];
-                       WARNING ("cpufreq: fopen (%s): %s", filename,
-                                       sstrerror (errno, errbuf,
-                                               sizeof (errbuf)));
-                       return (-1);
+                       WARNING ("cpufreq plugin: Reading \"%s\" failed.", filename);
+                       continue;
                }
 
-               if (fgets (buffer, 16, fp) == NULL)
-               {
-                       char errbuf[1024];
-                       WARNING ("cpufreq: fgets: %s",
-                                       sstrerror (errno, errbuf,
-                                               sizeof (errbuf)));
-                       fclose (fp);
-                       return (-1);
-               }
-
-               if (fclose (fp))
-               {
-                       char errbuf[1024];
-                       WARNING ("cpufreq: fclose: %s",
-                                       sstrerror (errno, errbuf,
-                                               sizeof (errbuf)));
-               }
-
-
-               /* You're seeing correctly: The file is reporting kHz values.. */
-               val = atoll (buffer) * 1000;
+               /* convert kHz to Hz */
+               v.gauge *= 1000.0;
 
-               cpufreq_submit (i, val);
+               cpufreq_submit (i, v);
        }
 
        return (0);
index 05b1199..7806c71 100644 (file)
@@ -1199,6 +1199,18 @@ int parse_values (char *buffer, value_list_t *vl, const data_set_t *ds)
        return (0);
 } /* int parse_values */
 
+int parse_value_file (char const *path, value_t *ret_value, int ds_type)
+{
+       char buffer[256];
+
+       if (read_file_contents (path, buffer, sizeof (buffer)) < 0)
+               return errno;
+
+       strstripnewline (buffer);
+
+       return parse_value (buffer, ret_value, ds_type);
+} /* int parse_value_file */
+
 #if !HAVE_GETPWNAM_R
 int getpwnam_r (const char *name, struct passwd *pwbuf, char *buf,
                size_t buflen, struct passwd **pwbufp)
index 720e5f1..9e25293 100644 (file)
@@ -322,6 +322,11 @@ int parse_identifier_vl (const char *str, value_list_t *vl);
 int parse_value (const char *value, value_t *ret_value, int ds_type);
 int parse_values (char *buffer, value_list_t *vl, const data_set_t *ds);
 
+/* parse_value_file reads "path" and parses its content as an integer or
+ * floating point, depending on "ds_type". On success, the value is stored in
+ * "ret_value" and zero is returned. On failure, a non-zero value is returned. */
+int parse_value_file (char const *path, value_t *ret_value, int ds_type);
+
 #if !HAVE_GETPWNAM_R
 int getpwnam_r (const char *name, struct passwd *pwbuf, char *buf,
                size_t buflen, struct passwd **pwbufp);
index f4f4ac4..b385c2a 100644 (file)
 
 #define ENTROPY_FILE "/proc/sys/kernel/random/entropy_avail"
 
-static void entropy_submit (double entropy)
+static void entropy_submit (value_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = entropy;
-
-       vl.values = values;
+       vl.values = &value;
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "entropy", sizeof (vl.plugin));
@@ -53,26 +50,14 @@ static void entropy_submit (double entropy)
 
 static int entropy_read (void)
 {
-       double entropy;
-       FILE *fh;
-       char buffer[64];
-
-       fh = fopen (ENTROPY_FILE, "r");
-       if (fh == NULL)
-               return (-1);
-
-       if (fgets (buffer, sizeof (buffer), fh) == NULL)
+       value_t v;
+       if (parse_value_file (ENTROPY_FILE, &v, DS_TYPE_GAUGE) != 0)
        {
-               fclose (fh);
+               ERROR ("entropy plugin: Reading \""ENTROPY_FILE"\" failed.");
                return (-1);
        }
-       fclose (fh);
-
-       entropy = atof (buffer);
-       
-       if (entropy > 0.0)
-               entropy_submit (entropy);
 
+       entropy_submit (v);
        return (0);
 }
 
index e001a62..aa95dac 100644 (file)
@@ -47,14 +47,11 @@ enum dev_type {
 };
 
 static void thermal_submit (const char *plugin_instance, enum dev_type dt,
-               gauge_t value)
+               value_t value)
 {
        value_list_t vl = VALUE_LIST_INIT;
-       value_t v;
-
-       v.gauge = value;
-       vl.values = &v;
 
+       vl.values = &value;
        vl.values_len = 1;
 
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
@@ -72,52 +69,26 @@ static void thermal_submit (const char *plugin_instance, enum dev_type dt,
 static int thermal_sysfs_device_read (const char __attribute__((unused)) *dir,
                const char *name, void __attribute__((unused)) *user_data)
 {
-       char filename[256];
-       char data[1024];
-       int len;
+       char filename[PATH_MAX];
        _Bool success = 0;
+       value_t value;
 
        if (device_list && ignorelist_match (device_list, name))
                return -1;
 
-       len = ssnprintf (filename, sizeof (filename),
-                       "%s/%s/temp", dirname_sysfs, name);
-       if ((len < 0) || ((size_t) len >= sizeof (filename)))
-               return -1;
-
-       len = (ssize_t) read_file_contents (filename, data, sizeof(data));
-       if (len > 1 && data[--len] == '\n') {
-               char *endptr = NULL;
-               double temp;
-
-               data[len] = 0;
-               errno = 0;
-               temp = strtod (data, &endptr) / 1000.0;
-
-               if (endptr == data + len && errno == 0) {
-                       thermal_submit(name, TEMP, temp);
-                       success = 1;
-               }
+       ssnprintf (filename, sizeof (filename), "%s/%s/temp", dirname_sysfs, name);
+       if (parse_value_file (filename, &value, DS_TYPE_GAUGE) == 0)
+       {
+               value.gauge /= 1000.0;
+               thermal_submit(name, TEMP, value);
+               success = 1;
        }
 
-       len = ssnprintf (filename, sizeof (filename),
-                       "%s/%s/cur_state", dirname_sysfs, name);
-       if ((len < 0) || ((size_t) len >= sizeof (filename)))
-               return -1;
-
-       len = (ssize_t) read_file_contents (filename, data, sizeof(data));
-       if (len > 1 && data[--len] == '\n') {
-               char *endptr = NULL;
-               double state;
-
-               data[len] = 0;
-               errno = 0;
-               state = strtod (data, &endptr);
-
-               if (endptr == data + len && errno == 0) {
-                       thermal_submit(name, COOLING_DEV, state);
-                       success = 1;
-               }
+       ssnprintf (filename, sizeof (filename), "%s/%s/cur_state", dirname_sysfs, name);
+       if (parse_value_file (filename, &value, DS_TYPE_GAUGE) == 0)
+       {
+               thermal_submit(name, COOLING_DEV, value);
+               success = 1;
        }
 
        return (success ? 0 : -1);
@@ -176,7 +147,7 @@ static int thermal_procfs_device_read (const char __attribute__((unused)) *dir,
                temp = (strtod (data + len, &endptr) + add) * factor;
 
                if (endptr != data + len && errno == 0) {
-                       thermal_submit(name, TEMP, temp);
+                       thermal_submit(name, TEMP, (value_t) { .gauge = temp });
                        return 0;
                }
        }
index 2d8a08e..7b813c9 100644 (file)
@@ -1018,8 +1018,7 @@ parse_int_file(const char *fmt, ...)
 {
        va_list args;
        char path[PATH_MAX];
-       FILE *filep;
-       int len, value;
+       int len;
 
        va_start(args, fmt);
        len = vsnprintf(path, sizeof(path), fmt, args);
@@ -1029,18 +1028,13 @@ parse_int_file(const char *fmt, ...)
                return -1;
        }
 
-       filep = fopen(path, "r");
-       if (!filep) {
-               ERROR("turbostat plugin: Failed to open '%s'", path);
-               return -1;
-       }
-       if (fscanf(filep, "%d", &value) != 1) {
-               ERROR("turbostat plugin: Failed to parse number from '%s'", path);
-               fclose(filep);
+       value_t v;
+       if (parse_value_file (path, &v, DS_TYPE_DERIVE) != 0) {
+               ERROR ("turbostat plugin: Parsing \"%s\" failed.", path);
                return -1;
        }
-       fclose(filep);
-       return value;
+
+       return (int) v.derive;
 }
 
 static int