about summary refs log tree commit diff
path: root/zfs.c
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2024-06-10 20:29:28 +0200
committerLeah Neukirchen <leah@vuxu.org>2024-06-10 20:29:28 +0200
commit653dc9cd6836d505abc1cf988b7e7186ff742f6d (patch)
treed4500deb315e8486f59a60db9af311b4f6f9ffde /zfs.c
parent5d807dc6d07dc3f0ee2a8415c1d3032ef97c6742 (diff)
downloadnano-exporter-653dc9cd6836d505abc1cf988b7e7186ff742f6d.tar.gz
nano-exporter-653dc9cd6836d505abc1cf988b7e7186ff742f6d.tar.xz
nano-exporter-653dc9cd6836d505abc1cf988b7e7186ff742f6d.zip
add very basic zfs collector
Diffstat (limited to 'zfs.c')
-rw-r--r--zfs.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/zfs.c b/zfs.c
new file mode 100644
index 0000000..283c7a8
--- /dev/null
+++ b/zfs.c
@@ -0,0 +1,56 @@
+#define _GNU_SOURCE
+#include <ctype.h>
+#include <fcntl.h>
+#include <glob.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "scrape.h"
+#include "util.h"
+
+// size of input buffer for paths and lines
+#define BUF_SIZE 256
+
+static void zfs_collect(scrape_req *req, void *ctx);
+
+const struct collector zfs_collector = {
+  .name = "zfs",
+  .collect = zfs_collect,
+};
+
+static void zfs_collect_state(scrape_req *req, char *path) {
+  char buf[BUF_SIZE];
+  char pool[BUF_SIZE] = { 0 };
+  memcpy(pool, path + 20 /* "/proc/spl/kstat/zfs/" */, strlen(path) - 20 - 6 /* "/state" */);
+
+  if (read_file_at(AT_FDCWD, path, buf, sizeof buf) < 0)
+    return;
+
+  for (char *s = buf; *s; s++)
+    *s = tolower(*s);
+
+  struct label zfs_label[] = {
+    { .key = "device", .value = pool },
+    { .key = "state", .value = buf },
+    LABEL_END,
+  };
+
+  scrape_write(req, "node_zfs_zpool_state", zfs_label, 1.0);
+}
+
+static void zfs_collect(scrape_req *req, void *ctx) {
+  (void) ctx;
+
+  // scan /proc/spl/kstat/zfs/*/state for metrics
+
+  glob_t globbuf = { 0 };
+  if (glob("/proc/spl/kstat/zfs/*/state", GLOB_NOSORT | GLOB_ONLYDIR, 0, &globbuf) != 0)
+    return;
+
+  for (size_t i = 0; i < globbuf.gl_pathc; i++)
+    zfs_collect_state(req, globbuf.gl_pathv[i]);
+
+  globfree(&globbuf);
+}