#include <netinet/icmp6.h>
// NEEDED BY do_space, do_inodes
#include <sys/mount.h>
+// NEEDED BY do_uptime
+#include <time.h>
#define KILO_FACTOR 1024
#define MEGA_FACTOR 1048576 // 1024 * 1024
#define GIGA_FACTOR 1073741824 // 1024 * 1024 * 1024
+#define MAX_INT_DIGITS 10 // maximum number of digits for int
+
// NEEDED BY: do_disk_io
#define RRD_TYPE_DISK "disk"
#define IFA_DATA(s) (((struct if_data *)ifa->ifa_data)->ifi_ ## s)
int do_freebsd_sysctl(int update_every, usec_t dt) {
- (void)dt;
-
static int do_cpu = -1, do_cpu_cores = -1, do_interrupts = -1, do_context = -1, do_forks = -1, do_processes = -1,
do_loadavg = -1, do_all_processes = -1, do_disk_io = -1, do_swap = -1, do_ram = -1, do_swapio = -1,
do_pgfaults = -1, do_committed = -1, do_ipc_semaphores = -1, do_ipc_shared_mem = -1, do_ipc_msg_queues = -1,
do_ip_packets = -1, do_ip_fragsout = -1, do_ip_fragsin = -1, do_ip_errors = -1,
do_ip6_packets = -1, do_ip6_fragsout = -1, do_ip6_fragsin = -1, do_ip6_errors = -1,
do_icmp6 = -1, do_icmp6_redir = -1, do_icmp6_errors = -1, do_icmp6_echos = -1, do_icmp6_router = -1,
- do_icmp6_neighbor = -1, do_icmp6_types = -1, do_space = -1, do_inodes = -1;
+ do_icmp6_neighbor = -1, do_icmp6_types = -1, do_space = -1, do_inodes = -1, do_uptime = -1;
if (unlikely(do_cpu == -1)) {
do_cpu = config_get_boolean("plugin:freebsd:sysctl", "cpu utilization", 1);
do_icmp6_types = config_get_boolean_ondemand("plugin:freebsd:sysctl", "icmp types", CONFIG_ONDEMAND_ONDEMAND);
do_space = config_get_boolean("plugin:freebsd:sysctl", "space usage for all disks", 1);
do_inodes = config_get_boolean("plugin:freebsd:sysctl", "inodes usage for all disks", 1);
+ do_uptime = config_get_boolean("plugin:freebsd:sysctl", "system uptime", 1);
}
RRDSET *st;
char title[4096 + 1];
// NEEDED BY: do_loadavg
- static usec_t last_loadavg_usec = 0;
+ static usec_t next_loadavg_dt = 0;
struct loadavg sysload;
// NEEDED BY: do_cpu, do_cpu_cores
// NEEDED BY: do_cpu_cores
static long *pcpu_cp_time = NULL;
- char cpuid[8]; // no more than 4 digits expected
+ char cpuid[MAX_INT_DIGITS + 1];
// NEEDED BY: do_all_processes, do_processes
struct vmtotal vmtotal_data;
int numdevs;
static void *devstat_data = NULL;
struct devstat *dstat;
+ char disk[DEVSTAT_NAME_LEN + MAX_INT_DIGITS + 1];
struct cur_dstat {
collected_number duration_read_ms;
collected_number duration_write_ms;
int mntsize;
char mntonname[MNAMELEN + 1];
+ // NEEDED BY: do_uptime
+ struct timespec boot_time, cur_time;
+
// --------------------------------------------------------------------
- if (last_loadavg_usec <= dt) {
+ if (next_loadavg_dt <= dt) {
if (likely(do_loadavg)) {
if (unlikely(GETSYSCTL("vm.loadavg", sysload))) {
do_loadavg = 0;
rrddim_set(st, "load5", (collected_number) ((double)sysload.ldavg[1] / sysload.fscale * 1000));
rrddim_set(st, "load15", (collected_number) ((double)sysload.ldavg[2] / sysload.fscale * 1000));
rrdset_done(st);
+
+ next_loadavg_dt = st->update_every * USEC_PER_SEC;
}
}
-
- last_loadavg_usec = st->update_every * USEC_PER_SEC;
}
- else last_loadavg_usec -= dt;
+ else next_loadavg_dt -= dt;
// --------------------------------------------------------------------
error("DISABLED: cpu.cpuXX");
} else {
pcpu_cp_time = reallocz(pcpu_cp_time, sizeof(cp_time) * ncpus);
-
- for (i = 0; i < ncpus; i++) {
- if (unlikely(getsysctl("kern.cp_times", pcpu_cp_time, sizeof(cp_time) * ncpus))) {
- do_cpu_cores = 0;
- error("DISABLED: cpu.cpuXX");
- break;
- }
- if (unlikely(ncpus > 9999)) {
- error("FREEBSD: There are more than 4 digits in cpu cores number");
- do_cpu_cores = 0;
- error("DISABLED: cpu.cpuXX");
- break;
- }
- snprintfz(cpuid, 8, "cpu%d", i);
-
- st = rrdset_find_bytype("cpu", cpuid);
- if (unlikely(!st)) {
- st = rrdset_create("cpu", cpuid, NULL, "utilization", "cpu.cpu", "Core utilization", "percentage", 1000, update_every, RRDSET_TYPE_STACKED);
-
- rrddim_add(st, "user", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
- rrddim_add(st, "nice", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
- rrddim_add(st, "system", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
- rrddim_add(st, "interrupt", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
- rrddim_add(st, "idle", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
- rrddim_hide(st, "idle");
- }
- else rrdset_next(st);
-
- rrddim_set(st, "user", pcpu_cp_time[i * 5 + 0]);
- rrddim_set(st, "nice", pcpu_cp_time[i * 5 + 1]);
- rrddim_set(st, "system", pcpu_cp_time[i * 5 + 2]);
- rrddim_set(st, "interrupt", pcpu_cp_time[i * 5 + 3]);
- rrddim_set(st, "idle", pcpu_cp_time[i * 5 + 4]);
- rrdset_done(st);
+ if (unlikely(getsysctl("kern.cp_times", pcpu_cp_time, sizeof(cp_time) * ncpus))) {
+ do_cpu_cores = 0;
+ error("DISABLED: cpu.cpuXX");
+ } else {
+ for (i = 0; i < ncpus; i++) {
+ snprintfz(cpuid, MAX_INT_DIGITS, "cpu%d", i);
+ st = rrdset_find_bytype("cpu", cpuid);
+ if (unlikely(!st)) {
+ st = rrdset_create("cpu", cpuid, NULL, "utilization", "cpu.cpu", "Core utilization",
+ "percentage", 1000, update_every, RRDSET_TYPE_STACKED);
+
+ rrddim_add(st, "user", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
+ rrddim_add(st, "nice", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
+ rrddim_add(st, "system", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
+ rrddim_add(st, "interrupt", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
+ rrddim_add(st, "idle", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
+ rrddim_hide(st, "idle");
+ } else
+ rrdset_next(st);
+
+ rrddim_set(st, "user", pcpu_cp_time[i * 5 + 0]);
+ rrddim_set(st, "nice", pcpu_cp_time[i * 5 + 1]);
+ rrddim_set(st, "system", pcpu_cp_time[i * 5 + 2]);
+ rrddim_set(st, "interrupt", pcpu_cp_time[i * 5 + 3]);
+ rrddim_set(st, "idle", pcpu_cp_time[i * 5 + 4]);
+ rrdset_done(st);
+ }
}
}
}
error("DISABLED: disk.io");
} else {
dstat = devstat_data + sizeof(long); // skip generation number
- collected_number total_disk_reads = 0;
- collected_number total_disk_writes = 0;
+ collected_number total_disk_kbytes_read = 0;
+ collected_number total_disk_kbytes_write = 0;
for (i = 0; i < numdevs; i++) {
if (((dstat[i].device_type & DEVSTAT_TYPE_MASK) == DEVSTAT_TYPE_DIRECT) || ((dstat[i].device_type & DEVSTAT_TYPE_MASK) == DEVSTAT_TYPE_STORARRAY)) {
+ sprintf(disk, "%s%d", dstat[i].device_name, dstat[i].unit_number);
// --------------------------------------------------------------------
- st = rrdset_find_bytype(RRD_TYPE_DISK, dstat[i].device_name);
+ st = rrdset_find_bytype(RRD_TYPE_DISK, disk);
if (unlikely(!st)) {
- 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);
+ st = rrdset_create(RRD_TYPE_DISK, disk, NULL, disk, "disk.io", "Disk I/O Bandwidth", "kilobytes/s", 2000, update_every, RRDSET_TYPE_AREA);
rrddim_add(st, "reads", NULL, 1, 1024, RRDDIM_INCREMENTAL);
rrddim_add(st, "writes", NULL, -1, 1024, RRDDIM_INCREMENTAL);
}
else rrdset_next(st);
- total_disk_reads += dstat[i].bytes[DEVSTAT_READ];
- total_disk_writes += dstat[i].bytes[DEVSTAT_WRITE];
+ total_disk_kbytes_read += dstat[i].bytes[DEVSTAT_READ]/KILO_FACTOR;
+ total_disk_kbytes_write += dstat[i].bytes[DEVSTAT_WRITE]/KILO_FACTOR;
prev_dstat.bytes_read = rrddim_set(st, "reads", dstat[i].bytes[DEVSTAT_READ]);
prev_dstat.bytes_write = rrddim_set(st, "writes", dstat[i].bytes[DEVSTAT_WRITE]);
rrdset_done(st);
// --------------------------------------------------------------------
- st = rrdset_find_bytype("disk_ops", dstat[i].device_name);
+ st = rrdset_find_bytype("disk_ops", disk);
if (unlikely(!st)) {
- 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);
+ st = rrdset_create("disk_ops", disk, NULL, disk, "disk.ops", "Disk Completed I/O Operations", "operations/s", 2001, update_every, RRDSET_TYPE_LINE);
st->isdetail = 1;
rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL);
// --------------------------------------------------------------------
- st = rrdset_find_bytype("disk_qops", dstat[i].device_name);
+ st = rrdset_find_bytype("disk_qops", disk);
if (unlikely(!st)) {
- 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);
+ st = rrdset_create("disk_qops", disk, NULL, disk, "disk.qops", "Disk Current I/O Operations", "operations", 2002, update_every, RRDSET_TYPE_LINE);
st->isdetail = 1;
rrddim_add(st, "operations", NULL, 1, 1, RRDDIM_ABSOLUTE);
// --------------------------------------------------------------------
- st = rrdset_find_bytype("disk_util", dstat[i].device_name);
+ st = rrdset_find_bytype("disk_util", disk);
if (unlikely(!st)) {
- 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);
+ st = rrdset_create("disk_util", disk, NULL, disk, "disk.util", "Disk Utilization Time", "% of time working", 2004, update_every, RRDSET_TYPE_AREA);
st->isdetail = 1;
rrddim_add(st, "utilization", NULL, 1, 10, RRDDIM_INCREMENTAL);
// --------------------------------------------------------------------
- st = rrdset_find_bytype("disk_iotime", dstat[i].device_name);
+ st = rrdset_find_bytype("disk_iotime", disk);
if (unlikely(!st)) {
- 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);
+ st = rrdset_create("disk_iotime", disk, NULL, disk, "disk.iotime", "Disk Total I/O Time", "milliseconds/s", 2022, update_every, RRDSET_TYPE_LINE);
st->isdetail = 1;
rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL);
// --------------------------------------------------------------------
- st = rrdset_find_bytype("disk_await", dstat[i].device_name);
+ st = rrdset_find_bytype("disk_await", disk);
if (unlikely(!st)) {
- 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);
+ st = rrdset_create("disk_await", disk, NULL, disk, "disk.await", "Average Completed I/O Operation Time", "ms per operation", 2005, update_every, RRDSET_TYPE_LINE);
st->isdetail = 1;
rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_ABSOLUTE);
// --------------------------------------------------------------------
- st = rrdset_find_bytype("disk_avgsz", dstat[i].device_name);
+ st = rrdset_find_bytype("disk_avgsz", disk);
if (unlikely(!st)) {
- 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);
+ st = rrdset_create("disk_avgsz", disk, NULL, disk, "disk.avgsz", "Average Completed I/O Operation Bandwidth", "kilobytes per operation", 2006, update_every, RRDSET_TYPE_AREA);
st->isdetail = 1;
rrddim_add(st, "reads", NULL, 1, 1024, RRDDIM_ABSOLUTE);
// --------------------------------------------------------------------
- st = rrdset_find_bytype("disk_svctm", dstat[i].device_name);
+ st = rrdset_find_bytype("disk_svctm", disk);
if (unlikely(!st)) {
- 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);
+ st = rrdset_create("disk_svctm", disk, NULL, disk, "disk.svctm", "Average Service Time", "ms per operation", 2007, update_every, RRDSET_TYPE_LINE);
st->isdetail = 1;
rrddim_add(st, "svctm", NULL, 1, 1, RRDDIM_ABSOLUTE);
rrdset_done(st);
}
}
+ }
- // --------------------------------------------------------------------
-
- st = rrdset_find_bytype("system", "io");
- if (unlikely(!st)) {
- st = rrdset_create("system", "io", NULL, "disk", NULL, "Disk I/O", "kilobytes/s", 150, update_every, RRDSET_TYPE_AREA);
- rrddim_add(st, "in", NULL, 1, 1024, RRDDIM_INCREMENTAL);
- rrddim_add(st, "out", NULL, -1, 1024, RRDDIM_INCREMENTAL);
- }
- else rrdset_next(st);
+ // --------------------------------------------------------------------
- rrddim_set(st, "in", total_disk_reads);
- rrddim_set(st, "out", total_disk_writes);
- rrdset_done(st);
+ st = rrdset_find_bytype("system", "io");
+ if (unlikely(!st)) {
+ st = rrdset_create("system", "io", NULL, "disk", NULL, "Disk I/O", "kilobytes/s", 150, update_every, RRDSET_TYPE_AREA);
+ rrddim_add(st, "in", NULL, 1, 1, RRDDIM_INCREMENTAL);
+ rrddim_add(st, "out", NULL, -1, 1, RRDDIM_INCREMENTAL);
}
+ else rrdset_next(st);
+
+ rrddim_set(st, "in", total_disk_kbytes_read);
+ rrddim_set(st, "out", total_disk_kbytes_write);
+ rrdset_done(st);
}
}
}
if (unlikely(GETSYSCTL("vm.stats.vm.v_active_count", vmmeter_data.v_active_count) ||
GETSYSCTL("vm.stats.vm.v_inactive_count", vmmeter_data.v_inactive_count) ||
GETSYSCTL("vm.stats.vm.v_wire_count", vmmeter_data.v_wire_count) ||
+#if __FreeBSD_version < 1200016
GETSYSCTL("vm.stats.vm.v_cache_count", vmmeter_data.v_cache_count) ||
+#endif
GETSYSCTL("vfs.bufspace", vfs_bufspace_count) ||
GETSYSCTL("vm.stats.vm.v_free_count", vmmeter_data.v_free_count))) {
do_ram = 0;
rrddim_add(st, "active", NULL, system_pagesize, MEGA_FACTOR, RRDDIM_ABSOLUTE);
rrddim_add(st, "inactive", NULL, system_pagesize, MEGA_FACTOR, RRDDIM_ABSOLUTE);
rrddim_add(st, "wired", NULL, system_pagesize, MEGA_FACTOR, RRDDIM_ABSOLUTE);
+#if __FreeBSD_version < 1200016
rrddim_add(st, "cache", NULL, system_pagesize, MEGA_FACTOR, RRDDIM_ABSOLUTE);
+#endif
rrddim_add(st, "buffers", NULL, 1, MEGA_FACTOR, RRDDIM_ABSOLUTE);
rrddim_add(st, "free", NULL, system_pagesize, MEGA_FACTOR, RRDDIM_ABSOLUTE);
}
rrddim_set(st, "active", vmmeter_data.v_active_count);
rrddim_set(st, "inactive", vmmeter_data.v_inactive_count);
rrddim_set(st, "wired", vmmeter_data.v_wire_count);
+#if __FreeBSD_version < 1200016
rrddim_set(st, "cache", vmmeter_data.v_cache_count);
+#endif
rrddim_set(st, "buffers", vfs_bufspace_count);
rrddim_set(st, "free", vmmeter_data.v_free_count);
rrdset_done(st);
if (likely(do_netisr || do_netisr_per_core)) {
if (unlikely(GETSYSCTL("kern.smp.cpus", ncpus))) {
common_error = 1;
- } else if (unlikely(ncpus > 9999)) {
- error("FREEBSD: There are more than 4 digits in cpu cores number");
- common_error = 1;
} else if (unlikely(sysctlbyname("net.isr.workstream", NULL, &netisr_workstream_size, NULL, 0) == -1)) {
error("FREEBSD: sysctl(net.isr.workstream...) failed: %s", strerror(errno));
common_error = 1;
}
}
+ // --------------------------------------------------------------------
+
+ if (likely(do_uptime)) {
+ if (unlikely(GETSYSCTL("kern.boottime", boot_time))) {
+ do_uptime = 0;
+ error("DISABLED: system.uptime");
+ } else {
+ clock_gettime(CLOCK_REALTIME, &cur_time);
+ st = rrdset_find("system.uptime");
+
+ if(unlikely(!st)) {
+ st = rrdset_create("system", "uptime", NULL, "uptime", NULL, "System Uptime", "seconds", 1000, update_every, RRDSET_TYPE_LINE);
+ rrddim_add(st, "uptime", NULL, 1, 1, RRDDIM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set(st, "uptime", cur_time.tv_sec - boot_time.tv_sec);
+ rrdset_done(st);
+ }
+ }
+
return 0;
}