diff options
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.yaml | 139 | ||||
-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(); |