diff options
-rw-r--r-- | README.md | 14 | ||||
-rw-r--r-- | filesystem.c | 74 |
2 files changed, 81 insertions, 7 deletions
diff --git a/README.md b/README.md index 453b992..1114d4b 100644 --- a/README.md +++ b/README.md @@ -152,11 +152,21 @@ Metrics: Labels: -* `device`: Device node mounted at the location. +* `device`: Device node path mounted at the location. * `fstype`: Mounted filesystem type. * `mountpoint`: Location where the filesystem is mounted. -TODO: inclusion/exclusion lists. +By default, all mounts where the device path starts with an `/` are +included. Command line arguments of the form +`--filesystem-{in,ex}clude-{device,type,mount}=X,Y,Z` can be used to +define comma-separated inclusion and exclusion lists for the device +path, filesystem type and mountpoint labels, respectively. Each of the +three categories is tested independently, and only if a mounted +filesystem passes all three tests, it is included in the metrics. For +each category, if an include list is specified, only the explicitly +listed values are accepted -- this overrides even the `/` prefix test +for devices. If an include list is not set, all values not on the +exclusion list are accepted. The data is derived from scanning `/proc/mounts` and calling `statvfs(2)` on all lines that pass the inclusion checks. diff --git a/filesystem.c b/filesystem.c index d31518e..6ed4407 100644 --- a/filesystem.c +++ b/filesystem.c @@ -9,15 +9,59 @@ // size of input buffer for paths and lines #define BUF_SIZE 256 +static void *filesystem_init(int argc, char *argv[]); static void filesystem_collect(scrape_req *req, void *ctx); const struct collector filesystem_collector = { .name = "filesystem", .collect = filesystem_collect, + .init = filesystem_init, + .has_args = true, }; -static void filesystem_collect(scrape_req *req, void *ctx) { - (void) ctx; +struct filesystem_context { + struct slist *include_device; + struct slist *exclude_device; + struct slist *include_mount; + struct slist *exclude_mount; + struct slist *include_type; + struct slist *exclude_type; +}; + +static void *filesystem_init(int argc, char *argv[]) { + struct filesystem_context *ctx = must_malloc(sizeof *ctx); + + ctx->include_device = 0; + ctx->exclude_device = 0; + ctx->include_mount = 0; + ctx->exclude_mount = 0; + ctx->include_type = 0; + ctx->exclude_type = 0; + + for (int arg = 0; arg < argc; arg++) { + if (strncmp(argv[arg], "include-device=", 15) == 0) { + ctx->include_device = slist_split(&argv[arg][15], ","); + } else if (strncmp(argv[arg], "exclude-device=", 15) == 0) { + ctx->exclude_device = slist_split(&argv[arg][15], ","); + } else if (strncmp(argv[arg], "include-mount=", 14) == 0) { + ctx->include_mount = slist_split(&argv[arg][14], ","); + } else if (strncmp(argv[arg], "exclude-mount=", 14) == 0) { + ctx->exclude_mount = slist_split(&argv[arg][14], ","); + } else if (strncmp(argv[arg], "include-type=", 13) == 0) { + ctx->include_type = slist_split(&argv[arg][13], ","); + } else if (strncmp(argv[arg], "exclude-type=", 13) == 0) { + ctx->exclude_type = slist_split(&argv[arg][13], ","); + } else { + fprintf(stderr, "unknown argument for filesystem collector: %s", argv[arg]); + return 0; + } + } + + return ctx; +} + +static void filesystem_collect(scrape_req *req, void *ctx_ptr) { + struct filesystem_context *ctx = ctx_ptr; // buffers @@ -56,9 +100,29 @@ static void filesystem_collect(scrape_req *req, void *ctx) { if (!*fstype) continue; - if (**dev != '/') - continue; - // TODO: device, mountpoint, filesystem exclude lists + if (ctx->include_device) { + if (!slist_contains(ctx->include_device, *dev)) + continue; + } else { + if (**dev != '/') + continue; + if (ctx->exclude_device && slist_contains(ctx->exclude_device, *dev)) + continue; + } + if (ctx->include_mount) { + if (!slist_contains(ctx->include_mount, *mount)) + continue; + } else if (ctx->exclude_mount) { + if (slist_contains(ctx->exclude_mount, *mount)) + continue; + } + if (ctx->include_type) { + if (!slist_contains(ctx->include_type, *fstype)) + continue; + } else if (ctx->exclude_type) { + if (slist_contains(ctx->exclude_type, *fstype)) + continue; + } // report metrics from statfs |