summaryrefslogtreecommitdiffstats
path: root/src/collectors/diskspace.plugin
diff options
context:
space:
mode:
Diffstat (limited to '')
l---------src/collectors/diskspace.plugin/README.md (renamed from collectors/diskspace.plugin/README.md)0
-rw-r--r--src/collectors/diskspace.plugin/integrations/disk_space.md (renamed from collectors/diskspace.plugin/integrations/disk_space.md)12
-rw-r--r--src/collectors/diskspace.plugin/metadata.yaml139
-rw-r--r--src/collectors/diskspace.plugin/plugin_diskspace.c (renamed from collectors/diskspace.plugin/plugin_diskspace.c)212
4 files changed, 245 insertions, 118 deletions
diff --git a/collectors/diskspace.plugin/README.md b/src/collectors/diskspace.plugin/README.md
index c9f4e1c5e..c9f4e1c5e 120000
--- a/collectors/diskspace.plugin/README.md
+++ b/src/collectors/diskspace.plugin/README.md
diff --git a/collectors/diskspace.plugin/integrations/disk_space.md b/src/collectors/diskspace.plugin/integrations/disk_space.md
index 1c937ed7f..47d3a9b67 100644
--- a/collectors/diskspace.plugin/integrations/disk_space.md
+++ b/src/collectors/diskspace.plugin/integrations/disk_space.md
@@ -1,9 +1,9 @@
<!--startmeta
-custom_edit_url: "https://github.com/netdata/netdata/edit/master/collectors/diskspace.plugin/README.md"
-meta_yaml: "https://github.com/netdata/netdata/edit/master/collectors/diskspace.plugin/metadata.yaml"
+custom_edit_url: "https://github.com/netdata/netdata/edit/master/src/collectors/diskspace.plugin/README.md"
+meta_yaml: "https://github.com/netdata/netdata/edit/master/src/collectors/diskspace.plugin/metadata.yaml"
sidebar_label: "Disk space"
learn_status: "Published"
-learn_rel_path: "Data Collection/Linux Systems"
+learn_rel_path: "Collecting Metrics/Linux Systems"
most_popular: False
message: "DO NOT EDIT THIS FILE DIRECTLY, IT IS GENERATED BY THE COLLECTOR'S metadata.yaml FILE"
endmeta-->
@@ -81,8 +81,8 @@ The following alerts are available:
| Alert name | On metric | Description |
|:------------|:----------|:------------|
-| [ disk_space_usage ](https://github.com/netdata/netdata/blob/master/health/health.d/disks.conf) | disk.space | disk ${label:mount_point} space utilization |
-| [ disk_inode_usage ](https://github.com/netdata/netdata/blob/master/health/health.d/disks.conf) | disk.inodes | disk ${label:mount_point} inode utilization |
+| [ disk_space_usage ](https://github.com/netdata/netdata/blob/master/src/health/health.d/disks.conf) | disk.space | disk ${label:mount_point} space utilization |
+| [ disk_inode_usage ](https://github.com/netdata/netdata/blob/master/src/health/health.d/disks.conf) | disk.inodes | disk ${label:mount_point} inode utilization |
## Setup
@@ -109,7 +109,7 @@ The file format is a modified INI syntax. The general structure is:
option3 = some third value
```
You can edit the configuration file using the `edit-config` script from the
-Netdata [config directory](https://github.com/netdata/netdata/blob/master/docs/configure/nodes.md#the-netdata-config-directory).
+Netdata [config directory](https://github.com/netdata/netdata/blob/master/docs/netdata-agent/configuration.md#the-netdata-config-directory).
```bash
cd /etc/netdata 2>/dev/null || cd /opt/netdata/etc/netdata
diff --git a/src/collectors/diskspace.plugin/metadata.yaml b/src/collectors/diskspace.plugin/metadata.yaml
new file mode 100644
index 000000000..578f56bd0
--- /dev/null
+++ b/src/collectors/diskspace.plugin/metadata.yaml
@@ -0,0 +1,139 @@
+plugin_name: diskspace.plugin
+modules:
+ - meta:
+ plugin_name: diskspace.plugin
+ module_name: diskspace.plugin
+ monitored_instance:
+ name: Disk space
+ link: ""
+ categories:
+ - data-collection.linux-systems
+ icon_filename: "hard-drive.svg"
+ related_resources:
+ integrations:
+ list:
+ - plugin_name: ebpf.plugin
+ module_name: disk
+ info_provided_to_referring_integrations:
+ description: ""
+ keywords:
+ - disk
+ - I/O
+ - space
+ - inode
+ most_popular: false
+ overview:
+ data_collection:
+ metrics_description: "Monitor Disk space metrics for proficient storage management. Keep track of usage, free space, and error rates to prevent disk space issues."
+ method_description: ""
+ supported_platforms:
+ include: []
+ exclude: []
+ multi_instance: true
+ additional_permissions:
+ description: ""
+ default_behavior:
+ auto_detection:
+ description: "The plugin reads data from `/proc/self/mountinfo` and `/proc/diskstats file`."
+ limits:
+ description: ""
+ performance_impact:
+ description: ""
+ setup:
+ prerequisites:
+ list: []
+ configuration:
+ file:
+ name: "netdata.conf"
+ section_name: "[plugin:proc:diskspace]"
+ description: "This is netdata main configuration file"
+ options:
+ description: "You can also specify per mount point `[plugin:proc:diskspace:mountpoint]`"
+ folding:
+ title: "Config options"
+ enabled: true
+ list:
+ - name: update every
+ description: Data collection frequency.
+ default_value: 1
+ required: false
+ - name: remove charts of unmounted disks
+ description: Remove chart when a device is unmounted on host.
+ default_value: yes
+ required: false
+ - name: check for new mount points every
+ description: Parse proc files frequency.
+ default_value: 15
+ required: false
+ - name: exclude space metrics on paths
+ description: Do not show metrics (charts) for listed paths. This option accepts netdata simple pattern.
+ default_value: /proc/* /sys/* /var/run/user/* /run/user/* /snap/* /var/lib/docker/*
+ required: false
+ - name: exclude space metrics on filesystems
+ description: Do not show metrics (charts) for listed filesystems. This option accepts netdata simple pattern.
+ default_value: "*gvfs *gluster* *s3fs *ipfs *davfs2 *httpfs *sshfs *gdfs *moosefs fusectl autofs"
+ required: false
+ - name: exclude inode metrics on filesystems
+ description: Do not show metrics (charts) for listed filesystems. This option accepts netdata simple pattern.
+ default_value: msdosfs msdos vfat overlayfs aufs* *unionfs
+ required: false
+ - name: space usage for all disks
+ description: Define if plugin will show metrics for space usage. When value is set to `auto` plugin will try to access information to display if filesystem or path was not discarded with previous option.
+ default_value: auto
+ required: false
+ - name: inodes usage for all disks
+ description: Define if plugin will show metrics for inode usage. When value is set to `auto` plugin will try to access information to display if filesystem or path was not discarded with previous option.
+ default_value: auto
+ required: false
+ examples:
+ folding:
+ enabled: true
+ title: ""
+ list: []
+ troubleshooting:
+ problems:
+ list: []
+ alerts:
+ - name: disk_space_usage
+ link: https://github.com/netdata/netdata/blob/master/src/health/health.d/disks.conf
+ metric: disk.space
+ info: disk ${label:mount_point} space utilization
+ os: "linux freebsd"
+ - name: disk_inode_usage
+ link: https://github.com/netdata/netdata/blob/master/src/health/health.d/disks.conf
+ metric: disk.inodes
+ info: disk ${label:mount_point} inode utilization
+ os: "linux freebsd"
+ metrics:
+ folding:
+ title: Metrics
+ enabled: false
+ description: ""
+ availability: []
+ scopes:
+ - name: mount point
+ description: ""
+ labels:
+ - name: mount_point
+ description: Path used to mount a filesystem
+ - name: filesystem
+ description: The filesystem used to format a partition.
+ - name: mount_root
+ description: Root directory where mount points are present.
+ metrics:
+ - name: disk.space
+ description: Disk Space Usage
+ unit: "GiB"
+ chart_type: stacked
+ dimensions:
+ - name: avail
+ - name: used
+ - name: reserved_for_root
+ - name: disk.inodes
+ description: Disk Files (inodes) Usage
+ unit: "inodes"
+ chart_type: stacked
+ dimensions:
+ - name: avail
+ - name: used
+ - name: reserved_for_root
diff --git a/collectors/diskspace.plugin/plugin_diskspace.c b/src/collectors/diskspace.plugin/plugin_diskspace.c
index 94257810c..d93e743ae 100644
--- a/collectors/diskspace.plugin/plugin_diskspace.c
+++ b/src/collectors/diskspace.plugin/plugin_diskspace.c
@@ -40,11 +40,10 @@ static inline void mountinfo_reload(int force) {
struct mount_point_metadata {
int do_space;
int do_inodes;
- int shown_error;
- int updated;
- int slow;
- bool function_ready;
+ bool shown_error;
+ bool updated;
+ bool slow;
STRING *filesystem;
STRING *mountroot;
@@ -68,48 +67,44 @@ static DICTIONARY *dict_mountpoints = NULL;
#define rrdset_obsolete_and_pointer_null(st) do { if(st) { rrdset_is_obsolete___safe_from_collector_thread(st); (st) = NULL; } } while(st)
-int mount_point_cleanup(const char *name, void *entry, int slow) {
- (void)name;
-
- struct mount_point_metadata *mp = (struct mount_point_metadata *)entry;
- if(!mp) return 0;
-
- if (slow != mp->slow)
- return 0;
+static void mount_points_cleanup(bool slow) {
+ struct mount_point_metadata *mp;
+ dfe_start_write(dict_mountpoints, mp) {
+ if(mp->slow != slow) continue;
- if(likely(mp->updated)) {
- mp->updated = 0;
- return 0;
+ if(mp->updated)
+ mp->updated = false;
+ else if(cleanup_mount_points)
+ dictionary_del(dict_mountpoints, mp_dfe.name);
}
+ dfe_done(mp);
- if(likely(cleanup_mount_points && mp->collected)) {
- mp->function_ready = false;
- mp->collected = 0;
- mp->updated = 0;
- mp->shown_error = 0;
+ dictionary_garbage_collect(dict_mountpoints);
+}
- string_freez(mp->filesystem);
- string_freez(mp->mountroot);
+void mountpoint_delete_cb(const DICTIONARY_ITEM *item __maybe_unused, void *entry, void *data __maybe_unused) {
+ struct mount_point_metadata *mp = (struct mount_point_metadata *)entry;
- rrdset_obsolete_and_pointer_null(mp->st_space);
- rrdset_obsolete_and_pointer_null(mp->st_inodes);
+ mp->collected = 0;
+ mp->updated = false;
+ mp->shown_error = false;
- mp->rd_space_avail = NULL;
- mp->rd_space_used = NULL;
- mp->rd_space_reserved = NULL;
+ string_freez(mp->filesystem);
+ mp->filesystem = NULL;
- mp->rd_inodes_avail = NULL;
- mp->rd_inodes_used = NULL;
- mp->rd_inodes_reserved = NULL;
- }
+ string_freez(mp->mountroot);
+ mp->mountroot = NULL;
- return 0;
-}
+ rrdset_obsolete_and_pointer_null(mp->st_space);
+ rrdset_obsolete_and_pointer_null(mp->st_inodes);
-int mount_point_cleanup_cb(const DICTIONARY_ITEM *item, void *entry, void *data __maybe_unused) {
- const char *name = dictionary_acquired_item_name(item);
+ mp->rd_space_avail = NULL;
+ mp->rd_space_used = NULL;
+ mp->rd_space_reserved = NULL;
- return mount_point_cleanup(name, (struct mount_point_metadata *)entry, 0);
+ mp->rd_inodes_avail = NULL;
+ mp->rd_inodes_used = NULL;
+ mp->rd_inodes_reserved = NULL;
}
// a copy of basic mountinfo fields
@@ -148,7 +143,7 @@ static void add_basic_mountinfo(struct basic_mountinfo **root, struct mountinfo
bmi->next = *root;
*root = bmi;
-};
+}
static void free_basic_mountinfo(struct basic_mountinfo *bmi)
{
@@ -160,7 +155,7 @@ static void free_basic_mountinfo(struct basic_mountinfo *bmi)
freez(bmi);
}
-};
+}
static void free_basic_mountinfo_list(struct basic_mountinfo *root)
{
@@ -297,8 +292,6 @@ static void calculate_values_and_show_charts(
rendered++;
}
- m->function_ready = rendered > 0;
-
if(likely(rendered))
m->collected++;
}
@@ -341,11 +334,12 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) {
true);
dict_mountpoints = dictionary_create_advanced(DICT_OPTION_NONE, &dictionary_stats_category_collectors, 0);
+ dictionary_register_delete_callback(dict_mountpoints, mountpoint_delete_cb, NULL);
}
- struct mount_point_metadata *m = dictionary_get(dict_mountpoints, mi->mount_point);
- if(unlikely(!m)) {
- int slow = 0;
+ const DICTIONARY_ITEM *item = dictionary_get_and_acquire_item(dict_mountpoints, mi->mount_point);
+ if(unlikely(!item)) {
+ bool slow = false;
int def_space = config_get_boolean_ondemand(CONFIG_SECTION_DISKSPACE, "space usage for all disks", CONFIG_BOOLEAN_AUTO);
int def_inodes = config_get_boolean_ondemand(CONFIG_SECTION_DISKSPACE, "inodes usage for all disks", CONFIG_BOOLEAN_AUTO);
@@ -393,7 +387,7 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) {
}
if ((now_monotonic_high_precision_usec() - start_time) > slow_timeout)
- slow = 1;
+ slow = true;
}
char var_name[4096 + 1];
@@ -408,55 +402,55 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) {
do_inodes = config_get_boolean_ondemand(var_name, "inodes usage", def_inodes);
struct mount_point_metadata mp = {
- .do_space = do_space,
- .do_inodes = do_inodes,
- .shown_error = 0,
- .updated = 0,
- .slow = 0,
-
- .collected = 0,
-
- .st_space = NULL,
- .rd_space_avail = NULL,
- .rd_space_used = NULL,
- .rd_space_reserved = NULL,
-
- .st_inodes = NULL,
- .rd_inodes_avail = NULL,
- .rd_inodes_used = NULL,
- .rd_inodes_reserved = NULL
+ .do_space = do_space,
+ .do_inodes = do_inodes,
+ .shown_error = false,
+ .updated = false,
+ .slow = slow,
+
+ .collected = 0,
+ .filesystem = string_strdupz(mi->filesystem),
+ .mountroot = string_strdupz(mi->root),
+ .chart_labels = rrdlabels_create(),
+
+ .st_space = NULL,
+ .rd_space_avail = NULL,
+ .rd_space_used = NULL,
+ .rd_space_reserved = NULL,
+
+ .st_inodes = NULL,
+ .rd_inodes_avail = NULL,
+ .rd_inodes_used = NULL,
+ .rd_inodes_reserved = NULL
};
- mp.filesystem = string_strdupz(mi->filesystem);
- mp.mountroot = string_strdupz(mi->root);
-
- mp.chart_labels = rrdlabels_create();
rrdlabels_add(mp.chart_labels, "mount_point", mi->mount_point, RRDLABEL_SRC_AUTO);
rrdlabels_add(mp.chart_labels, "filesystem", mi->filesystem, RRDLABEL_SRC_AUTO);
rrdlabels_add(mp.chart_labels, "mount_root", mi->root, RRDLABEL_SRC_AUTO);
- m = dictionary_set(dict_mountpoints, mi->mount_point, &mp, sizeof(struct mount_point_metadata));
-
- m->slow = slow;
+ item = dictionary_set_and_acquire_item(dict_mountpoints, mi->mount_point, &mp, sizeof(struct mount_point_metadata));
}
+ struct mount_point_metadata *m = dictionary_acquired_item_value(item);
if (m->slow) {
add_basic_mountinfo(&slow_mountinfo_tmp_root, mi);
- return;
+ goto cleanup;
}
- m->updated = 1;
+ m->updated = true;
- if(unlikely(m->do_space == CONFIG_BOOLEAN_NO && m->do_inodes == CONFIG_BOOLEAN_NO))
- return;
+ if(unlikely(m->do_space == CONFIG_BOOLEAN_NO && m->do_inodes == CONFIG_BOOLEAN_NO)) {
+ goto cleanup;
+ }
if (unlikely(
mi->flags & MOUNTINFO_READONLY &&
!(mi->flags & MOUNTINFO_IS_IN_SYSD_PROTECTED_LIST) &&
!m->collected &&
m->do_space != CONFIG_BOOLEAN_YES &&
- m->do_inodes != CONFIG_BOOLEAN_YES))
- return;
+ m->do_inodes != CONFIG_BOOLEAN_YES)) {
+ goto cleanup;
+ }
usec_t start_time = now_monotonic_high_precision_usec();
struct statvfs buff_statvfs;
@@ -469,15 +463,15 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) {
, mi->filesystem?mi->filesystem:""
, mi->root?mi->root:""
);
- m->shown_error = 1;
+ m->shown_error = true;
}
- return;
+ goto cleanup;
}
if ((now_monotonic_high_precision_usec() - start_time) > slow_timeout)
- m->slow = 1;
+ m->slow = true;
- m->shown_error = 0;
+ m->shown_error = false;
struct basic_mountinfo bmi;
bmi.mount_point = mi->mount_point;
@@ -486,12 +480,17 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) {
bmi.root = mi->root;
calculate_values_and_show_charts(&bmi, m, &buff_statvfs, update_every);
+
+cleanup:
+ dictionary_acquired_item_release(dict_mountpoints, item);
}
static inline void do_slow_disk_space_stats(struct basic_mountinfo *mi, int update_every) {
- struct mount_point_metadata *m = dictionary_get(dict_mountpoints, mi->mount_point);
+ const DICTIONARY_ITEM *item = dictionary_get_and_acquire_item(dict_mountpoints, mi->mount_point);
+ if(!item) return;
- m->updated = 1;
+ struct mount_point_metadata *m = dictionary_acquired_item_value(item);
+ m->updated = true;
struct statvfs buff_statvfs;
if (statvfs(mi->mount_point, &buff_statvfs) < 0) {
@@ -502,13 +501,16 @@ static inline void do_slow_disk_space_stats(struct basic_mountinfo *mi, int upda
, mi->filesystem?mi->filesystem:""
, mi->root?mi->root:""
);
- m->shown_error = 1;
+ m->shown_error = true;
}
- return;
+ goto cleanup;
}
- m->shown_error = 0;
+ m->shown_error = false;
calculate_values_and_show_charts(mi, m, &buff_statvfs, update_every);
+
+cleanup:
+ dictionary_acquired_item_release(dict_mountpoints, item);
}
static void diskspace_slow_worker_cleanup(void *ptr)
@@ -584,13 +586,9 @@ void *diskspace_slow_worker(void *ptr)
if(unlikely(!service_running(SERVICE_COLLECTORS))) break;
- worker_is_busy(WORKER_JOB_SLOW_CLEANUP);
-
- for(bmi = slow_mountinfo_root; bmi; bmi = bmi->next) {
- struct mount_point_metadata *m = dictionary_get(dict_mountpoints, bmi->mount_point);
-
- if (m)
- mount_point_cleanup(bmi->mount_point, m, 1);
+ if(dict_mountpoints) {
+ worker_is_busy(WORKER_JOB_SLOW_CLEANUP);
+ mount_points_cleanup(true);
}
usec_t dt = now_monotonic_high_precision_usec() - start_time;
@@ -636,12 +634,8 @@ static void diskspace_main_cleanup(void *ptr) {
#error WORKER_UTILIZATION_MAX_JOB_TYPES has to be at least 3
#endif
-int diskspace_function_mount_points(BUFFER *wb, int timeout __maybe_unused, const char *function __maybe_unused,
- void *collector_data __maybe_unused,
- rrd_function_result_callback_t result_cb, void *result_cb_data,
- rrd_function_is_cancelled_cb_t is_cancelled_cb, void *is_cancelled_cb_data,
- rrd_function_register_canceller_cb_t register_canceller_cb __maybe_unused,
- void *register_canceller_cb_data __maybe_unused) {
+int diskspace_function_mount_points(BUFFER *wb, const char *function __maybe_unused) {
+ netdata_mutex_lock(&slow_mountinfo_mutex);
buffer_flush(wb);
wb->content_type = CT_APPLICATION_JSON;
@@ -651,6 +645,7 @@ int diskspace_function_mount_points(BUFFER *wb, int timeout __maybe_unused, cons
buffer_json_member_add_uint64(wb, "status", HTTP_RESP_OK);
buffer_json_member_add_string(wb, "type", "table");
buffer_json_member_add_time_t(wb, "update_every", 1);
+ buffer_json_member_add_boolean(wb, "has_history", false);
buffer_json_member_add_string(wb, "help", RRDFUNCTIONS_DISKSPACE_HELP);
buffer_json_member_add_array(wb, "data");
@@ -665,8 +660,8 @@ int diskspace_function_mount_points(BUFFER *wb, int timeout __maybe_unused, cons
double max_inodes_reserved = 0.0;
struct mount_point_metadata *mp;
- dfe_start_write(dict_mountpoints, mp) {
- if (!mp->function_ready)
+ dfe_start_read(dict_mountpoints, mp) {
+ if (!mp->collected)
continue;
buffer_json_add_array_item_array(wb);
@@ -846,16 +841,8 @@ int diskspace_function_mount_points(BUFFER *wb, int timeout __maybe_unused, cons
buffer_json_member_add_time_t(wb, "expires", now_realtime_sec() + 1);
buffer_json_finalize(wb);
- int response = HTTP_RESP_OK;
- if(is_cancelled_cb && is_cancelled_cb(is_cancelled_cb_data)) {
- buffer_flush(wb);
- response = HTTP_RESP_CLIENT_CLOSED_REQUEST;
- }
-
- if(result_cb)
- result_cb(wb, response, result_cb_data);
-
- return response;
+ netdata_mutex_unlock(&slow_mountinfo_mutex);
+ return HTTP_RESP_OK;
}
void *diskspace_main(void *ptr) {
@@ -864,8 +851,10 @@ void *diskspace_main(void *ptr) {
worker_register_job_name(WORKER_JOB_MOUNTPOINT, "mountpoint");
worker_register_job_name(WORKER_JOB_CLEANUP, "cleanup");
- rrd_collector_started();
- rrd_function_add(localhost, NULL, "mount-points", 10, RRDFUNCTIONS_DISKSPACE_HELP, true, diskspace_function_mount_points, NULL);
+ rrd_function_add_inline(localhost, NULL, "mount-points", 10,
+ RRDFUNCTIONS_PRIORITY_DEFAULT, RRDFUNCTIONS_DISKSPACE_HELP,
+ "top", HTTP_ACCESS_ANONYMOUS_DATA,
+ diskspace_function_mount_points);
netdata_thread_cleanup_push(diskspace_main_cleanup, ptr);
@@ -934,9 +923,8 @@ void *diskspace_main(void *ptr) {
if(dict_mountpoints) {
worker_is_busy(WORKER_JOB_CLEANUP);
- dictionary_walkthrough_read(dict_mountpoints, mount_point_cleanup_cb, NULL);
+ mount_points_cleanup(false);
}
-
}
worker_unregister();