@cryptotaxi247 / netdata-1 / commits / 5ba248ecd

ZFS plugin for Linux; fixes #1994

Costa Tsaousis (ktsaou) committed Mar 25, 2017 at 23:51 UTC 5ba248ecd55038de0744919f47c2b76c65f166ee
9 files changed +935 -2
CMakeLists.txt
+1
@@ -83,6 +83,7 @@ set(NETDATA_SOURCE_FILES
83 src/proc_self_mountinfo.c
84 src/proc_self_mountinfo.h
85 src/proc_softirqs.c
86 + src/proc_spl_kstat_zfs.c
87 src/proc_stat.c
88 src/proc_sys_kernel_random_entropy_avail.c
89 src/proc_uptime.c
conf.d/Makefile.am
+1
@@ -81,6 +81,7 @@ dist_healthconfig_DATA = \
81 health.d/squid.conf \
82 health.d/varnish.conf \
83 health.d/web_log.conf \
84 + health.d/zfs.conf \
85 $(NULL)
86
87 if LINUX
conf.d/health.d/zfs.conf new
+10
@@ -0,0 +1,10 @@
1 +
2 + alarm: zfs_memory_throttle
3 + on: zfs.memory_ops
4 + lookup: sum -10m unaligned absolute of throttled
5 + units: events
6 + every: 1m
7 + warn: $this > 0
8 + delay: down 1h multiplier 1.5 max 2h
9 + info: the number of times ZFS had to limit the ARC growth in the last 10 minutes
10 + to: sysadmin
src/Makefile.am
+1
@@ -178,6 +178,7 @@ netdata_SOURCES += \
178 proc_net_softnet_stat.c \
179 proc_net_stat_conntrack.c \
180 proc_net_stat_synproxy.c \
181 + proc_spl_kstat_zfs.c \
182 proc_stat.c \
183 proc_sys_kernel_random_entropy_avail.c \
184 proc_vmstat.c \
src/plugin_proc.c
+3
@@ -49,6 +49,9 @@ static struct proc_module {
49 { .name = "/proc/net/rpc/nfsd", .dim = "nfsd", .func = do_proc_net_rpc_nfsd },
50 { .name = "/proc/net/rpc/nfs", .dim = "nfs", .func = do_proc_net_rpc_nfs },
51
52 + // ZFS metrics
53 + { .name = "/proc/spl/kstat/zfs/arcstats", .dim = "zfs_arcstats", .func = do_proc_spl_kstat_zfs_arcstats },
54 +
55 // IPC metrics
56 { .name = "ipc", .dim = "ipc", .func = do_ipc },
57
src/plugin_proc.h
+1
@@ -25,6 +25,7 @@ extern int do_proc_net_softnet_stat(int update_every, usec_t dt);
25 extern int do_proc_uptime(int update_every, usec_t dt);
26 extern int do_proc_sys_devices_system_edac_mc(int update_every, usec_t dt);
27 extern int do_proc_sys_devices_system_node(int update_every, usec_t dt);
28 +extern int do_proc_spl_kstat_zfs_arcstats(int update_every, usec_t dt);
29
30 extern int get_numa_node_count(void);
31
src/proc_spl_kstat_zfs.c new
+910
@@ -0,0 +1,910 @@
1 +#include "common.h"
2 +
3 +#define ZFS_PROC_ARCSTATS "/proc/spl/kstat/zfs/arcstats"
4 +#define ZFS_FAMILY_SIZE "size"
5 +#define ZFS_FAMILY_EFFICIENCY "efficiency"
6 +#define ZFS_FAMILY_ACCESSES "accesses"
7 +#define ZFS_FAMILY_OPERATIONS "operations"
8 +#define ZFS_FAMILY_HASH "hashes"
9 +
10 +static struct arcstats {
11 + unsigned long long hits;
12 + unsigned long long misses;
13 + unsigned long long demand_data_hits;
14 + unsigned long long demand_data_misses;
15 + unsigned long long demand_metadata_hits;
16 + unsigned long long demand_metadata_misses;
17 + unsigned long long prefetch_data_hits;
18 + unsigned long long prefetch_data_misses;
19 + unsigned long long prefetch_metadata_hits;
20 + unsigned long long prefetch_metadata_misses;
21 + unsigned long long mru_hits;
22 + unsigned long long mru_ghost_hits;
23 + unsigned long long mfu_hits;
24 + unsigned long long mfu_ghost_hits;
25 + unsigned long long deleted;
26 + unsigned long long mutex_miss;
27 + unsigned long long evict_skip;
28 + unsigned long long evict_not_enough;
29 + unsigned long long evict_l2_cached;
30 + unsigned long long evict_l2_eligible;
31 + unsigned long long evict_l2_ineligible;
32 + unsigned long long evict_l2_skip;
33 + unsigned long long hash_elements;
34 + unsigned long long hash_elements_max;
35 + unsigned long long hash_collisions;
36 + unsigned long long hash_chains;
37 + unsigned long long hash_chain_max;
38 + unsigned long long p;
39 + unsigned long long c;
40 + unsigned long long c_min;
41 + unsigned long long c_max;
42 + unsigned long long size;
43 + unsigned long long hdr_size;
44 + unsigned long long data_size;
45 + unsigned long long metadata_size;
46 + unsigned long long other_size;
47 + unsigned long long anon_size;
48 + unsigned long long anon_evictable_data;
49 + unsigned long long anon_evictable_metadata;
50 + unsigned long long mru_size;
51 + unsigned long long mru_evictable_data;
52 + unsigned long long mru_evictable_metadata;
53 + unsigned long long mru_ghost_size;
54 + unsigned long long mru_ghost_evictable_data;
55 + unsigned long long mru_ghost_evictable_metadata;
56 + unsigned long long mfu_size;
57 + unsigned long long mfu_evictable_data;
58 + unsigned long long mfu_evictable_metadata;
59 + unsigned long long mfu_ghost_size;
60 + unsigned long long mfu_ghost_evictable_data;
61 + unsigned long long mfu_ghost_evictable_metadata;
62 + unsigned long long l2_hits;
63 + unsigned long long l2_misses;
64 + unsigned long long l2_feeds;
65 + unsigned long long l2_rw_clash;
66 + unsigned long long l2_read_bytes;
67 + unsigned long long l2_write_bytes;
68 + unsigned long long l2_writes_sent;
69 + unsigned long long l2_writes_done;
70 + unsigned long long l2_writes_error;
71 + unsigned long long l2_writes_lock_retry;
72 + unsigned long long l2_evict_lock_retry;
73 + unsigned long long l2_evict_reading;
74 + unsigned long long l2_evict_l1cached;
75 + unsigned long long l2_free_on_write;
76 + unsigned long long l2_cdata_free_on_write;
77 + unsigned long long l2_abort_lowmem;
78 + unsigned long long l2_cksum_bad;
79 + unsigned long long l2_io_error;
80 + unsigned long long l2_size;
81 + unsigned long long l2_asize;
82 + unsigned long long l2_hdr_size;
83 + unsigned long long l2_compress_successes;
84 + unsigned long long l2_compress_zeros;
85 + unsigned long long l2_compress_failures;
86 + unsigned long long memory_throttle_count;
87 + unsigned long long duplicate_buffers;
88 + unsigned long long duplicate_buffers_size;
89 + unsigned long long duplicate_reads;
90 + unsigned long long memory_direct_count;
91 + unsigned long long memory_indirect_count;
92 + unsigned long long arc_no_grow;
93 + unsigned long long arc_tempreserve;
94 + unsigned long long arc_loaned_bytes;
95 + unsigned long long arc_prune;
96 + unsigned long long arc_meta_used;
97 + unsigned long long arc_meta_limit;
98 + unsigned long long arc_meta_max;
99 + unsigned long long arc_meta_min;
100 + unsigned long long arc_need_free;
101 + unsigned long long arc_sys_free;
102 +} arcstats = { 0 };
103 +
104 +int l2exist = -1;
105 +
106 +static void generate_charts_arcstats(int update_every) {
107 +
108 + // ARC reads
109 + unsigned long long aread = arcstats.hits + arcstats.misses;
110 +
111 + // Demand reads
112 + unsigned long long dhit = arcstats.demand_data_hits + arcstats.demand_metadata_hits;
113 + unsigned long long dmiss = arcstats.demand_data_misses + arcstats.demand_metadata_misses;
114 + unsigned long long dread = dhit + dmiss;
115 +
116 + // Prefetch reads
117 + unsigned long long phit = arcstats.prefetch_data_hits + arcstats.prefetch_metadata_hits;
118 + unsigned long long pmiss = arcstats.prefetch_data_misses + arcstats.prefetch_metadata_misses;
119 + unsigned long long pread = phit + pmiss;
120 +
121 + // Metadata reads
122 + unsigned long long mhit = arcstats.prefetch_metadata_hits + arcstats.demand_metadata_hits;
123 + unsigned long long mmiss = arcstats.prefetch_metadata_misses + arcstats.demand_metadata_misses;
124 + unsigned long long mread = mhit + mmiss;
125 +
126 + // l2 reads
127 + unsigned long long l2hit = arcstats.l2_hits + arcstats.l2_misses;
128 + unsigned long long l2miss = arcstats.prefetch_metadata_misses + arcstats.demand_metadata_misses;
129 + unsigned long long l2read = l2hit + l2miss;
130 +
131 + // --------------------------------------------------------------------
132 +
133 + {
134 + static RRDSET *st_arc_size = NULL;
135 + static RRDDIM *rd_arc_size = NULL;
136 + static RRDDIM *rd_arc_target_size = NULL;
137 + static RRDDIM *rd_arc_target_min_size = NULL;
138 + static RRDDIM *rd_arc_target_max_size = NULL;
139 +
140 + if (unlikely(!st_arc_size)) {
141 + st_arc_size = rrdset_create_localhost(
142 + "zfs"
143 + , "arc_size"
144 + , NULL
145 + , ZFS_FAMILY_SIZE
146 + , NULL
147 + , "ZFS ARC Size"
148 + , "MB"
149 + , 2000
150 + , update_every
151 + , RRDSET_TYPE_AREA
152 + );
153 +
154 + rd_arc_size = rrddim_add(st_arc_size, "size", "arcsz", 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
155 + rd_arc_target_size = rrddim_add(st_arc_size, "target", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
156 + rd_arc_target_min_size = rrddim_add(st_arc_size, "min", "min (hard limit)", 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
157 + rd_arc_target_max_size = rrddim_add(st_arc_size, "max", "max (high water)", 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
158 + }
159 + else
160 + rrdset_next(st_arc_size);
161 +
162 + rrddim_set_by_pointer(st_arc_size, rd_arc_size, arcstats.size);
163 + rrddim_set_by_pointer(st_arc_size, rd_arc_target_size, arcstats.c);
164 + rrddim_set_by_pointer(st_arc_size, rd_arc_target_min_size, arcstats.c_min);
165 + rrddim_set_by_pointer(st_arc_size, rd_arc_target_max_size, arcstats.c_max);
166 + rrdset_done(st_arc_size);
167 + }
168 +
169 + // --------------------------------------------------------------------
170 +
171 + if(likely(l2exist)) {
172 + static RRDSET *st_l2_size = NULL;
173 + static RRDDIM *rd_l2_size = NULL;
174 + static RRDDIM *rd_l2_asize = NULL;
175 +
176 + if (unlikely(!st_l2_size)) {
177 + st_l2_size = rrdset_create_localhost(
178 + "zfs"
179 + , "l2_size"
180 + , NULL
181 + , ZFS_FAMILY_SIZE
182 + , NULL
183 + , "ZFS L2 ARC Size"
184 + , "MB"
185 + , 2000
186 + , update_every
187 + , RRDSET_TYPE_AREA
188 + );
189 +
190 + rd_l2_asize = rrddim_add(st_l2_size, "actual", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
191 + rd_l2_size = rrddim_add(st_l2_size, "size", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
192 + }
193 + else
194 + rrdset_next(st_l2_size);
195 +
196 + rrddim_set_by_pointer(st_l2_size, rd_l2_size, arcstats.l2_size);
197 + rrddim_set_by_pointer(st_l2_size, rd_l2_asize, arcstats.l2_asize);
198 + rrdset_done(st_l2_size);
199 + }
200 +
201 + // --------------------------------------------------------------------
202 +
203 + {
204 + static RRDSET *st_reads = NULL;
205 + static RRDDIM *rd_aread = NULL;
206 + static RRDDIM *rd_dread = NULL;
207 + static RRDDIM *rd_pread = NULL;
208 + static RRDDIM *rd_mread = NULL;
209 + static RRDDIM *rd_l2read = NULL;
210 +
211 + if (unlikely(!st_reads)) {
212 + st_reads = rrdset_create_localhost(
213 + "zfs"
214 + , "reads"
215 + , NULL
216 + , ZFS_FAMILY_ACCESSES
217 + , NULL
218 + , "ZFS Reads"
219 + , "reads/s"
220 + , 2010
221 + , update_every
222 + , RRDSET_TYPE_AREA
223 + );
224 +
225 + rd_aread = rrddim_add(st_reads, "areads", "arc", 1, 1, RRD_ALGORITHM_INCREMENTAL);
226 + rd_dread = rrddim_add(st_reads, "dreads", "demand", 1, 1, RRD_ALGORITHM_INCREMENTAL);
227 + rd_pread = rrddim_add(st_reads, "preads", "prefetch", 1, 1, RRD_ALGORITHM_INCREMENTAL);
228 + rd_mread = rrddim_add(st_reads, "mreads", "metadata", 1, 1, RRD_ALGORITHM_INCREMENTAL);
229 +
230 + if(l2exist)
231 + rd_l2read = rrddim_add(st_reads, "l2reads", "l2", 1, 1, RRD_ALGORITHM_INCREMENTAL);
232 + }
233 + else
234 + rrdset_next(st_reads);
235 +
236 + rrddim_set_by_pointer(st_reads, rd_aread, aread);
237 + rrddim_set_by_pointer(st_reads, rd_dread, dread);
238 + rrddim_set_by_pointer(st_reads, rd_pread, pread);
239 + rrddim_set_by_pointer(st_reads, rd_mread, mread);
240 +
241 + if(l2exist)
242 + rrddim_set_by_pointer(st_reads, rd_l2read, l2read);
243 +
244 + rrdset_done(st_reads);
245 + }
246 +
247 + // --------------------------------------------------------------------
248 +
249 + if(likely(l2exist)) {
250 + static RRDSET *st_l2bytes = NULL;
251 + static RRDDIM *rd_l2_read_bytes = NULL;
252 + static RRDDIM *rd_l2_write_bytes = NULL;
253 +
254 + if (unlikely(!st_l2bytes)) {
255 + st_l2bytes = rrdset_create_localhost(
256 + "zfs"
257 + , "bytes"
258 + , NULL
259 + , ZFS_FAMILY_ACCESSES
260 + , NULL
261 + , "ZFS ARC L2 Read/Write Rate"
262 + , "kilobytes/s"
263 + , 2200
264 + , update_every
265 + , RRDSET_TYPE_AREA
266 + );
267 +
268 + rd_l2_read_bytes = rrddim_add(st_l2bytes, "read", NULL, 1, 1024, RRD_ALGORITHM_INCREMENTAL);
269 + rd_l2_write_bytes = rrddim_add(st_l2bytes, "write", NULL, -1, 1024, RRD_ALGORITHM_INCREMENTAL);
270 + }
271 + else
272 + rrdset_next(st_l2bytes);
273 +
274 + rrddim_set_by_pointer(st_l2bytes, rd_l2_read_bytes, arcstats.l2_read_bytes);
275 + rrddim_set_by_pointer(st_l2bytes, rd_l2_write_bytes, arcstats.l2_write_bytes);
276 + rrdset_done(st_l2bytes);
277 + }
278 +
279 + // --------------------------------------------------------------------
280 +
281 + {
282 + static RRDSET *st_ahits = NULL;
283 + static RRDDIM *rd_ahits = NULL;
284 + static RRDDIM *rd_amisses = NULL;
285 +
286 + if (unlikely(!st_ahits)) {
287 + st_ahits = rrdset_create_localhost(
288 + "zfs"
289 + , "hits"
290 + , NULL
291 + , ZFS_FAMILY_EFFICIENCY
292 + , NULL
293 + , "ZFS ARC Hits"
294 + , "percentage"
295 + , 2020
296 + , update_every
297 + , RRDSET_TYPE_STACKED
298 + );
299 +
300 + rd_ahits = rrddim_add(st_ahits, "hits", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
301 + rd_amisses = rrddim_add(st_ahits, "misses", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
302 + }
303 + else
304 + rrdset_next(st_ahits);
305 +
306 + rrddim_set_by_pointer(st_ahits, rd_ahits, arcstats.hits);
307 + rrddim_set_by_pointer(st_ahits, rd_amisses, arcstats.misses);
308 + rrdset_done(st_ahits);
309 + }
310 +
311 + // --------------------------------------------------------------------
312 +
313 + {
314 + static RRDSET *st_dhits = NULL;
315 + static RRDDIM *rd_dhits = NULL;
316 + static RRDDIM *rd_dmisses = NULL;
317 +
318 + if (unlikely(!st_dhits)) {
319 + st_dhits = rrdset_create_localhost(
320 + "zfs"
321 + , "dhits"
322 + , NULL
323 + , ZFS_FAMILY_EFFICIENCY
324 + , NULL
325 + , "ZFS Demand Hits"
326 + , "percentage"
327 + , 2030
328 + , update_every
329 + , RRDSET_TYPE_STACKED
330 + );
331 +
332 + rd_dhits = rrddim_add(st_dhits, "hits", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
333 + rd_dmisses = rrddim_add(st_dhits, "misses", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
334 + }
335 + else
336 + rrdset_next(st_dhits);
337 +
338 + rrddim_set_by_pointer(st_dhits, rd_dhits, dhit);
339 + rrddim_set_by_pointer(st_dhits, rd_dmisses, dmiss);
340 + rrdset_done(st_dhits);
341 + }
342 +
343 + // --------------------------------------------------------------------
344 +
345 + {
346 + static RRDSET *st_phits = NULL;
347 + static RRDDIM *rd_phits = NULL;
348 + static RRDDIM *rd_pmisses = NULL;
349 +
350 + if (unlikely(!st_phits)) {
351 + st_phits = rrdset_create_localhost(
352 + "zfs"
353 + , "phits"
354 + , NULL
355 + , ZFS_FAMILY_EFFICIENCY
356 + , NULL
357 + , "ZFS Prefetch Hits"
358 + , "percentage"
359 + , 2040
360 + , update_every
361 + , RRDSET_TYPE_STACKED
362 + );
363 +
364 + rd_phits = rrddim_add(st_phits, "hits", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
365 + rd_pmisses = rrddim_add(st_phits, "misses", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
366 + }
367 + else
368 + rrdset_next(st_phits);
369 +
370 + rrddim_set_by_pointer(st_phits, rd_phits, phit);
371 + rrddim_set_by_pointer(st_phits, rd_pmisses, pmiss);
372 + rrdset_done(st_phits);
373 + }
374 +
375 + // --------------------------------------------------------------------
376 +
377 + {
378 + static RRDSET *st_mhits = NULL;
379 + static RRDDIM *rd_mhits = NULL;
380 + static RRDDIM *rd_mmisses = NULL;
381 +
382 + if (unlikely(!st_mhits)) {
383 + st_mhits = rrdset_create_localhost(
384 + "zfs"
385 + , "mhits"
386 + , NULL
387 + , ZFS_FAMILY_EFFICIENCY
388 + , NULL
389 + , "ZFS Metadata Hits"
390 + , "percentage"
391 + , 2050
392 + , update_every
393 + , RRDSET_TYPE_STACKED
394 + );
395 +
396 + rd_mhits = rrddim_add(st_mhits, "hits", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
397 + rd_mmisses = rrddim_add(st_mhits, "misses", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
398 + }
399 + else
400 + rrdset_next(st_mhits);
401 +
402 + rrddim_set_by_pointer(st_mhits, rd_mhits, mhit);
403 + rrddim_set_by_pointer(st_mhits, rd_mmisses, mmiss);
404 + rrdset_done(st_mhits);
405 + }
406 +
407 + // --------------------------------------------------------------------
408 +
409 + if(likely(l2exist)) {
410 + static RRDSET *st_l2hits = NULL;
411 + static RRDDIM *rd_l2hits = NULL;
412 + static RRDDIM *rd_l2misses = NULL;
413 +
414 + if (unlikely(!st_l2hits)) {
415 + st_l2hits = rrdset_create_localhost(
416 + "zfs"
417 + , "l2hits"
418 + , NULL
419 + , ZFS_FAMILY_EFFICIENCY
420 + , NULL
421 + , "ZFS L2 Hits"
422 + , "percentage"
423 + , 2060
424 + , update_every
425 + , RRDSET_TYPE_STACKED
426 + );
427 +
428 + rd_l2hits = rrddim_add(st_l2hits, "hits", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
429 + rd_l2misses = rrddim_add(st_l2hits, "misses", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
430 + }
431 + else
432 + rrdset_next(st_l2hits);
433 +
434 + rrddim_set_by_pointer(st_l2hits, rd_l2hits, l2hit);
435 + rrddim_set_by_pointer(st_l2hits, rd_l2misses, l2miss);
436 + rrdset_done(st_l2hits);
437 + }
438 +
439 + // --------------------------------------------------------------------
440 +
441 + {
442 + static RRDSET *st_list_hits = NULL;
443 + static RRDDIM *rd_mfu = NULL;
444 + static RRDDIM *rd_mru = NULL;
445 + static RRDDIM *rd_mfug = NULL;
446 + static RRDDIM *rd_mrug = NULL;
447 +
448 + if (unlikely(!st_list_hits)) {
449 + st_list_hits = rrdset_create_localhost(
450 + "zfs"
451 + , "list_hits"
452 + , NULL
453 + , ZFS_FAMILY_EFFICIENCY
454 + , NULL
455 + , "ZFS List Hits"
456 + , "hits/s"
457 + , 2100
458 + , update_every
459 + , RRDSET_TYPE_AREA
460 + );
461 +
462 + rd_mfu = rrddim_add(st_list_hits, "mfu", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
463 + rd_mfug = rrddim_add(st_list_hits, "mfug", "mfu ghost", 1, 1, RRD_ALGORITHM_INCREMENTAL);
464 + rd_mru = rrddim_add(st_list_hits, "mru", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
465 + rd_mrug = rrddim_add(st_list_hits, "mrug", "mru ghost", 1, 1, RRD_ALGORITHM_INCREMENTAL);
466 + }
467 + else
468 + rrdset_next(st_list_hits);
469 +
470 + rrddim_set_by_pointer(st_list_hits, rd_mfu, arcstats.mfu_hits);
471 + rrddim_set_by_pointer(st_list_hits, rd_mru, arcstats.mru_hits);
472 + rrddim_set_by_pointer(st_list_hits, rd_mfug, arcstats.mfu_ghost_hits);
473 + rrddim_set_by_pointer(st_list_hits, rd_mrug, arcstats.mru_ghost_hits);
474 + rrdset_done(st_list_hits);
475 + }
476 +}
477 +
478 +static void generate_charts_arc_summary(int update_every) {
479 + unsigned long long arc_accesses_total = arcstats.hits + arcstats.misses;
480 + unsigned long long real_hits = arcstats.mfu_hits + arcstats.mru_hits;
481 + unsigned long long real_misses = arc_accesses_total - real_hits;
482 +
483 + //unsigned long long anon_hits = arcstats.hits - (arcstats.mfu_hits + arcstats.mru_hits + arcstats.mfu_ghost_hits + arcstats.mru_ghost_hits);
484 +
485 + unsigned long long arc_size = arcstats.size;
486 + unsigned long long mru_size = arcstats.p;
487 + //unsigned long long target_min_size = arcstats.c_min;
488 + //unsigned long long target_max_size = arcstats.c_max;
489 + unsigned long long target_size = arcstats.c;
490 + //unsigned long long target_size_ratio = (target_max_size / target_min_size);
491 +
492 + unsigned long long mfu_size;
493 + if(arc_size > target_size)
494 + mfu_size = arc_size - mru_size;
495 + else
496 + mfu_size = target_size - mru_size;
497 +
498 + // --------------------------------------------------------------------
499 +
500 + {
501 + static RRDSET *st_arc_size_breakdown = NULL;
502 + static RRDDIM *rd_most_recent = NULL;
503 + static RRDDIM *rd_most_frequent = NULL;
504 +
505 + if (unlikely(!st_arc_size_breakdown)) {
506 + st_arc_size_breakdown = rrdset_create_localhost(
507 + "zfs"
508 + , "arc_size_breakdown"
509 + , NULL
510 + , ZFS_FAMILY_EFFICIENCY
511 + , NULL
512 + , "ZFS ARC Size Breakdown"
513 + , "percentage"
514 + , 2020
515 + , update_every
516 + , RRDSET_TYPE_STACKED
517 + );
518 +
519 + rd_most_recent = rrddim_add(st_arc_size_breakdown, "recent", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_ROW_TOTAL);
520 + rd_most_frequent = rrddim_add(st_arc_size_breakdown, "frequent", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_ROW_TOTAL);
521 + }
522 + else
523 + rrdset_next(st_arc_size_breakdown);
524 +
525 + rrddim_set_by_pointer(st_arc_size_breakdown, rd_most_recent, mru_size);
526 + rrddim_set_by_pointer(st_arc_size_breakdown, rd_most_frequent, mfu_size);
527 + rrdset_done(st_arc_size_breakdown);
528 + }
529 +
530 + // --------------------------------------------------------------------
531 +
532 + {
533 + static RRDSET *st_memory = NULL;
534 + static RRDDIM *rd_direct = NULL;
535 + static RRDDIM *rd_throttled = NULL;
536 + static RRDDIM *rd_indirect = NULL;
537 +
538 + if (unlikely(!st_memory)) {
539 + st_memory = rrdset_create_localhost(
540 + "zfs"
541 + , "memory_ops"
542 + , NULL
543 + , ZFS_FAMILY_OPERATIONS
544 + , NULL
545 + , "ZFS Memory Operations"
546 + , "operations/s"
547 + , 2023
548 + , update_every
549 + , RRDSET_TYPE_LINE
550 + );
551 +
552 + rd_direct = rrddim_add(st_memory, "direct", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
553 + rd_throttled = rrddim_add(st_memory, "throttled", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
554 + rd_indirect = rrddim_add(st_memory, "indirect", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
555 + }
556 + else
557 + rrdset_next(st_memory);
558 +
559 + rrddim_set_by_pointer(st_memory, rd_direct, arcstats.memory_direct_count);
560 + rrddim_set_by_pointer(st_memory, rd_throttled, arcstats.memory_throttle_count);
561 + rrddim_set_by_pointer(st_memory, rd_indirect, arcstats.memory_indirect_count);
562 + rrdset_done(st_memory);
563 + }
564 +
565 + // --------------------------------------------------------------------
566 +
567 + {
568 + static RRDSET *st_important_ops = NULL;
569 + static RRDDIM *rd_deleted = NULL;
570 + static RRDDIM *rd_mutex_misses = NULL;
571 + static RRDDIM *rd_evict_skips = NULL;
572 + static RRDDIM *rd_hash_collisions = NULL;
573 +
574 + if (unlikely(!st_important_ops)) {
575 + st_important_ops = rrdset_create_localhost(
576 + "zfs"
577 + , "important_ops"
578 + , NULL
579 + , ZFS_FAMILY_OPERATIONS
580 + , NULL
581 + , "ZFS Important Operations"
582 + , "operations/s"
583 + , 2022
584 + , update_every
585 + , RRDSET_TYPE_LINE
586 + );
587 +
588 + rd_evict_skips = rrddim_add(st_important_ops, "eskip", "evict skip", 1, 1, RRD_ALGORITHM_INCREMENTAL);
589 + rd_deleted = rrddim_add(st_important_ops, "deleted", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
590 + rd_mutex_misses = rrddim_add(st_important_ops, "mtxmis", "mutex miss", 1, 1, RRD_ALGORITHM_INCREMENTAL);
591 + rd_hash_collisions = rrddim_add(st_important_ops, "hash_collisions", "hash collisions", 1, 1, RRD_ALGORITHM_INCREMENTAL);
592 + }
593 + else
594 + rrdset_next(st_important_ops);
595 +
596 + rrddim_set_by_pointer(st_important_ops, rd_deleted, arcstats.deleted);
597 + rrddim_set_by_pointer(st_important_ops, rd_evict_skips, arcstats.evict_skip);
598 + rrddim_set_by_pointer(st_important_ops, rd_mutex_misses, arcstats.mutex_miss);
599 + rrddim_set_by_pointer(st_important_ops, rd_hash_collisions, arcstats.hash_collisions);
600 + rrdset_done(st_important_ops);
601 + }
602 +
603 + // --------------------------------------------------------------------
604 +
605 + {
606 + static RRDSET *st_actual_hits = NULL;
607 + static RRDDIM *rd_actual_hits = NULL;
608 + static RRDDIM *rd_actual_misses = NULL;
609 +
610 + if (unlikely(!st_actual_hits)) {
611 + st_actual_hits = rrdset_create_localhost(
612 + "zfs"
613 + , "actual_hits"
614 + , NULL
615 + , ZFS_FAMILY_EFFICIENCY
616 + , NULL
617 + , "ZFS Actual Cache Hits"
618 + , "percentage"
619 + , 2019
620 + , update_every
621 + , RRDSET_TYPE_STACKED
622 + );
623 +
624 + rd_actual_hits = rrddim_add(st_actual_hits, "hits", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
625 + rd_actual_misses = rrddim_add(st_actual_hits, "misses", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
626 + }
627 + else
628 + rrdset_next(st_actual_hits);
629 +
630 + rrddim_set_by_pointer(st_actual_hits, rd_actual_hits, real_hits);
631 + rrddim_set_by_pointer(st_actual_hits, rd_actual_misses, real_misses);
632 + rrdset_done(st_actual_hits);
633 + }
634 +
635 + // --------------------------------------------------------------------
636 +
637 + {
638 + static RRDSET *st_demand_data_hits = NULL;
639 + static RRDDIM *rd_demand_data_hits = NULL;
640 + static RRDDIM *rd_demand_data_misses = NULL;
641 +
642 + if (unlikely(!st_demand_data_hits)) {
643 + st_demand_data_hits = rrdset_create_localhost(
644 + "zfs"
645 + , "demand_data_hits"
646 + , NULL
647 + , ZFS_FAMILY_EFFICIENCY
648 + , NULL
649 + , "ZFS Data Demand Efficiency"
650 + , "percentage"
651 + , 2031
652 + , update_every
653 + , RRDSET_TYPE_STACKED
654 + );
655 +
656 + rd_demand_data_hits = rrddim_add(st_demand_data_hits, "hits", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
657 + rd_demand_data_misses = rrddim_add(st_demand_data_hits, "misses", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
658 + }
659 + else
660 + rrdset_next(st_demand_data_hits);
661 +
662 + rrddim_set_by_pointer(st_demand_data_hits, rd_demand_data_hits, arcstats.demand_data_hits);
663 + rrddim_set_by_pointer(st_demand_data_hits, rd_demand_data_misses, arcstats.demand_data_misses);
664 + rrdset_done(st_demand_data_hits);
665 + }
666 +
667 + // --------------------------------------------------------------------
668 +
669 + {
670 + static RRDSET *st_prefetch_data_hits = NULL;
671 + static RRDDIM *rd_prefetch_data_hits = NULL;
672 + static RRDDIM *rd_prefetch_data_misses = NULL;
673 +
674 + if (unlikely(!st_prefetch_data_hits)) {
675 + st_prefetch_data_hits = rrdset_create_localhost(
676 + "zfs"
677 + , "prefetch_data_hits"
678 + , NULL
679 + , ZFS_FAMILY_EFFICIENCY
680 + , NULL
681 + , "ZFS Data Prefetch Efficiency"
682 + , "percentage"
683 + , 2032
684 + , update_every
685 + , RRDSET_TYPE_STACKED
686 + );
687 +
688 + rd_prefetch_data_hits = rrddim_add(st_prefetch_data_hits, "hits", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
689 + rd_prefetch_data_misses = rrddim_add(st_prefetch_data_hits, "misses", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
690 + }
691 + else
692 + rrdset_next(st_prefetch_data_hits);
693 +
694 + rrddim_set_by_pointer(st_prefetch_data_hits, rd_prefetch_data_hits, arcstats.prefetch_data_hits);
695 + rrddim_set_by_pointer(st_prefetch_data_hits, rd_prefetch_data_misses, arcstats.prefetch_data_misses);
696 + rrdset_done(st_prefetch_data_hits);
697 + }
698 +
699 + // --------------------------------------------------------------------
700 +
701 + {
702 + static RRDSET *st_hash_elements = NULL;
703 + static RRDDIM *rd_hash_elements_current = NULL;
704 + static RRDDIM *rd_hash_elements_max = NULL;
705 +
706 + if (unlikely(!st_hash_elements)) {
707 + st_hash_elements = rrdset_create_localhost(
708 + "zfs"
709 + , "hash_elements"
710 + , NULL
711 + , ZFS_FAMILY_HASH
712 + , NULL
713 + , "ZFS ARC Hash Elements"
714 + , "elements"
715 + , 2300
716 + , update_every
717 + , RRDSET_TYPE_LINE
718 + );
719 +
720 + rd_hash_elements_current = rrddim_add(st_hash_elements, "current", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
721 + rd_hash_elements_max = rrddim_add(st_hash_elements, "max", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
722 + }
723 + else
724 + rrdset_next(st_hash_elements);
725 +
726 + rrddim_set_by_pointer(st_hash_elements, rd_hash_elements_current, arcstats.hash_elements);
727 + rrddim_set_by_pointer(st_hash_elements, rd_hash_elements_max, arcstats.hash_elements_max);
728 + rrdset_done(st_hash_elements);
729 + }
730 +
731 + // --------------------------------------------------------------------
732 +
733 + {
734 + static RRDSET *st_hash_chains = NULL;
735 + static RRDDIM *rd_hash_chains_current = NULL;
736 + static RRDDIM *rd_hash_chains_max = NULL;
737 +
738 + if (unlikely(!st_hash_chains)) {
739 + st_hash_chains = rrdset_create_localhost(
740 + "zfs"
741 + , "hash_chains"
742 + , NULL
743 + , ZFS_FAMILY_HASH
744 + , NULL
745 + , "ZFS ARC Hash Chains"
746 + , "chains"
747 + , 2310
748 + , update_every
749 + , RRDSET_TYPE_LINE
750 + );
751 +
752 + rd_hash_chains_current = rrddim_add(st_hash_chains, "current", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
753 + rd_hash_chains_max = rrddim_add(st_hash_chains, "max", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
754 + }
755 + else
756 + rrdset_next(st_hash_chains);
757 +
758 + rrddim_set_by_pointer(st_hash_chains, rd_hash_chains_current, arcstats.hash_chains);
759 + rrddim_set_by_pointer(st_hash_chains, rd_hash_chains_max, arcstats.hash_chain_max);
760 + rrdset_done(st_hash_chains);
761 + }
762 +
763 + // --------------------------------------------------------------------
764 +
765 +}
766 +
767 +int do_proc_spl_kstat_zfs_arcstats(int update_every, usec_t dt) {
768 + (void)dt;
769 +
770 + static procfile *ff = NULL;
771 + static ARL_BASE *arl_base = NULL;
772 +
773 + if(unlikely(!arl_base)) {
774 + arl_base = arl_create("arcstats", NULL, 60);
775 +
776 + arl_expect(arl_base, "hits", &arcstats.hits);
777 + arl_expect(arl_base, "misses", &arcstats.misses);
778 + arl_expect(arl_base, "demand_data_hits", &arcstats.demand_data_hits);
779 + arl_expect(arl_base, "demand_data_misses", &arcstats.demand_data_misses);
780 + arl_expect(arl_base, "demand_metadata_hits", &arcstats.demand_metadata_hits);
781 + arl_expect(arl_base, "demand_metadata_misses", &arcstats.demand_metadata_misses);
782 + arl_expect(arl_base, "prefetch_data_hits", &arcstats.prefetch_data_hits);
783 + arl_expect(arl_base, "prefetch_data_misses", &arcstats.prefetch_data_misses);
784 + arl_expect(arl_base, "prefetch_metadata_hits", &arcstats.prefetch_metadata_hits);
785 + arl_expect(arl_base, "prefetch_metadata_misses", &arcstats.prefetch_metadata_misses);
786 + arl_expect(arl_base, "mru_hits", &arcstats.mru_hits);
787 + arl_expect(arl_base, "mru_ghost_hits", &arcstats.mru_ghost_hits);
788 + arl_expect(arl_base, "mfu_hits", &arcstats.mfu_hits);
789 + arl_expect(arl_base, "mfu_ghost_hits", &arcstats.mfu_ghost_hits);
790 + arl_expect(arl_base, "deleted", &arcstats.deleted);
791 + arl_expect(arl_base, "mutex_miss", &arcstats.mutex_miss);
792 + arl_expect(arl_base, "evict_skip", &arcstats.evict_skip);
793 + arl_expect(arl_base, "evict_not_enough", &arcstats.evict_not_enough);
794 + arl_expect(arl_base, "evict_l2_cached", &arcstats.evict_l2_cached);
795 + arl_expect(arl_base, "evict_l2_eligible", &arcstats.evict_l2_eligible);
796 + arl_expect(arl_base, "evict_l2_ineligible", &arcstats.evict_l2_ineligible);
797 + arl_expect(arl_base, "evict_l2_skip", &arcstats.evict_l2_skip);
798 + arl_expect(arl_base, "hash_elements", &arcstats.hash_elements);
799 + arl_expect(arl_base, "hash_elements_max", &arcstats.hash_elements_max);
800 + arl_expect(arl_base, "hash_collisions", &arcstats.hash_collisions);
801 + arl_expect(arl_base, "hash_chains", &arcstats.hash_chains);
802 + arl_expect(arl_base, "hash_chain_max", &arcstats.hash_chain_max);
803 + arl_expect(arl_base, "p", &arcstats.p);
804 + arl_expect(arl_base, "c", &arcstats.c);
805 + arl_expect(arl_base, "c_min", &arcstats.c_min);
806 + arl_expect(arl_base, "c_max", &arcstats.c_max);
807 + arl_expect(arl_base, "size", &arcstats.size);
808 + arl_expect(arl_base, "hdr_size", &arcstats.hdr_size);
809 + arl_expect(arl_base, "data_size", &arcstats.data_size);
810 + arl_expect(arl_base, "metadata_size", &arcstats.metadata_size);
811 + arl_expect(arl_base, "other_size", &arcstats.other_size);
812 + arl_expect(arl_base, "anon_size", &arcstats.anon_size);
813 + arl_expect(arl_base, "anon_evictable_data", &arcstats.anon_evictable_data);
814 + arl_expect(arl_base, "anon_evictable_metadata", &arcstats.anon_evictable_metadata);
815 + arl_expect(arl_base, "mru_size", &arcstats.mru_size);
816 + arl_expect(arl_base, "mru_evictable_data", &arcstats.mru_evictable_data);
817 + arl_expect(arl_base, "mru_evictable_metadata", &arcstats.mru_evictable_metadata);
818 + arl_expect(arl_base, "mru_ghost_size", &arcstats.mru_ghost_size);
819 + arl_expect(arl_base, "mru_ghost_evictable_data", &arcstats.mru_ghost_evictable_data);
820 + arl_expect(arl_base, "mru_ghost_evictable_metadata", &arcstats.mru_ghost_evictable_metadata);
821 + arl_expect(arl_base, "mfu_size", &arcstats.mfu_size);
822 + arl_expect(arl_base, "mfu_evictable_data", &arcstats.mfu_evictable_data);
823 + arl_expect(arl_base, "mfu_evictable_metadata", &arcstats.mfu_evictable_metadata);
824 + arl_expect(arl_base, "mfu_ghost_size", &arcstats.mfu_ghost_size);
825 + arl_expect(arl_base, "mfu_ghost_evictable_data", &arcstats.mfu_ghost_evictable_data);
826 + arl_expect(arl_base, "mfu_ghost_evictable_metadata", &arcstats.mfu_ghost_evictable_metadata);
827 + arl_expect(arl_base, "l2_hits", &arcstats.l2_hits);
828 + arl_expect(arl_base, "l2_misses", &arcstats.l2_misses);
829 + arl_expect(arl_base, "l2_feeds", &arcstats.l2_feeds);
830 + arl_expect(arl_base, "l2_rw_clash", &arcstats.l2_rw_clash);
831 + arl_expect(arl_base, "l2_read_bytes", &arcstats.l2_read_bytes);
832 + arl_expect(arl_base, "l2_write_bytes", &arcstats.l2_write_bytes);
833 + arl_expect(arl_base, "l2_writes_sent", &arcstats.l2_writes_sent);
834 + arl_expect(arl_base, "l2_writes_done", &arcstats.l2_writes_done);
835 + arl_expect(arl_base, "l2_writes_error", &arcstats.l2_writes_error);
836 + arl_expect(arl_base, "l2_writes_lock_retry", &arcstats.l2_writes_lock_retry);
837 + arl_expect(arl_base, "l2_evict_lock_retry", &arcstats.l2_evict_lock_retry);
838 + arl_expect(arl_base, "l2_evict_reading", &arcstats.l2_evict_reading);
839 + arl_expect(arl_base, "l2_evict_l1cached", &arcstats.l2_evict_l1cached);
840 + arl_expect(arl_base, "l2_free_on_write", &arcstats.l2_free_on_write);
841 + arl_expect(arl_base, "l2_cdata_free_on_write", &arcstats.l2_cdata_free_on_write);
842 + arl_expect(arl_base, "l2_abort_lowmem", &arcstats.l2_abort_lowmem);
843 + arl_expect(arl_base, "l2_cksum_bad", &arcstats.l2_cksum_bad);
844 + arl_expect(arl_base, "l2_io_error", &arcstats.l2_io_error);
845 + arl_expect(arl_base, "l2_size", &arcstats.l2_size);
846 + arl_expect(arl_base, "l2_asize", &arcstats.l2_asize);
847 + arl_expect(arl_base, "l2_hdr_size", &arcstats.l2_hdr_size);
848 + arl_expect(arl_base, "l2_compress_successes", &arcstats.l2_compress_successes);
849 + arl_expect(arl_base, "l2_compress_zeros", &arcstats.l2_compress_zeros);
850 + arl_expect(arl_base, "l2_compress_failures", &arcstats.l2_compress_failures);
851 + arl_expect(arl_base, "memory_throttle_count", &arcstats.memory_throttle_count);
852 + arl_expect(arl_base, "duplicate_buffers", &arcstats.duplicate_buffers);
853 + arl_expect(arl_base, "duplicate_buffers_size", &arcstats.duplicate_buffers_size);
854 + arl_expect(arl_base, "duplicate_reads", &arcstats.duplicate_reads);
855 + arl_expect(arl_base, "memory_direct_count", &arcstats.memory_direct_count);
856 + arl_expect(arl_base, "memory_indirect_count", &arcstats.memory_indirect_count);
857 + arl_expect(arl_base, "arc_no_grow", &arcstats.arc_no_grow);
858 + arl_expect(arl_base, "arc_tempreserve", &arcstats.arc_tempreserve);
859 + arl_expect(arl_base, "arc_loaned_bytes", &arcstats.arc_loaned_bytes);
860 + arl_expect(arl_base, "arc_prune", &arcstats.arc_prune);
861 + arl_expect(arl_base, "arc_meta_used", &arcstats.arc_meta_used);
862 + arl_expect(arl_base, "arc_meta_limit", &arcstats.arc_meta_limit);
863 + arl_expect(arl_base, "arc_meta_max", &arcstats.arc_meta_max);
864 + arl_expect(arl_base, "arc_meta_min", &arcstats.arc_meta_min);
865 + arl_expect(arl_base, "arc_need_free", &arcstats.arc_need_free);
866 + arl_expect(arl_base, "arc_sys_free", &arcstats.arc_sys_free);
867 + }
868 +
869 + if(unlikely(!ff)) {
870 + char filename[FILENAME_MAX + 1];
871 + snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, ZFS_PROC_ARCSTATS);
872 + ff = procfile_open(config_get("plugin:proc:" ZFS_PROC_ARCSTATS, "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT);
873 + if(unlikely(!ff))
874 + return 1;
875 + }
876 +
877 + ff = procfile_readall(ff);
878 + if(unlikely(!ff))
879 + return 0; // we return 0, so that we will retry to open it next time
880 +
881 + size_t lines = procfile_lines(ff), l;
882 +
883 + arl_begin(arl_base);
884 +
885 + for(l = 0; l < lines ;l++) {
886 + size_t words = procfile_linewords(ff, l);
887 + if(unlikely(words < 3)) {
888 + if(unlikely(words)) error("Cannot read " ZFS_PROC_ARCSTATS " line %zu. Expected 3 params, read %zu.", l, words);
889 + continue;
890 + }
891 +
892 + const char *key = procfile_lineword(ff, l, 0);
893 + const char *value = procfile_lineword(ff, l, 2);
894 +
895 + if(unlikely(l2exist == -1)) {
896 + if(key[0] == 'l' && key[1] == '2' && key[2] == '_')
897 + l2exist = 1;
898 + }
899 +
900 + if(unlikely(arl_check(arl_base, key, value))) break;
901 + }
902 +
903 + if(unlikely(l2exist == -1))
904 + l2exist = 0;
905 +
906 + generate_charts_arcstats(update_every);
907 + generate_charts_arc_summary(update_every);
908 +
909 + return 0;
910 +}
web/dashboard_info.js
+6
@@ -103,6 +103,12 @@ netdataDashboard.menu = {
103 info: 'Performance metrics of the NFS operations of this system, acting as an NFS client.'
104 },
105
106 + 'zfs': {
107 + title: 'ZFS filesystem',
108 + icon: '<i class="fa fa-folder-open" aria-hidden="true"></i>',
109 + info: 'Performance metrics of the ZFS filesystem. The following charts visualize all metrics reported by <a href="https://github.com/zfsonlinux/zfs/blob/master/cmd/arcstat/arcstat.py" target="_blank">arcstat.py</a> and <a href="https://github.com/zfsonlinux/zfs/blob/master/cmd/arc_summary/arc_summary.py" target="_blank">arc_summary.py</a>.'
110 + },
111 +
112 'apps': {
113 title: 'Applications',
114 icon: '<i class="fa fa-heartbeat" aria-hidden="true"></i>',
web/index.html
+2 -2
@@ -2895,7 +2895,7 @@
2895 });
2896
2897 NETDATA.requiredJs.push({
2898 - url: NETDATA.serverDefault + 'dashboard_info.js?v20170308-1',
2898 + url: NETDATA.serverDefault + 'dashboard_info.js?v20170325-1',
2899 async: false,
2900 isAlreadyLoaded: function() { return false; }
2901 });
@@ -3523,4 +3523,4 @@
3523 </div>
3524 </body>
3525 </html>
3526 -<script type="text/javascript" src="dashboard.js?v20170211-2"></script>
3526 +<script type="text/javascript" src="dashboard.js?v20170325-1"></script>