diff options
-rw-r--r-- | README.md | 37 | ||||
-rw-r--r-- | filesystem.c | 76 | ||||
-rw-r--r-- | filesystem.h | 8 | ||||
-rw-r--r-- | main.c | 2 |
4 files changed, 122 insertions, 1 deletions
diff --git a/README.md b/README.md index 7ea87fa..1626b83 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ including generated metrics, labels and configuration options. | Name | Description | | ---- | ----------- | | [`cpu`](#cpu) | CPU usage from `/proc/stat` and CPU frequency scaling data from sysfs. | +| [`filesystem`](#filesystem) | Statistics of mounted filesystems from `statvfs(2)`. | | [`hwmon`](#hwmon) | Temperature, fan and voltage sensors from `/sys/class/hwmon`. | | [`meminfo`](#meminfo) | Memory usage statistics from `/proc/meminfo`. | | [`network`](#network) | Network device transmit/receive statistics from `/proc/net/dev`. | @@ -82,13 +83,39 @@ Metrics and labels: `cpufreq/scaling_cur_freq` value under the CPU-specific sysfs directory. +### `filesystem` + +Metrics: + +* `node_filesystem_size_bytes`: Total size of the filesystem. +* `node_filesystem_free_bytes`: Number of free bytes in the + filesystem. +* `node_filesystem_avail_bytes`: Number of free bytes available to + unprivileged users. +* `node_filesystem_files`: Total number of inodes supported by the + filesystem. +* `node_filesystem_files_free`: Number of free inodes. +* `node_filesystem_readonly`: Whether the filesystem is mounted + read-only: `0` (rw) or `1` (ro). + +Labels: + +* `device`: Device node mounted at the location. +* `fstype`: Mounted filesystem type. +* `mountpoint`: Location where the filesystem is mounted. + +TODO: inclusion/exclusion lists. + +The data is derived from scanning `/proc/mounts` and calling +`statvfs(2)` on all lines that pass the inclusion checks. + ### `hwmon` The `hwmon` collector pulls data from all the sysfs subdirectories under `/sys/class/hwmon`. The supported entry types are temperature (`temp*`), fan (`fan*` and voltage (`in*`) sensors. -Metrics and dimensions: +Metrics: * `node_hwmon_temp_celsius`: Current temperature in degrees Celsius. * `node_hwmon_fan_rpm`: Current fan speed in RPM. @@ -144,6 +171,14 @@ included in your `/proc/net/dev` file. A normal set is: | | X | `colls` | Collisions while transmitting | | | X | `carrier` | ? | +By default, statistics are reported for all network interfaces except +the loopback interface (`lo`). The `--network-include=` and +`--network-exclude=` options can be used to define a comma-separated +list of interface names to explicitly include and exclude, +respectively. If an include list is set, only those interfaces are +included. Otherwise, all interfaces *not* mentioned in the exclude +list are included. + ### `textfile` The `textfile` collector can be used to conveniently export custom diff --git a/filesystem.c b/filesystem.c new file mode 100644 index 0000000..84f6805 --- /dev/null +++ b/filesystem.c @@ -0,0 +1,76 @@ +#define _POSIX_C_SOURCE 200809L + +#include <string.h> +#include <sys/statvfs.h> + +#include "filesystem.h" +#include "util.h" + +// size of input buffer for paths and lines +#define BUF_SIZE 256 + +static void filesystem_collect(scrape_req *req, void *ctx); + +const struct collector filesystem_collector = { + .name = "filesystem", + .collect = filesystem_collect, +}; + +static void filesystem_collect(scrape_req *req, void *ctx) { + // buffers + + const char *labels[][2] = { // all filled by code + { "device", 0 }, + { "fstype", 0 }, + { "mountpoint", 0 }, + { 0, 0 }, + }; + const char **dev = &labels[0][1]; + const char **fstype = &labels[1][1]; + const char **mount = &labels[2][1]; + + char buf[BUF_SIZE]; + + FILE *f; + struct statvfs fs; + + // loop over /proc/mounts to get visible mounts + + f = fopen("/proc/mounts", "r"); + if (!f) + return; + + while (fgets_line(buf, sizeof buf, f)) { + // extract device, mountpoint and filesystem type + + char *p; + *dev = strtok_r(buf, " ", &p); + if (!*dev) + continue; + *mount = strtok_r(0, " ", &p); + if (!*mount) + continue; + *fstype = strtok_r(0, " ", &p); + if (!*fstype) + continue; + + if (**dev != '/') + continue; + // TODO: device, mountpoint, filesystem exclude lists + + // report metrics from statfs + + if (statvfs(*mount, &fs) != 0) + continue; + + double bs = fs.f_frsize; + scrape_write(req, "node_filesystem_avail_bytes", labels, fs.f_bavail * bs); + scrape_write(req, "node_filesystem_files", labels, fs.f_files); + scrape_write(req, "node_filesystem_files_free", labels, fs.f_ffree); + scrape_write(req, "node_filesystem_free_bytes", labels, fs.f_bfree * bs); + scrape_write(req, "node_filesystem_readonly", labels, fs.f_flag & ST_RDONLY ? 1.0 : 0.0); + scrape_write(req, "node_filesystem_size_bytes", labels, fs.f_blocks * bs); + } + + fclose(f); +} diff --git a/filesystem.h b/filesystem.h new file mode 100644 index 0000000..60485cf --- /dev/null +++ b/filesystem.h @@ -0,0 +1,8 @@ +#ifndef PNANOE_FILESYSTEM_H_ +#define PNANOE_FILESYSTEM_H_ 1 + +#include "collector.h" + +extern const struct collector filesystem_collector; + +#endif // PNANOE_FILESYSTEM_H_ diff --git a/main.c b/main.c index 84647d0..77d4e49 100644 --- a/main.c +++ b/main.c @@ -6,6 +6,7 @@ #include <string.h> #include "cpu.h" +#include "filesystem.h" #include "hwmon.h" #include "meminfo.h" #include "network.h" @@ -16,6 +17,7 @@ static const struct collector *collectors[] = { &cpu_collector, + &filesystem_collector, &hwmon_collector, &meminfo_collector, &network_collector, |