3 // NEEDED BY: struct vmtotal, struct vmmeter
4 #include <sys/vmmeter.h>
5 // NEEDED BY: struct devstat
6 #include <sys/devicestat.h>
7 // NEEDED BY: struct xswdev
8 #include <vm/vm_param.h>
9 // NEEDED BY: struct semid_kernel, struct shmid_kernel, struct msqid_kernel
15 // NEEDED BY: struct sysctl_netisr_workstream, struct sysctl_netisr_work
16 #include <net/netisr.h>
17 // NEEDED BY: do_disk_io
18 #define RRD_TYPE_DISK "disk"
20 // FreeBSD calculates load averages once every 5 seconds
21 #define MIN_LOADAVG_UPDATE_EVERY 5
23 int do_freebsd_sysctl(int update_every, usec_t dt) {
26 static int do_cpu = -1, do_cpu_cores = -1, do_interrupts = -1, do_context = -1, do_forks = -1, do_processes = -1,
27 do_loadavg = -1, do_all_processes = -1, do_disk_io = -1, do_swap = -1, do_ram = -1, do_swapio = -1,
28 do_pgfaults = -1, do_committed = -1, do_ipc_semaphores = -1, do_ipc_shared_mem = -1, do_ipc_msg_queues = -1,
29 do_dev_intr = -1, do_soft_intr = -1, do_netisr = -1, do_netisr_per_core = -1;
31 if (unlikely(do_cpu == -1)) {
32 do_cpu = config_get_boolean("plugin:freebsd:sysctl", "cpu utilization", 1);
33 do_cpu_cores = config_get_boolean("plugin:freebsd:sysctl", "per cpu core utilization", 1);
34 do_interrupts = config_get_boolean("plugin:freebsd:sysctl", "cpu interrupts", 1);
35 do_dev_intr = config_get_boolean("plugin:freebsd:sysctl", "device interrupts", 1);
36 do_soft_intr = config_get_boolean("plugin:freebsd:sysctl", "software interrupts", 1);
37 do_context = config_get_boolean("plugin:freebsd:sysctl", "context switches", 1);
38 do_forks = config_get_boolean("plugin:freebsd:sysctl", "processes started", 1);
39 do_processes = config_get_boolean("plugin:freebsd:sysctl", "processes running", 1);
40 do_loadavg = config_get_boolean("plugin:freebsd:sysctl", "enable load average", 1);
41 do_all_processes = config_get_boolean("plugin:freebsd:sysctl", "enable total processes", 1);
42 do_disk_io = config_get_boolean("plugin:freebsd:sysctl", "stats for all disks", 1);
43 do_swap = config_get_boolean("plugin:freebsd:sysctl", "system swap", 1);
44 do_ram = config_get_boolean("plugin:freebsd:sysctl", "system ram", 1);
45 do_swapio = config_get_boolean("plugin:freebsd:sysctl", "swap i/o", 1);
46 do_pgfaults = config_get_boolean("plugin:freebsd:sysctl", "memory page faults", 1);
47 do_committed = config_get_boolean("plugin:freebsd:sysctl", "committed memory", 1);
48 do_ipc_semaphores = config_get_boolean("plugin:freebsd:sysctl", "ipc semaphores", 1);
49 do_ipc_shared_mem = config_get_boolean("plugin:freebsd:sysctl", "ipc shared memory", 1);
50 do_ipc_msg_queues = config_get_boolean("plugin:freebsd:sysctl", "ipc message queues", 1);
51 do_netisr = config_get_boolean("plugin:freebsd:sysctl", "netisr", 1);
52 do_netisr_per_core = config_get_boolean("plugin:freebsd:sysctl", "netisr per core", 1);
57 int system_pagesize = getpagesize(); // wouldn't it be better to get value directly from hw.pagesize?
61 // NEEDED BY: do_loadavg
62 static usec_t last_loadavg_usec = 0;
63 struct loadavg sysload;
65 // NEEDED BY: do_cpu, do_cpu_cores
66 long cp_time[CPUSTATES];
68 // NEEDED BY: du_cpu_cores, do_netisr, do_netisr_per_core
71 // NEEDED BY: do_cpu_cores
72 static long *pcpu_cp_time = NULL;
73 char cpuid[8]; // no more than 4 digits expected
75 // NEEDED BY: do_all_processes, do_processes
76 struct vmtotal vmtotal_data;
78 // NEEDED BY: do_context, do_forks
81 // NEEDED BY: do_interrupts
83 unsigned long nintr = 0;
84 static unsigned long *intrcnt = NULL;
85 unsigned long long totalintr = 0;
87 // NEEDED BY: do_disk_io
88 #define BINTIME_SCALE 5.42101086242752217003726400434970855712890625e-17 // this is 1000/2^64
90 static void *devstat_data = NULL;
91 struct devstat *dstat;
93 collected_number duration_read_ms;
94 collected_number duration_write_ms;
95 collected_number busy_time_ms;
98 collected_number bytes_read;
99 collected_number bytes_write;
100 collected_number operations_read;
101 collected_number operations_write;
102 collected_number duration_read_ms;
103 collected_number duration_write_ms;
104 collected_number busy_time_ms;
107 // NEEDED BY: do_swap
108 size_t mibsize, size;
109 int mib[3]; // CTL_MAXNAME = 24 maximum mib components (sysctl.h)
112 collected_number bytes_used;
113 collected_number bytes_total;
114 } total_xsw = {0, 0};
116 // NEEDED BY: do_swapio, do_ram
117 struct vmmeter vmmeter_data;
120 int vfs_bufspace_count;
122 // NEEDED BY: do_ipc_semaphores
125 collected_number sets;
126 collected_number semaphores;
127 } ipc_sem = {0, 0, 0};
128 static struct semid_kernel *ipc_sem_data = NULL;
130 // NEEDED BY: do_ipc_shared_mem
133 collected_number segs;
134 collected_number segsize;
135 } ipc_shm = {0, 0, 0};
136 static struct shmid_kernel *ipc_shm_data = NULL;
138 // NEEDED BY: do_ipc_msg_queues
141 collected_number queues;
142 collected_number messages;
143 collected_number usedsize;
144 collected_number allocsize;
145 } ipc_msq = {0, 0, 0, 0, 0};
146 static struct msqid_kernel *ipc_msq_data = NULL;
148 // NEEDED BY: do_netisr, do_netisr_per_core
149 size_t netisr_workstream_size;
150 size_t netisr_work_size;
151 unsigned long num_netisr_workstreams = 0, num_netisr_works = 0;
152 static struct sysctl_netisr_workstream *netisr_workstream = NULL;
153 static struct sysctl_netisr_work *netisr_work = NULL;
154 static struct netisr_stats {
155 collected_number dispatched;
156 collected_number hybrid_dispatched;
157 collected_number qdrops;
158 collected_number queued;
159 } *netisr_stats = NULL;
160 char netstat_cpuid[21]; // no more than 4 digits expected
162 // --------------------------------------------------------------------
164 if (last_loadavg_usec <= dt) {
165 if (likely(do_loadavg)) {
166 if (unlikely(GETSYSCTL("vm.loadavg", sysload))) {
168 error("DISABLED: system.load");
171 st = rrdset_find_bytype("system", "load");
173 st = rrdset_create("system", "load", NULL, "load", NULL, "System Load Average", "load", 100, (update_every < MIN_LOADAVG_UPDATE_EVERY) ? MIN_LOADAVG_UPDATE_EVERY : update_every, RRDSET_TYPE_LINE);
174 rrddim_add(st, "load1", NULL, 1, 1000, RRDDIM_ABSOLUTE);
175 rrddim_add(st, "load5", NULL, 1, 1000, RRDDIM_ABSOLUTE);
176 rrddim_add(st, "load15", NULL, 1, 1000, RRDDIM_ABSOLUTE);
178 else rrdset_next(st);
180 rrddim_set(st, "load1", (collected_number) ((double)sysload.ldavg[0] / sysload.fscale * 1000));
181 rrddim_set(st, "load5", (collected_number) ((double)sysload.ldavg[1] / sysload.fscale * 1000));
182 rrddim_set(st, "load15", (collected_number) ((double)sysload.ldavg[2] / sysload.fscale * 1000));
187 last_loadavg_usec = st->update_every * USEC_PER_SEC;
189 else last_loadavg_usec -= dt;
191 // --------------------------------------------------------------------
193 if (likely(do_all_processes | do_processes | do_committed)) {
194 if (unlikely(GETSYSCTL("vm.vmtotal", vmtotal_data))) {
195 do_all_processes = 0;
196 error("DISABLED: system.active_processes");
198 error("DISABLED: system.processes");
200 error("DISABLED: mem.committed");
202 if (likely(do_all_processes)) {
204 st = rrdset_find_bytype("system", "active_processes");
206 st = rrdset_create("system", "active_processes", NULL, "processes", NULL, "System Active Processes", "processes", 750, update_every, RRDSET_TYPE_LINE);
207 rrddim_add(st, "active", NULL, 1, 1, RRDDIM_ABSOLUTE);
209 else rrdset_next(st);
211 rrddim_set(st, "active", (vmtotal_data.t_rq + vmtotal_data.t_dw + vmtotal_data.t_pw + vmtotal_data.t_sl + vmtotal_data.t_sw));
215 // --------------------------------------------------------------------
217 if (likely(do_processes)) {
219 st = rrdset_find_bytype("system", "processes");
221 st = rrdset_create("system", "processes", NULL, "processes", NULL, "System Processes", "processes", 600, update_every, RRDSET_TYPE_LINE);
223 rrddim_add(st, "running", NULL, 1, 1, RRDDIM_ABSOLUTE);
224 rrddim_add(st, "blocked", NULL, -1, 1, RRDDIM_ABSOLUTE);
226 else rrdset_next(st);
228 rrddim_set(st, "running", vmtotal_data.t_rq);
229 rrddim_set(st, "blocked", (vmtotal_data.t_dw + vmtotal_data.t_pw));
233 // --------------------------------------------------------------------
235 if (likely(do_committed)) {
236 st = rrdset_find("mem.committed");
238 st = rrdset_create("mem", "committed", NULL, "system", NULL, "Committed (Allocated) Memory", "MB", 5000, update_every, RRDSET_TYPE_AREA);
241 rrddim_add(st, "Committed_AS", NULL, system_pagesize, 1024, RRDDIM_ABSOLUTE);
243 else rrdset_next(st);
245 rrddim_set(st, "Committed_AS", vmtotal_data.t_rm);
251 // --------------------------------------------------------------------
253 if (likely(do_cpu)) {
254 if (unlikely(CPUSTATES != 5)) {
255 error("FREEBSD: There are %d CPU states (5 was expected)", CPUSTATES);
257 error("DISABLED: system.cpu");
259 if (unlikely(GETSYSCTL("kern.cp_time", cp_time))) {
261 error("DISABLED: system.cpu");
264 st = rrdset_find_bytype("system", "cpu");
266 st = rrdset_create("system", "cpu", NULL, "cpu", "system.cpu", "Total CPU utilization", "percentage", 100, update_every, RRDSET_TYPE_STACKED);
268 rrddim_add(st, "user", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
269 rrddim_add(st, "nice", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
270 rrddim_add(st, "system", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
271 rrddim_add(st, "interrupt", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
272 rrddim_add(st, "idle", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
273 rrddim_hide(st, "idle");
275 else rrdset_next(st);
277 rrddim_set(st, "user", cp_time[0]);
278 rrddim_set(st, "nice", cp_time[1]);
279 rrddim_set(st, "system", cp_time[2]);
280 rrddim_set(st, "interrupt", cp_time[3]);
281 rrddim_set(st, "idle", cp_time[4]);
287 // --------------------------------------------------------------------
289 if (likely(do_cpu_cores)) {
290 if (unlikely(CPUSTATES != 5)) {
291 error("FREEBSD: There are %d CPU states (5 was expected)", CPUSTATES);
293 error("DISABLED: cpu.cpuXX");
295 if (unlikely(GETSYSCTL("kern.smp.cpus", ncpus))) {
297 error("DISABLED: cpu.cpuXX");
299 pcpu_cp_time = reallocz(pcpu_cp_time, sizeof(cp_time) * ncpus);
301 for (i = 0; i < ncpus; i++) {
302 if (unlikely(getsysctl("kern.cp_times", pcpu_cp_time, sizeof(cp_time) * ncpus))) {
304 error("DISABLED: cpu.cpuXX");
307 if (unlikely(ncpus > 9999)) {
308 error("FREEBSD: There are more than 4 digits in cpu cores number");
310 error("DISABLED: cpu.cpuXX");
313 snprintfz(cpuid, 8, "cpu%d", i);
315 st = rrdset_find_bytype("cpu", cpuid);
317 st = rrdset_create("cpu", cpuid, NULL, "utilization", "cpu.cpu", "Core utilization", "percentage", 1000, update_every, RRDSET_TYPE_STACKED);
319 rrddim_add(st, "user", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
320 rrddim_add(st, "nice", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
321 rrddim_add(st, "system", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
322 rrddim_add(st, "interrupt", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
323 rrddim_add(st, "idle", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
324 rrddim_hide(st, "idle");
326 else rrdset_next(st);
328 rrddim_set(st, "user", pcpu_cp_time[i * 5 + 0]);
329 rrddim_set(st, "nice", pcpu_cp_time[i * 5 + 1]);
330 rrddim_set(st, "system", pcpu_cp_time[i * 5 + 2]);
331 rrddim_set(st, "interrupt", pcpu_cp_time[i * 5 + 3]);
332 rrddim_set(st, "idle", pcpu_cp_time[i * 5 + 4]);
339 // --------------------------------------------------------------------
341 if (likely(do_interrupts)) {
342 if (unlikely(sysctlbyname("hw.intrcnt", NULL, &intrcnt_size, NULL, 0) == -1)) {
343 error("FREEBSD: sysctl(hw.intrcnt...) failed: %s", strerror(errno));
345 error("DISABLED: system.intr");
347 nintr = intrcnt_size / sizeof(u_long);
348 intrcnt = reallocz(intrcnt, nintr * sizeof(u_long));
349 if (unlikely(getsysctl("hw.intrcnt", intrcnt, nintr * sizeof(u_long)))){
351 error("DISABLED: system.intr");
353 for (i = 0; i < nintr; i++)
354 totalintr += intrcnt[i];
356 st = rrdset_find_bytype("system", "intr");
358 st = rrdset_create("system", "intr", NULL, "interrupts", NULL, "Total Hardware Interrupts", "interrupts/s", 900, update_every, RRDSET_TYPE_LINE);
361 rrddim_add(st, "interrupts", NULL, 1, 1, RRDDIM_INCREMENTAL);
363 else rrdset_next(st);
365 rrddim_set(st, "interrupts", totalintr);
371 // --------------------------------------------------------------------
373 if (likely(do_dev_intr)) {
374 if (unlikely(GETSYSCTL("vm.stats.sys.v_intr", u_int_data))) {
376 error("DISABLED: system.dev_intr");
379 st = rrdset_find_bytype("system", "dev_intr");
381 st = rrdset_create("system", "dev_intr", NULL, "interrupts", NULL, "Device Interrupts", "interrupts/s", 1000, update_every, RRDSET_TYPE_LINE);
383 rrddim_add(st, "interrupts", NULL, 1, 1, RRDDIM_INCREMENTAL);
385 else rrdset_next(st);
387 rrddim_set(st, "interrupts", u_int_data);
392 // --------------------------------------------------------------------
394 if (likely(do_soft_intr)) {
395 if (unlikely(GETSYSCTL("vm.stats.sys.v_soft", u_int_data))) {
397 error("DISABLED: system.dev_intr");
400 st = rrdset_find_bytype("system", "soft_intr");
402 st = rrdset_create("system", "soft_intr", NULL, "interrupts", NULL, "Software Interrupts", "interrupts/s", 1100, update_every, RRDSET_TYPE_LINE);
404 rrddim_add(st, "interrupts", NULL, 1, 1, RRDDIM_INCREMENTAL);
406 else rrdset_next(st);
408 rrddim_set(st, "interrupts", u_int_data);
413 // --------------------------------------------------------------------
415 if (likely(do_context)) {
416 if (unlikely(GETSYSCTL("vm.stats.sys.v_swtch", u_int_data))) {
418 error("DISABLED: system.ctxt");
421 st = rrdset_find_bytype("system", "ctxt");
423 st = rrdset_create("system", "ctxt", NULL, "processes", NULL, "CPU Context Switches", "context switches/s", 800, update_every, RRDSET_TYPE_LINE);
425 rrddim_add(st, "switches", NULL, 1, 1, RRDDIM_INCREMENTAL);
427 else rrdset_next(st);
429 rrddim_set(st, "switches", u_int_data);
434 // --------------------------------------------------------------------
436 if (likely(do_forks)) {
437 if (unlikely(GETSYSCTL("vm.stats.vm.v_forks", u_int_data))) {
439 error("DISABLED: system.forks");
442 st = rrdset_find_bytype("system", "forks");
444 st = rrdset_create("system", "forks", NULL, "processes", NULL, "Started Processes", "processes/s", 700, update_every, RRDSET_TYPE_LINE);
447 rrddim_add(st, "started", NULL, 1, 1, RRDDIM_INCREMENTAL);
449 else rrdset_next(st);
451 rrddim_set(st, "started", u_int_data);
456 // --------------------------------------------------------------------
458 if (likely(do_disk_io)) {
459 if (unlikely(GETSYSCTL("kern.devstat.numdevs", numdevs))) {
461 error("DISABLED: disk.io");
463 devstat_data = reallocz(devstat_data, sizeof(long) + sizeof(struct devstat) * numdevs); // there is generation number before devstat structures
464 if (unlikely(getsysctl("kern.devstat.all", devstat_data, sizeof(long) + sizeof(struct devstat) * numdevs))) {
466 error("DISABLED: disk.io");
468 dstat = devstat_data + sizeof(long); // skip generation number
469 collected_number total_disk_reads = 0;
470 collected_number total_disk_writes = 0;
472 for (i = 0; i < numdevs; i++) {
473 if ((dstat[i].device_type == (DEVSTAT_TYPE_IF_SCSI | DEVSTAT_TYPE_DIRECT)) || (dstat[i].device_type == (DEVSTAT_TYPE_IF_IDE | DEVSTAT_TYPE_DIRECT))) {
475 // --------------------------------------------------------------------
477 st = rrdset_find_bytype(RRD_TYPE_DISK, dstat[i].device_name);
479 st = rrdset_create(RRD_TYPE_DISK, dstat[i].device_name, NULL, dstat[i].device_name, "disk.io", "Disk I/O Bandwidth", "kilobytes/s", 2000, update_every, RRDSET_TYPE_AREA);
481 rrddim_add(st, "reads", NULL, 1, 1024, RRDDIM_INCREMENTAL);
482 rrddim_add(st, "writes", NULL, -1, 1024, RRDDIM_INCREMENTAL);
484 else rrdset_next(st);
486 total_disk_reads += dstat[i].bytes[DEVSTAT_READ];
487 total_disk_writes += dstat[i].bytes[DEVSTAT_WRITE];
488 prev_dstat.bytes_read = rrddim_set(st, "reads", dstat[i].bytes[DEVSTAT_READ]);
489 prev_dstat.bytes_write = rrddim_set(st, "writes", dstat[i].bytes[DEVSTAT_WRITE]);
492 // --------------------------------------------------------------------
494 st = rrdset_find_bytype("disk_ops", dstat[i].device_name);
496 st = rrdset_create("disk_ops", dstat[i].device_name, NULL, dstat[i].device_name, "disk.ops", "Disk Completed I/O Operations", "operations/s", 2001, update_every, RRDSET_TYPE_LINE);
499 rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL);
500 rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_INCREMENTAL);
502 else rrdset_next(st);
504 prev_dstat.operations_read = rrddim_set(st, "reads", dstat[i].operations[DEVSTAT_READ]);
505 prev_dstat.operations_write = rrddim_set(st, "writes", dstat[i].operations[DEVSTAT_WRITE]);
508 // --------------------------------------------------------------------
510 st = rrdset_find_bytype("disk_qops", dstat[i].device_name);
512 st = rrdset_create("disk_qops", dstat[i].device_name, NULL, dstat[i].device_name, "disk.qops", "Disk Current I/O Operations", "operations", 2002, update_every, RRDSET_TYPE_LINE);
515 rrddim_add(st, "operations", NULL, 1, 1, RRDDIM_ABSOLUTE);
517 else rrdset_next(st);
519 rrddim_set(st, "operations", dstat[i].start_count - dstat[i].end_count);
522 // --------------------------------------------------------------------
524 st = rrdset_find_bytype("disk_util", dstat[i].device_name);
526 st = rrdset_create("disk_util", dstat[i].device_name, NULL, dstat[i].device_name, "disk.util", "Disk Utilization Time", "% of time working", 2004, update_every, RRDSET_TYPE_AREA);
529 rrddim_add(st, "utilization", NULL, 1, 10, RRDDIM_INCREMENTAL);
531 else rrdset_next(st);
533 cur_dstat.busy_time_ms = dstat[i].busy_time.sec * 1000 + dstat[i].busy_time.frac * BINTIME_SCALE;
534 prev_dstat.busy_time_ms = rrddim_set(st, "utilization", cur_dstat.busy_time_ms);
537 // --------------------------------------------------------------------
539 st = rrdset_find_bytype("disk_iotime", dstat[i].device_name);
541 st = rrdset_create("disk_iotime", dstat[i].device_name, NULL, dstat[i].device_name, "disk.iotime", "Disk Total I/O Time", "milliseconds/s", 2022, update_every, RRDSET_TYPE_LINE);
544 rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL);
545 rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_INCREMENTAL);
547 else rrdset_next(st);
549 cur_dstat.duration_read_ms = dstat[i].duration[DEVSTAT_READ].sec * 1000 + dstat[i].duration[DEVSTAT_READ].frac * BINTIME_SCALE;
550 cur_dstat.duration_write_ms = dstat[i].duration[DEVSTAT_WRITE].sec * 1000 + dstat[i].duration[DEVSTAT_READ].frac * BINTIME_SCALE;
551 prev_dstat.duration_read_ms = rrddim_set(st, "reads", cur_dstat.duration_read_ms);
552 prev_dstat.duration_write_ms = rrddim_set(st, "writes", cur_dstat.duration_write_ms);
555 // --------------------------------------------------------------------
556 // calculate differential charts
557 // only if this is not the first time we run
561 // --------------------------------------------------------------------
563 st = rrdset_find_bytype("disk_await", dstat[i].device_name);
565 st = rrdset_create("disk_await", dstat[i].device_name, NULL, dstat[i].device_name, "disk.await", "Average Completed I/O Operation Time", "ms per operation", 2005, update_every, RRDSET_TYPE_LINE);
568 rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_ABSOLUTE);
569 rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_ABSOLUTE);
571 else rrdset_next(st);
573 rrddim_set(st, "reads", (dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) ?
574 (cur_dstat.duration_read_ms - prev_dstat.duration_read_ms) / (dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) : 0);
575 rrddim_set(st, "writes", (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write) ?
576 (cur_dstat.duration_write_ms - prev_dstat.duration_write_ms) / (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write) : 0);
579 // --------------------------------------------------------------------
581 st = rrdset_find_bytype("disk_avgsz", dstat[i].device_name);
583 st = rrdset_create("disk_avgsz", dstat[i].device_name, NULL, dstat[i].device_name, "disk.avgsz", "Average Completed I/O Operation Bandwidth", "kilobytes per operation", 2006, update_every, RRDSET_TYPE_AREA);
586 rrddim_add(st, "reads", NULL, 1, 1024, RRDDIM_ABSOLUTE);
587 rrddim_add(st, "writes", NULL, -1, 1024, RRDDIM_ABSOLUTE);
589 else rrdset_next(st);
591 rrddim_set(st, "reads", (dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) ?
592 (dstat[i].bytes[DEVSTAT_READ] - prev_dstat.bytes_read) / (dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) : 0);
593 rrddim_set(st, "writes", (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write) ?
594 (dstat[i].bytes[DEVSTAT_WRITE] - prev_dstat.bytes_write) / (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write) : 0);
597 // --------------------------------------------------------------------
599 st = rrdset_find_bytype("disk_svctm", dstat[i].device_name);
601 st = rrdset_create("disk_svctm", dstat[i].device_name, NULL, dstat[i].device_name, "disk.svctm", "Average Service Time", "ms per operation", 2007, update_every, RRDSET_TYPE_LINE);
604 rrddim_add(st, "svctm", NULL, 1, 1, RRDDIM_ABSOLUTE);
606 else rrdset_next(st);
608 rrddim_set(st, "svctm", ((dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) + (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write)) ?
609 (cur_dstat.busy_time_ms - prev_dstat.busy_time_ms) / ((dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) + (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write)) : 0);
614 // --------------------------------------------------------------------
616 st = rrdset_find_bytype("system", "io");
618 st = rrdset_create("system", "io", NULL, "disk", NULL, "Disk I/O", "kilobytes/s", 150, update_every, RRDSET_TYPE_AREA);
619 rrddim_add(st, "in", NULL, 1, 1024, RRDDIM_INCREMENTAL);
620 rrddim_add(st, "out", NULL, -1, 1024, RRDDIM_INCREMENTAL);
622 else rrdset_next(st);
624 rrddim_set(st, "in", total_disk_reads);
625 rrddim_set(st, "out", total_disk_writes);
632 // --------------------------------------------------------------------
635 if (likely(do_swap)) {
636 mibsize = sizeof mib / sizeof mib[0];
637 if (unlikely(sysctlnametomib("vm.swap_info", mib, &mibsize) == -1)) {
638 error("FREEBSD: sysctl(%s...) failed: %s", "vm.swap_info", strerror(errno));
640 error("DISABLED: disk.io");
645 if (unlikely(sysctl(mib, mibsize + 1, &xsw, &size, NULL, 0) == -1 )) {
646 if (unlikely(errno != ENOENT)) {
647 error("FREEBSD: sysctl(%s...) failed: %s", "vm.swap_info", strerror(errno));
649 error("DISABLED: disk.io");
651 if (unlikely(size != sizeof(xsw))) {
652 error("FREEBSD: sysctl(%s...) expected %lu, got %lu", "vm.swap_info", (unsigned long)sizeof(xsw), (unsigned long)size);
654 error("DISABLED: disk.io");
658 total_xsw.bytes_used += xsw.xsw_used * system_pagesize;
659 total_xsw.bytes_total += xsw.xsw_nblks * system_pagesize;
662 if (likely(do_swap)) {
663 st = rrdset_find("system.swap");
665 st = rrdset_create("system", "swap", NULL, "swap", NULL, "System Swap", "MB", 201, update_every, RRDSET_TYPE_STACKED);
668 rrddim_add(st, "free", NULL, 1, 1048576, RRDDIM_ABSOLUTE);
669 rrddim_add(st, "used", NULL, 1, 1048576, RRDDIM_ABSOLUTE);
671 else rrdset_next(st);
673 rrddim_set(st, "used", total_xsw.bytes_used);
674 rrddim_set(st, "free", total_xsw.bytes_total - total_xsw.bytes_used);
680 // --------------------------------------------------------------------
682 if (likely(do_ram)) {
683 if (unlikely(GETSYSCTL("vm.stats.vm.v_active_count", vmmeter_data.v_active_count) ||
684 GETSYSCTL("vm.stats.vm.v_inactive_count", vmmeter_data.v_inactive_count) ||
685 GETSYSCTL("vm.stats.vm.v_wire_count", vmmeter_data.v_wire_count) ||
686 GETSYSCTL("vm.stats.vm.v_cache_count", vmmeter_data.v_cache_count) ||
687 GETSYSCTL("vfs.bufspace", vfs_bufspace_count) ||
688 GETSYSCTL("vm.stats.vm.v_free_count", vmmeter_data.v_free_count))) {
690 error("DISABLED: system.swapio");
692 st = rrdset_find("system.ram");
694 st = rrdset_create("system", "ram", NULL, "ram", NULL, "System RAM", "MB", 200, update_every, RRDSET_TYPE_STACKED);
696 rrddim_add(st, "active", NULL, system_pagesize, 1024, RRDDIM_ABSOLUTE);
697 rrddim_add(st, "inactive", NULL, system_pagesize, 1024, RRDDIM_ABSOLUTE);
698 rrddim_add(st, "wired", NULL, system_pagesize, 1024, RRDDIM_ABSOLUTE);
699 rrddim_add(st, "cache", NULL, system_pagesize, 1024, RRDDIM_ABSOLUTE);
700 rrddim_add(st, "buffers", NULL, 1, 1024, RRDDIM_ABSOLUTE);
701 rrddim_add(st, "free", NULL, system_pagesize, 1024, RRDDIM_ABSOLUTE);
703 else rrdset_next(st);
705 rrddim_set(st, "active", vmmeter_data.v_active_count);
706 rrddim_set(st, "inactive", vmmeter_data.v_inactive_count);
707 rrddim_set(st, "wired", vmmeter_data.v_wire_count);
708 rrddim_set(st, "cache", vmmeter_data.v_cache_count);
709 rrddim_set(st, "buffers", vfs_bufspace_count);
710 rrddim_set(st, "free", vmmeter_data.v_free_count);
715 // --------------------------------------------------------------------
717 if (likely(do_swapio)) {
718 if (unlikely(GETSYSCTL("vm.stats.vm.v_swappgsin", vmmeter_data.v_swappgsin) || GETSYSCTL("vm.stats.vm.v_swappgsout", vmmeter_data.v_swappgsout))) {
720 error("DISABLED: system.swapio");
722 st = rrdset_find("system.swapio");
724 st = rrdset_create("system", "swapio", NULL, "swap", NULL, "Swap I/O", "kilobytes/s", 250, update_every, RRDSET_TYPE_AREA);
726 rrddim_add(st, "in", NULL, system_pagesize, 1024, RRDDIM_INCREMENTAL);
727 rrddim_add(st, "out", NULL, -system_pagesize, 1024, RRDDIM_INCREMENTAL);
729 else rrdset_next(st);
731 rrddim_set(st, "in", vmmeter_data.v_swappgsin);
732 rrddim_set(st, "out", vmmeter_data.v_swappgsout);
737 // --------------------------------------------------------------------
739 if (likely(do_pgfaults)) {
740 if (unlikely(GETSYSCTL("vm.stats.vm.v_vm_faults", vmmeter_data.v_vm_faults) ||
741 GETSYSCTL("vm.stats.vm.v_io_faults", vmmeter_data.v_io_faults) ||
742 GETSYSCTL("vm.stats.vm.v_cow_faults", vmmeter_data.v_cow_faults) ||
743 GETSYSCTL("vm.stats.vm.v_cow_optim", vmmeter_data.v_cow_optim) ||
744 GETSYSCTL("vm.stats.vm.v_intrans", vmmeter_data.v_intrans))) {
746 error("DISABLED: mem.pgfaults");
748 st = rrdset_find("mem.pgfaults");
750 st = rrdset_create("mem", "pgfaults", NULL, "system", NULL, "Memory Page Faults", "page faults/s", 500, update_every, RRDSET_TYPE_LINE);
753 rrddim_add(st, "memory", NULL, 1, 1, RRDDIM_INCREMENTAL);
754 rrddim_add(st, "io_requiring", NULL, 1, 1, RRDDIM_INCREMENTAL);
755 rrddim_add(st, "cow", NULL, 1, 1, RRDDIM_INCREMENTAL);
756 rrddim_add(st, "cow_optimized", NULL, 1, 1, RRDDIM_INCREMENTAL);
757 rrddim_add(st, "in_transit", NULL, 1, 1, RRDDIM_INCREMENTAL);
759 else rrdset_next(st);
761 rrddim_set(st, "memory", vmmeter_data.v_vm_faults);
762 rrddim_set(st, "io_requiring", vmmeter_data.v_io_faults);
763 rrddim_set(st, "cow", vmmeter_data.v_cow_faults);
764 rrddim_set(st, "cow_optimized", vmmeter_data.v_cow_optim);
765 rrddim_set(st, "in_transit", vmmeter_data.v_intrans);
770 // --------------------------------------------------------------------
772 if (likely(do_ipc_semaphores)) {
773 if (unlikely(GETSYSCTL("kern.ipc.semmni", ipc_sem.semmni))) {
774 do_ipc_semaphores = 0;
775 error("DISABLED: system.ipc_semaphores");
776 error("DISABLED: system.ipc_semaphore_arrays");
778 ipc_sem_data = reallocz(ipc_sem_data, sizeof(struct semid_kernel) * ipc_sem.semmni);
779 if (unlikely(getsysctl("kern.ipc.sema", ipc_sem_data, sizeof(struct semid_kernel) * ipc_sem.semmni))) {
780 do_ipc_semaphores = 0;
781 error("DISABLED: system.ipc_semaphores");
782 error("DISABLED: system.ipc_semaphore_arrays");
784 for (i = 0; i < ipc_sem.semmni; i++) {
785 if (unlikely(ipc_sem_data[i].u.sem_perm.mode & SEM_ALLOC)) {
787 ipc_sem.semaphores += ipc_sem_data[i].u.sem_nsems;
791 // --------------------------------------------------------------------
793 st = rrdset_find("system.ipc_semaphores");
795 st = rrdset_create("system", "ipc_semaphores", NULL, "ipc semaphores", NULL, "IPC Semaphores", "semaphores", 1000, rrd_update_every, RRDSET_TYPE_AREA);
796 rrddim_add(st, "semaphores", NULL, 1, 1, RRDDIM_ABSOLUTE);
798 else rrdset_next(st);
800 rrddim_set(st, "semaphores", ipc_sem.semaphores);
803 // --------------------------------------------------------------------
805 st = rrdset_find("system.ipc_semaphore_arrays");
807 st = rrdset_create("system", "ipc_semaphore_arrays", NULL, "ipc semaphores", NULL, "IPC Semaphore Arrays", "arrays", 1000, rrd_update_every, RRDSET_TYPE_AREA);
808 rrddim_add(st, "arrays", NULL, 1, 1, RRDDIM_ABSOLUTE);
810 else rrdset_next(st);
812 rrddim_set(st, "arrays", ipc_sem.sets);
818 // --------------------------------------------------------------------
820 if (likely(do_ipc_shared_mem)) {
821 if (unlikely(GETSYSCTL("kern.ipc.shmmni", ipc_shm.shmmni))) {
822 do_ipc_shared_mem = 0;
823 error("DISABLED: system.ipc_shared_mem_segs");
824 error("DISABLED: system.ipc_shared_mem_size");
826 ipc_shm_data = reallocz(ipc_shm_data, sizeof(struct shmid_kernel) * ipc_shm.shmmni);
827 if (unlikely(getsysctl("kern.ipc.shmsegs", ipc_shm_data, sizeof(struct shmid_kernel) * ipc_shm.shmmni))) {
828 do_ipc_shared_mem = 0;
829 error("DISABLED: system.ipc_shared_mem_segs");
830 error("DISABLED: system.ipc_shared_mem_size");
832 for (i = 0; i < ipc_shm.shmmni; i++) {
833 if (unlikely(ipc_shm_data[i].u.shm_perm.mode & 0x0800)) {
835 ipc_shm.segsize += ipc_shm_data[i].u.shm_segsz;
839 // --------------------------------------------------------------------
841 st = rrdset_find("system.ipc_shared_mem_segs");
843 st = rrdset_create("system", "ipc_shared_mem_segs", NULL, "ipc shared memory", NULL, "IPC Shared Memory Segments", "segments", 1000, rrd_update_every, RRDSET_TYPE_AREA);
844 rrddim_add(st, "segments", NULL, 1, 1, RRDDIM_ABSOLUTE);
846 else rrdset_next(st);
848 rrddim_set(st, "segments", ipc_shm.segs);
851 // --------------------------------------------------------------------
853 st = rrdset_find("system.ipc_shared_mem_size");
855 st = rrdset_create("system", "ipc_shared_mem_size", NULL, "ipc shared memory", NULL, "IPC Shared Memory Segments Size", "kilobytes", 1000, rrd_update_every, RRDSET_TYPE_AREA);
856 rrddim_add(st, "allocated", NULL, 1, 1024, RRDDIM_ABSOLUTE);
858 else rrdset_next(st);
860 rrddim_set(st, "allocated", ipc_shm.segsize);
866 // --------------------------------------------------------------------
868 if (likely(do_ipc_msg_queues)) {
869 if (unlikely(GETSYSCTL("kern.ipc.msgmni", ipc_msq.msgmni))) {
870 do_ipc_msg_queues = 0;
871 error("DISABLED: system.ipc_msq_queues");
872 error("DISABLED: system.ipc_msq_messages");
873 error("DISABLED: system.ipc_msq_size");
875 ipc_msq_data = reallocz(ipc_msq_data, sizeof(struct msqid_kernel) * ipc_msq.msgmni);
876 if (unlikely(getsysctl("kern.ipc.msqids", ipc_msq_data, sizeof(struct msqid_kernel) * ipc_msq.msgmni))) {
877 do_ipc_msg_queues = 0;
878 error("DISABLED: system.ipc_msq_queues");
879 error("DISABLED: system.ipc_msq_messages");
880 error("DISABLED: system.ipc_msq_size");
882 for (i = 0; i < ipc_msq.msgmni; i++) {
883 if (unlikely(ipc_msq_data[i].u.msg_qbytes != 0)) {
885 ipc_msq.messages += ipc_msq_data[i].u.msg_qnum;
886 ipc_msq.usedsize += ipc_msq_data[i].u.msg_cbytes;
887 ipc_msq.allocsize += ipc_msq_data[i].u.msg_qbytes;
891 // --------------------------------------------------------------------
893 st = rrdset_find("system.ipc_msq_queues");
895 st = rrdset_create("system", "ipc_msq_queues", NULL, "ipc message queues", NULL, "Number of IPC Message Queues", "queues", 990, rrd_update_every, RRDSET_TYPE_AREA);
896 rrddim_add(st, "queues", NULL, 1, 1, RRDDIM_ABSOLUTE);
898 else rrdset_next(st);
900 rrddim_set(st, "queues", ipc_msq.queues);
903 // --------------------------------------------------------------------
905 st = rrdset_find("system.ipc_msq_messages");
907 st = rrdset_create("system", "ipc_msq_messages", NULL, "ipc message queues", NULL, "Number of Messages in IPC Message Queues", "messages", 1000, rrd_update_every, RRDSET_TYPE_AREA);
908 rrddim_add(st, "messages", NULL, 1, 1, RRDDIM_ABSOLUTE);
910 else rrdset_next(st);
912 rrddim_set(st, "messages", ipc_msq.messages);
915 // --------------------------------------------------------------------
917 st = rrdset_find("system.ipc_msq_size");
919 st = rrdset_create("system", "ipc_msq_size", NULL, "ipc message queues", NULL, "Size of IPC Message Queues", "bytes", 1100, rrd_update_every, RRDSET_TYPE_LINE);
920 rrddim_add(st, "allocated", NULL, 1, 1, RRDDIM_ABSOLUTE);
921 rrddim_add(st, "used", NULL, 1, 1, RRDDIM_ABSOLUTE);
923 else rrdset_next(st);
925 rrddim_set(st, "allocated", ipc_msq.allocsize);
926 rrddim_set(st, "used", ipc_msq.usedsize);
933 // --------------------------------------------------------------------
935 if (likely(do_netisr || do_netisr_per_core)) {
936 if (unlikely(GETSYSCTL("kern.smp.cpus", ncpus))) {
938 } else if (unlikely(ncpus > 9999)) {
939 error("FREEBSD: There are more than 4 digits in cpu cores number");
941 } else if (unlikely(sysctlbyname("net.isr.workstream", NULL, &netisr_workstream_size, NULL, 0) == -1)) {
942 error("FREEBSD: sysctl(net.isr.workstream...) failed: %s", strerror(errno));
944 } else if (unlikely(sysctlbyname("net.isr.work", NULL, &netisr_work_size, NULL, 0) == -1)) {
945 error("FREEBSD: sysctl(net.isr.work...) failed: %s", strerror(errno));
948 num_netisr_workstreams = netisr_workstream_size / sizeof(struct sysctl_netisr_workstream);
949 netisr_workstream = reallocz(netisr_workstream, num_netisr_workstreams * sizeof(struct sysctl_netisr_workstream));
950 if (unlikely(getsysctl("net.isr.workstream", netisr_workstream, num_netisr_workstreams * sizeof(struct sysctl_netisr_workstream)))){
953 num_netisr_works = netisr_work_size / sizeof(struct sysctl_netisr_work);
954 netisr_work = reallocz(netisr_work, num_netisr_works * sizeof(struct sysctl_netisr_work));
955 if (unlikely(getsysctl("net.isr.work", netisr_work, num_netisr_works * sizeof(struct sysctl_netisr_work)))){
960 if (unlikely(common_error)) {
962 error("DISABLED: system.softnet_stat");
963 do_netisr_per_core = 0;
964 error("DISABLED: system.cpuX_softnet_stat");
967 netisr_stats = reallocz(netisr_stats, (ncpus + 1) * sizeof(struct netisr_stats));
968 bzero(netisr_stats, (ncpus + 1) * sizeof(struct netisr_stats));
969 for (i = 0; i < num_netisr_workstreams; i++) {
970 for (n = 0; n < num_netisr_works; n++) {
971 if (netisr_workstream[i].snws_wsid == netisr_work[n].snw_wsid) {
972 netisr_stats[netisr_workstream[i].snws_cpu].dispatched += netisr_work[n].snw_dispatched;
973 netisr_stats[netisr_workstream[i].snws_cpu].hybrid_dispatched += netisr_work[n].snw_hybrid_dispatched;
974 netisr_stats[netisr_workstream[i].snws_cpu].qdrops += netisr_work[n].snw_qdrops;
975 netisr_stats[netisr_workstream[i].snws_cpu].queued += netisr_work[n].snw_queued;
979 for (i = 0; i < ncpus; i++) {
980 netisr_stats[ncpus].dispatched += netisr_stats[i].dispatched;
981 netisr_stats[ncpus].hybrid_dispatched += netisr_stats[i].hybrid_dispatched;
982 netisr_stats[ncpus].qdrops += netisr_stats[i].qdrops;
983 netisr_stats[ncpus].queued += netisr_stats[i].queued;
988 // --------------------------------------------------------------------
990 if (likely(do_netisr)) {
991 st = rrdset_find_bytype("system", "softnet_stat");
993 st = rrdset_create("system", "softnet_stat", NULL, "softnet_stat", NULL, "System softnet_stat", "events/s", 955, update_every, RRDSET_TYPE_LINE);
994 rrddim_add(st, "dispatched", NULL, 1, 1, RRDDIM_INCREMENTAL);
995 rrddim_add(st, "hybrid_dispatched", NULL, 1, 1, RRDDIM_INCREMENTAL);
996 rrddim_add(st, "qdrops", NULL, 1, 1, RRDDIM_INCREMENTAL);
997 rrddim_add(st, "queued", NULL, 1, 1, RRDDIM_INCREMENTAL);
999 else rrdset_next(st);
1001 rrddim_set(st, "dispatched", netisr_stats[ncpus].dispatched);
1002 rrddim_set(st, "hybrid_dispatched", netisr_stats[ncpus].hybrid_dispatched);
1003 rrddim_set(st, "qdrops", netisr_stats[ncpus].qdrops);
1004 rrddim_set(st, "queued", netisr_stats[ncpus].queued);
1008 // --------------------------------------------------------------------
1010 if (likely(do_netisr_per_core)) {
1011 for (i = 0; i < ncpus ;i++) {
1012 snprintfz(netstat_cpuid, 21, "cpu%d_softnet_stat", i);
1014 st = rrdset_find_bytype("cpu", netstat_cpuid);
1015 if (unlikely(!st)) {
1016 st = rrdset_create("cpu", netstat_cpuid, NULL, "softnet_stat", NULL, "Per CPU netisr statistics", "events/s", 1101 + i, update_every, RRDSET_TYPE_LINE);
1017 rrddim_add(st, "dispatched", NULL, 1, 1, RRDDIM_INCREMENTAL);
1018 rrddim_add(st, "hybrid_dispatched", NULL, 1, 1, RRDDIM_INCREMENTAL);
1019 rrddim_add(st, "qdrops", NULL, 1, 1, RRDDIM_INCREMENTAL);
1020 rrddim_add(st, "queued", NULL, 1, 1, RRDDIM_INCREMENTAL);
1022 else rrdset_next(st);
1024 rrddim_set(st, "dispatched", netisr_stats[i].dispatched);
1025 rrddim_set(st, "hybrid_dispatched", netisr_stats[i].hybrid_dispatched);
1026 rrddim_set(st, "qdrops", netisr_stats[i].qdrops);
1027 rrddim_set(st, "queued", netisr_stats[i].queued);