diff options
Diffstat (limited to 'filesystem.c')
-rw-r--r-- | filesystem.c | 76 |
1 files changed, 76 insertions, 0 deletions
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); +} |