allow certain paths to be excluded from disk space statistics; fixes #1206
Costa Tsaousis (ktsaou) committed
Nov 5, 2016 at 03:42 UTC
7d28ae33c4227645b918a9f7829cea9801eb815a
1 file changed
+103
-11
src/proc_diskstats.c
+103
-11
@@ -56,10 +56,88 @@ static inline void mountinfo_reload(int force) {
56
}
57
}
58
59
+
60
+// linked list of mount points that are by default disabled
61
+static struct excluded_mount_point {
62
+ const char *prefix;
63
+ size_t len;
64
+ struct excluded_mount_point *next;
65
+} *excluded_mount_points = NULL;
66
+
67
+static inline int is_mount_point_excluded(const char *mount_point) {
68
+ static int initialized = 0;
69
+
70
+ if(unlikely(!initialized)) {
71
+ initialized = 1;
72
+
73
+ char *a = config_get("plugin:proc:/proc/diskstats", "exclude space metrics on paths", "/var/run/user/ /run/user/");
74
+ if(a && *a) {
75
+ char *s = a;
76
+
77
+ while(s && *s) {
78
+ // skip all spaces
79
+ while(isspace(*s)) s++;
80
+
81
+ // empty string
82
+ if(unlikely(!*s)) break;
83
+
84
+ // find the next space
85
+ char *c = s;
86
+ while(*c && !isspace(*c)) c++;
87
+
88
+ char *n;
89
+ if(likely(*c)) n = c + 1;
90
+ else n = NULL;
91
+
92
+ // terminate our string
93
+ *c = '\0';
94
+
95
+ // allocate the structure
96
+ struct excluded_mount_point *m = mallocz(sizeof(struct excluded_mount_point));
97
+ m->prefix = strdup(s);
98
+ m->len = strlen(m->prefix);
99
+ m->next = excluded_mount_points;
100
+ excluded_mount_points = m;
101
+
102
+ // prepare for next loop
103
+ s = n;
104
+ if(likely(n)) *c = ' ';
105
+ }
106
+ }
107
+ }
108
+
109
+ size_t len = strlen(mount_point);
110
+ struct excluded_mount_point *m;
111
+ for(m = excluded_mount_points; m ; m = m->next) {
112
+ if(m->len <= len) {
113
+ // fprintf(stderr, "SPACE: comparing '%s' with '%s'\n", mount_point, m->prefix);
114
+ if(strncmp(m->prefix, mount_point, m->len) == 0) {
115
+ // fprintf(stderr, "SPACE: excluded '%s'\n", mount_point);
116
+ return 1;
117
+ }
118
+ }
119
+ }
120
+
121
+ // fprintf(stderr, "SPACE: included '%s'\n", mount_point);
122
+ return 0;
123
+}
124
+
125
+// Data to be stored in DICTIONARY mount_points used by do_disk_space_stats().
126
+// This DICTIONARY is used to lookup the settings of the mount point on each iteration.
127
+struct mount_point_metadata {
128
+ int do_space;
129
+ int do_inodes;
130
+};
131
+
132
static inline void do_disk_space_stats(struct disk *d, const char *mount_point, const char *mount_source, const char *disk, const char *family, int update_every, unsigned long long dt) {
133
+ static DICTIONARY *mount_points = NULL;
134
int do_space, do_inodes;
135
62
- if(d) {
136
+ if(unlikely(!mount_points)) {
137
+ mount_points = dictionary_create(DICTIONARY_FLAG_SINGLE_THREADED);
138
+ }
139
+
140
+ if(unlikely(d)) {
141
// verify we collected the metrics for the right disk.
142
// if not the mountpoint has changed.
143
@@ -80,19 +158,33 @@ static inline void do_disk_space_stats(struct disk *d, const char *mount_point,
158
do_inodes = d->do_inodes;
159
}
160
else {
83
- char var_name[4096 + 1];
84
- snprintfz(var_name, 4096, "plugin:proc:/proc/diskstats:%s", mount_point);
161
+ struct mount_point_metadata *m = dictionary_get(mount_points, mount_point);
162
+ if(!m) {
163
+ char var_name[4096 + 1];
164
+ snprintfz(var_name, 4096, "plugin:proc:/proc/diskstats:%s", mount_point);
165
86
- int def_space = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "space usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
87
- int def_inodes = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "inodes usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
166
+ int def_space = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "space usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
167
+ int def_inodes = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "inodes usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
168
89
- if(unlikely(strncmp(mount_point, "/run/user/", 10) == 0)) {
90
- def_space = CONFIG_ONDEMAND_NO;
91
- def_inodes = CONFIG_ONDEMAND_NO;
92
- }
169
+ if(is_mount_point_excluded(mount_point)) {
170
+ def_space = CONFIG_ONDEMAND_NO;
171
+ def_inodes = CONFIG_ONDEMAND_NO;
172
+ }
173
94
- do_space = config_get_boolean_ondemand(var_name, "space usage", def_space);
95
- do_inodes = config_get_boolean_ondemand(var_name, "inodes usage", def_inodes);
174
+ do_space = config_get_boolean_ondemand(var_name, "space usage", def_space);
175
+ do_inodes = config_get_boolean_ondemand(var_name, "inodes usage", def_inodes);
176
+
177
+ struct mount_point_metadata mp = {
178
+ .do_space = do_space,
179
+ .do_inodes = do_inodes
180
+ };
181
+
182
+ dictionary_set(mount_points, mount_point, &mp, sizeof(struct mount_point_metadata));
183
+ }
184
+ else {
185
+ do_space = m->do_space;
186
+ do_inodes = m->do_inodes;
187
+ }
188
}
189
190
if(do_space == CONFIG_ONDEMAND_NO && do_inodes == CONFIG_ONDEMAND_NO)