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>