From f5b161b793ae962bbfa3d4148f0166af6f705a46 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Wed, 6 Apr 2016 20:42:15 +0200 Subject: [PATCH 01/10] plugins: adding the sysctl/proc build config It makes it very easy to have 2 implementation of plugins. Only the correct one gets compiled and linked to the global executable. --- configure.ac | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/configure.ac b/configure.ac index d50fbc5..74cbb9e 100644 --- a/configure.ac +++ b/configure.ac @@ -15,6 +15,16 @@ AM_INIT_AUTOMAKE([foreign subdir-objects]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) AM_MAINTAINER_MODE([enable]) +AC_CANONICAL_HOST +case $host in + *bsd* | *darwin* ) + SYS_API='sysctl' ;; + *) + SYS_API='proc' ;; +esac + +AC_SUBST([SYS_API]) + AC_PROG_CC AC_PROG_CC_C_O From ba8211cc0dfb05b459b1d1492313cef7fd0f0a82 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Wed, 6 Apr 2016 21:02:13 +0200 Subject: [PATCH 02/10] Makefile: fix the .pod -> .1 for non-gnu make --- common.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common.am b/common.am index 8686f90..ec99832 100644 --- a/common.am +++ b/common.am @@ -1,8 +1,9 @@ MANCENTER="Munin C Documentation" -%.1:%.pod +.pod.1: $(AM_V_GEN)pod2man --section=1 --release=$(VERSION) --center=$(MANCENTER) $< > $@ sed -i -e 's#@@pkglibexecdir@@#$(pkglibexecdir)#' -e 's#@@CONFDIR@@#$(sysconfdir)#' $@ +SUFFIXES = .1 .pod # vim:ft=make From 5f389b9251b7c752ddd0433eb11764e8af0d06fb Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Sat, 23 Jun 2018 13:58:50 +0200 Subject: [PATCH 03/10] plugins: first BSD version of plugins --- src/common/xctype.h | 7 + src/plugins/Makefile.am | 2 +- src/plugins/cpu-sysctl.c | 189 ++++++++++++++++++++++++++ src/plugins/memory-sysctl.c | 106 +++++++++++++++ src/plugins/p/{load.c => load-proc.c} | 0 src/plugins/p/load-sysctl.c | 55 ++++++++ 6 files changed, 358 insertions(+), 1 deletion(-) create mode 100644 src/common/xctype.h create mode 100644 src/plugins/cpu-sysctl.c create mode 100644 src/plugins/memory-sysctl.c rename src/plugins/p/{load.c => load-proc.c} (100%) create mode 100644 src/plugins/p/load-sysctl.c diff --git a/src/common/xctype.h b/src/common/xctype.h new file mode 100644 index 0000000..fe67da3 --- /dev/null +++ b/src/common/xctype.h @@ -0,0 +1,7 @@ +/* put here extended versions of + * Only use #define tricks to avoid the overhead of func call + */ + +/* Defined by the ctype(3) in NetBSD */ +#define xisdigit(x) isdigit((int)(unsigned char) (x)) +#define xisspace(x) isspace((int)(unsigned char) (x)) diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index 603d602..365d75c 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -24,7 +24,7 @@ munin_plugins_c_SOURCES = \ p/if_err_.c \ p/interrupts.c \ p/iostat.c \ - p/load.c \ + p/load-$(SYS_API).c \ p/open_files.c \ p/open_inodes.c \ p/processes.c \ diff --git a/src/plugins/cpu-sysctl.c b/src/plugins/cpu-sysctl.c new file mode 100644 index 0000000..3ea6ead --- /dev/null +++ b/src/plugins/cpu-sysctl.c @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2015 Steve Schnepp - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "plugins.h" + +#define SYSWARNING 30 +#define SYSCRITICAL 50 +#define USRWARNING 80 + +/* TODO: port support for env.foo_warning and env.foo_critical from mainline plugin */ + +static int print_stat_value(const char* field_name, const char* stat_value, int hz_) { + return printf("%s.value %llu\n", field_name, strtoull(stat_value, NULL, 0) * 100 / hz_); +} + +int cpu(int argc, char **argv) { + FILE *f; + char buff[256], *s; + int ncpu=0, extinfo=0, hz_; + bool scaleto100 = false; + if(argc > 1) { + if(!strcmp(argv[1], "config")) { + s = getenv("scaleto100"); + if(s && !strcmp(s, "yes")) + scaleto100 = true; + + if(!(f=fopen(PROC_STAT, "r"))) + return fail("cannot open " PROC_STAT); + while(fgets(buff, 256, f)) { + if(!strncmp(buff, "cpu", 3)) { + if(isdigit(buff[3])) + ncpu++; + if(buff[3] == ' ' && 0 == extinfo) { + strtok(buff+4, " \t"); + for(extinfo=1;strtok(NULL, " \t");extinfo++) + ; + } + } + } + fclose(f); + + if(ncpu < 1 || extinfo < 4) + return fail("cannot parse " PROC_STAT); + + puts("graph_title CPU usage"); + if(extinfo >= 7) + puts("graph_order system user nice idle iowait irq softirq"); + else + puts("graph_order system user nice idle"); + if(scaleto100) + puts("graph_args --base 1000 -r --lower-limit 0 --upper-limit 100"); + else + printf("graph_args --base 1000 -r --lower-limit 0 --upper-limit %d\n", 100 * ncpu); + puts("graph_vlabel %\n" + "graph_scale no\n" + "graph_info This graph shows how CPU time is spent.\n" + "graph_category system\n" + "graph_period second\n" + "system.label system\n" + "system.draw AREA"); + printf("system.max %d\n", 100 * ncpu); + puts("system.min 0\n" + "system.type DERIVE"); + printf("system.warning %d\n", SYSWARNING * ncpu); + printf("system.critical %d\n", SYSCRITICAL * ncpu); + puts("system.info CPU time spent by the kernel in system activities\n" + "user.label user\n" + "user.draw STACK\n" + "user.min 0"); + printf("user.max %d\n", 100 * ncpu); + printf("user.warning %d\n", USRWARNING * ncpu); + puts("user.type DERIVE\n" + "user.info CPU time spent by normal programs and daemons\n" + "nice.label nice\n" + "nice.draw STACK\n" + "nice.min 0"); + printf("nice.max %d\n", 100 * ncpu); + puts("nice.type DERIVE\n" + "nice.info CPU time spent by nice(1)d programs\n" + "idle.label idle\n" + "idle.draw STACK\n" + "idle.min 0"); + printf("idle.max %d\n", 100 * ncpu); + puts("idle.type DERIVE\n" + "idle.info Idle CPU time"); + if(scaleto100) + printf("system.cdef system,%d,/\n" + "user.cdef user,%d,/\n" + "nice.cdef nice,%d,/\n" + "idle.cdef idle,%d,/\n", ncpu, ncpu, ncpu, ncpu); + if(extinfo >= 7) { + puts("iowait.label iowait\n" + "iowait.draw STACK\n" + "iowait.min 0"); + printf("iowait.max %d\n", 100 * ncpu); + puts("iowait.type DERIVE\n" + "iowait.info CPU time spent waiting for I/O operations to finish\n" + "irq.label irq\n" + "irq.draw STACK\n" + "irq.min 0"); + printf("irq.max %d\n", 100 * ncpu); + puts("irq.type DERIVE\n" + "irq.info CPU time spent handling interrupts\n" + "softirq.label softirq\n" + "softirq.draw STACK\n" + "softirq.min 0"); + printf("softirq.max %d\n", 100 * ncpu); + puts("softirq.type DERIVE\n" + "softirq.info CPU time spent handling \"batched\" interrupts"); + if(scaleto100) + printf("iowait.cdef iowait,%d,/\n" + "irq.cdef irq,%d,/\n" + "softirq.cdef softirq,%d,/\n", ncpu, ncpu, ncpu); + } + if(extinfo >= 8) { + puts("steal.label steal\n" + "steal.draw STACK\n" + "steal.min 0"); + printf("steal.max %d\n", 100 * ncpu); + puts("steal.type DERIVE\n" + "steal.info The time that a virtual CPU had runnable tasks, but the virtual CPU itself was not running"); + if(scaleto100) + printf("steal.cdef steal,%d,/\n", ncpu); + } + if(extinfo >= 9) { + puts("guest.label guest\n" + "guest.draw STACK\n" + "guest.min 0"); + printf("guest.max %d\n", 100 * ncpu); + puts("guest.type DERIVE\n" + "guest.info The time spent running a virtual CPU for guest operating systems under the control of the Linux kernel."); + if(scaleto100) + printf("guest.cdef guest,%d,/\n", ncpu); + } + return 0; + } + if(!strcmp(argv[1], "autoconf")) + return autoconf_check_readable(PROC_STAT); + } + if(!(f=fopen(PROC_STAT, "r"))) + return fail("cannot open " PROC_STAT); + hz_ = getenvint("HZ", 100); + while(fgets(buff, 256, f)) { + if(!strncmp(buff, "cpu ", 4)) { + fclose(f); + if(!(s = strtok(buff+4, " \t"))) + break; + print_stat_value("user", s, hz_); + if(!(s = strtok(NULL, " \t"))) + break; + print_stat_value("nice", s, hz_); + if(!(s = strtok(NULL, " \t"))) + break; + print_stat_value("system", s, hz_); + if(!(s = strtok(NULL, " \t"))) + break; + print_stat_value("idle", s, hz_); + if(!(s = strtok(NULL, " \t"))) + return 0; + print_stat_value("iowait", s, hz_); + if(!(s = strtok(NULL, " \t"))) + return 0; + print_stat_value("irq", s, hz_); + if(!(s = strtok(NULL, " \t"))) + return 0; + print_stat_value("softirq", s, hz_); + if(!(s = strtok(NULL, " \t"))) + return 0; + print_stat_value("steal", s, hz_); + if(!(s = strtok(NULL, " \t"))) + return 0; + print_stat_value("guest", s, hz_); + return 0; + } + } + fclose(f); + return fail("no cpu line found in " PROC_STAT); +} diff --git a/src/plugins/memory-sysctl.c b/src/plugins/memory-sysctl.c new file mode 100644 index 0000000..07fb433 --- /dev/null +++ b/src/plugins/memory-sysctl.c @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2015 Steve Schnepp - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +/* This plugin is compatible with munin-mainline version 2.0.25. */ + +#include +#include +#include +#include +#include +#include "common.h" +#include "plugins.h" + +#include + +int memory(int argc, char **argv) { + + if(argc > 1) { + if(!strcmp(argv[1], "config")) { + printf( + "graph_vlabel Bytes\n" + "graph_args --base 1024 -l 0\n" + "graph_title Memory usage\n" + "graph_category system\n" + "graph_info This graph shows what the machine uses memory for.\n" + ); + printf("apps.label apps\n"); + printf("apps.draw AREA\n"); + printf("apps.info Memory used by user-space applications.\n"); + + printf("free.label free\n"); + printf("free.draw STACK\n"); + printf("free.info Wasted memory. Memory that is not used for anything at all.\n"); + + printf("swap.label swap\n"); + printf("swap.draw STACK\n"); + printf("swap.info Swap space used.\n"); + + +if [ "$1" = "config" ]; then + echo 'graph_args --base 1024 -l 0 --vertical-label Bytes --upper-limit' $MEMMAX + echo 'graph_title Memory usage' + echo 'graph_category system' + echo 'graph_info This graph shows what the machine uses its memory for.' + echo 'graph_order active inactive wired cached free swap buffers' + echo 'active.label active' + echo 'active.info pages recently statistically used' + echo 'active.draw AREA' + echo 'inactive.label inactive' + echo 'inactive.info pages recently statistically unused' + echo 'inactive.draw STACK' + echo 'wired.label wired' + echo 'wired.info pages that are fixed into memory, usually for kernel purposes, but also sometimes for special use in processes' + echo 'wired.draw STACK' + echo 'cached.label cache' + echo 'cached.info pages that have percolated from inactive to a status where they maintain their data, but can often be immediately reused' + echo 'cached.draw STACK' + echo 'free.label free' + echo 'free.info pages without data content' + echo 'free.draw STACK' + echo 'swap.label swap' + echo 'swap.info Swap space used' + echo 'swap.draw STACK' + echo 'buffers.label buffers' + echo 'buffers.info pages used for filesystem buffers' + echo 'buffers.draw LINE' + exit 0 +fi + + + + + + + + + + + return 0; + } + if(!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + struct vmtotal s; + size_t len = sizeof(s); + + if (sysctlbyname("vm.total", &s, &len, NULL, 0) < 0) { + return fail("sysctl"); + } + + double ldavg = l.ldavg[0]; + double fscale = l.fscale; + + printf("# vm.loadavg, ldavg:%f fscale:%f -", ldavg, fscale); + printf("\n"); + + double load_1 = ldavg / fscale; + printf("load.value %.2f\n", load_1); + return 0; +} diff --git a/src/plugins/p/load.c b/src/plugins/p/load-proc.c similarity index 100% rename from src/plugins/p/load.c rename to src/plugins/p/load-proc.c diff --git a/src/plugins/p/load-sysctl.c b/src/plugins/p/load-sysctl.c new file mode 100644 index 0000000..ca4d751 --- /dev/null +++ b/src/plugins/p/load-sysctl.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2015 Steve Schnepp - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +/* This plugin is compatible with munin-mainline version 2.0.25. */ + +#include +#include +#include +#include +#include +#include "common.h" +#include "plugins.h" + +#include + +int load(int argc, char **argv) { + if(argc > 1) { + if(!strcmp(argv[1], "config")) { + puts("graph_title Load average\n" + "graph_args --base 1000 -l 0\n" + "graph_vlabel load\n" + "graph_scale no\n" + "graph_category system\n" + "load.label load"); + print_warncrit("load"); + puts("graph_info The load average of the machine describes how many processes are in the run-queue (scheduled to run \"immediately\").\n" + "load.info 5 minute load average"); + return 0; + } + if(!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + struct loadavg l; + size_t len = sizeof(l); + + if (sysctlbyname("vm.loadavg", &l, &len, NULL, 0) < 0) { + return fail("sysctl"); + } + + double ldavg = l.ldavg[0]; + double fscale = l.fscale; + + printf("# vm.loadavg, ldavg:%f fscale:%f -", ldavg, fscale); + printf("\n"); + + double load_1 = ldavg / fscale; + printf("load.value %.2f\n", load_1); + return 0; +} From 31932ece8c5d353f2acc340c66c0f2628ca5b532 Mon Sep 17 00:00:00 2001 From: Steve Mokris Date: Sun, 4 Sep 2022 14:39:56 -0400 Subject: [PATCH 04/10] Makefile: fix the .pod -> .1 for non-gnu sed --- common.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.am b/common.am index ec99832..7ee063d 100644 --- a/common.am +++ b/common.am @@ -2,7 +2,7 @@ MANCENTER="Munin C Documentation" .pod.1: $(AM_V_GEN)pod2man --section=1 --release=$(VERSION) --center=$(MANCENTER) $< > $@ - sed -i -e 's#@@pkglibexecdir@@#$(pkglibexecdir)#' -e 's#@@CONFDIR@@#$(sysconfdir)#' $@ + sed -i '' -e 's#@@pkglibexecdir@@#$(pkglibexecdir)#' -e 's#@@CONFDIR@@#$(sysconfdir)#' $@ SUFFIXES = .1 .pod From cee18d0ed60350175233416631b12aeffec9a869 Mon Sep 17 00:00:00 2001 From: Steve Mokris Date: Sun, 4 Sep 2022 14:40:27 -0400 Subject: [PATCH 05/10] plugins: vfork is deprecated on macOS --- src/node/inetd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/inetd.c b/src/node/inetd.c index d7dd6a1..b765518 100644 --- a/src/node/inetd.c +++ b/src/node/inetd.c @@ -19,7 +19,7 @@ #include #include -#if !(defined(HAVE_WORKING_VFORK) || defined(S_SPLINT_S)) +#if !(defined(HAVE_WORKING_VFORK) || defined(S_SPLINT_S)) || defined(__APPLE__) #define vfork fork #endif From a22624af5899f71b331e0c4383d5019bdb1aa900 Mon Sep 17 00:00:00 2001 From: Steve Mokris Date: Sun, 4 Sep 2022 20:45:40 -0400 Subject: [PATCH 06/10] plugins: first macOS version of plugins --- configure.ac | 22 +- src/plugins/Makefile.am | 32 +-- src/plugins/common.c | 10 + src/plugins/common.h | 3 + src/plugins/cpu-sysctl.c | 189 ------------------ src/plugins/p/cpu-darwin.c | 65 ++++++ src/plugins/p/{cpu.c => cpu-proc.c} | 0 src/plugins/p/df-bsd.c | 82 ++++++++ src/plugins/p/{df.c => df-sunos.c} | 16 -- src/plugins/p/entropy-darwin.c | 15 ++ src/plugins/p/{entropy.c => entropy-proc.c} | 0 src/plugins/p/forks-darwin.c | 39 ++++ src/plugins/p/{forks.c => forks-proc.c} | 0 src/plugins/p/fw_packets-darwin.c | 99 +++++++++ .../p/{fw_packets.c => fw_packets-proc.c} | 0 src/plugins/p/if_err_-darwin.c | 120 +++++++++++ src/plugins/p/{if_err_.c => if_err_-proc.c} | 0 src/plugins/p/interrupts-darwin.c | 15 ++ .../p/{interrupts.c => interrupts-proc.c} | 0 src/plugins/p/iostat-darwin.c | 119 +++++++++++ src/plugins/p/{iostat.c => iostat-proc.c} | 0 src/plugins/p/{load-sysctl.c => load-bsd.c} | 0 .../{memory-sysctl.c => p/memory-bsd.c} | 0 src/plugins/p/memory-darwin.c | 82 ++++++++ src/plugins/p/{memory.c => memory-proc.c} | 0 src/plugins/p/open_files-darwin.c | 73 +++++++ .../p/{open_files.c => open_files-proc.c} | 0 src/plugins/p/open_inodes-darwin.c | 15 ++ .../p/{open_inodes.c => open_inodes-proc.c} | 0 src/plugins/p/processes-darwin.c | 51 +++++ .../p/{processes.c => processes-proc.c} | 0 src/plugins/p/swap-darwin.c | 52 +++++ src/plugins/p/{swap.c => swap-proc.c} | 0 src/plugins/p/threads-darwin.c | 56 ++++++ src/plugins/p/{threads.c => threads-proc.c} | 0 src/plugins/p/uptime-darwin.c | 45 +++++ src/plugins/p/{uptime.c => uptime-proc.c} | 0 37 files changed, 976 insertions(+), 224 deletions(-) delete mode 100644 src/plugins/cpu-sysctl.c create mode 100644 src/plugins/p/cpu-darwin.c rename src/plugins/p/{cpu.c => cpu-proc.c} (100%) create mode 100644 src/plugins/p/df-bsd.c rename src/plugins/p/{df.c => df-sunos.c} (93%) create mode 100644 src/plugins/p/entropy-darwin.c rename src/plugins/p/{entropy.c => entropy-proc.c} (100%) create mode 100644 src/plugins/p/forks-darwin.c rename src/plugins/p/{forks.c => forks-proc.c} (100%) create mode 100644 src/plugins/p/fw_packets-darwin.c rename src/plugins/p/{fw_packets.c => fw_packets-proc.c} (100%) create mode 100644 src/plugins/p/if_err_-darwin.c rename src/plugins/p/{if_err_.c => if_err_-proc.c} (100%) create mode 100644 src/plugins/p/interrupts-darwin.c rename src/plugins/p/{interrupts.c => interrupts-proc.c} (100%) create mode 100644 src/plugins/p/iostat-darwin.c rename src/plugins/p/{iostat.c => iostat-proc.c} (100%) rename src/plugins/p/{load-sysctl.c => load-bsd.c} (100%) rename src/plugins/{memory-sysctl.c => p/memory-bsd.c} (100%) create mode 100644 src/plugins/p/memory-darwin.c rename src/plugins/p/{memory.c => memory-proc.c} (100%) create mode 100644 src/plugins/p/open_files-darwin.c rename src/plugins/p/{open_files.c => open_files-proc.c} (100%) create mode 100644 src/plugins/p/open_inodes-darwin.c rename src/plugins/p/{open_inodes.c => open_inodes-proc.c} (100%) create mode 100644 src/plugins/p/processes-darwin.c rename src/plugins/p/{processes.c => processes-proc.c} (100%) create mode 100644 src/plugins/p/swap-darwin.c rename src/plugins/p/{swap.c => swap-proc.c} (100%) create mode 100644 src/plugins/p/threads-darwin.c rename src/plugins/p/{threads.c => threads-proc.c} (100%) create mode 100644 src/plugins/p/uptime-darwin.c rename src/plugins/p/{uptime.c => uptime-proc.c} (100%) diff --git a/configure.ac b/configure.ac index 74cbb9e..4873799 100644 --- a/configure.ac +++ b/configure.ac @@ -17,13 +17,29 @@ AM_MAINTAINER_MODE([enable]) AC_CANONICAL_HOST case $host in - *bsd* | *darwin* ) - SYS_API='sysctl' ;; + *bsd* ) + SYS_API='bsd' + DF_API='bsd' + LOAD_API='bsd' + ;; + *darwin* ) + # macOS (Darwin/XNU) is mostly-BSD-compatible, but has some deviations. + SYS_API='darwin' + DF_API='bsd' + LOAD_API='bsd' + LDFLAGS+='-framework CoreFoundation -framework IOKit' + ;; *) - SYS_API='proc' ;; + # Linux takes APIs from a variety of sources. + SYS_API='proc' + DF_API='sunos' + LOAD_API='bsd' + ;; esac AC_SUBST([SYS_API]) +AC_SUBST([DF_API]) +AC_SUBST([LOAD_API]) AC_PROG_CC AC_PROG_CC_C_O diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index 365d75c..9b61c8f 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -15,23 +15,23 @@ munin_plugins_c_SOURCES = \ common.c \ common.h \ plugins.h \ - p/cpu.c \ - p/df.c \ - p/entropy.c \ + p/cpu-$(SYS_API).c \ + p/df-$(DF_API).c \ + p/entropy-$(SYS_API).c \ p/external_.c \ - p/forks.c \ - p/fw_packets.c \ - p/if_err_.c \ - p/interrupts.c \ - p/iostat.c \ - p/load-$(SYS_API).c \ - p/open_files.c \ - p/open_inodes.c \ - p/processes.c \ - p/swap.c \ - p/threads.c \ - p/memory.c \ - p/uptime.c \ + p/forks-$(SYS_API).c \ + p/fw_packets-$(SYS_API).c \ + p/if_err_-$(SYS_API).c \ + p/interrupts-$(SYS_API).c \ + p/iostat-$(SYS_API).c \ + p/load-$(LOAD_API).c \ + p/memory-$(SYS_API).c \ + p/open_files-$(SYS_API).c \ + p/open_inodes-$(SYS_API).c \ + p/processes-$(SYS_API).c \ + p/swap-$(SYS_API).c \ + p/threads-$(SYS_API).c \ + p/uptime-$(SYS_API).c \ main.c man_MANS = munin-plugins-c.1 CLEANFILES = $(man_MANS) diff --git a/src/plugins/common.c b/src/plugins/common.c index b5eaf95..6c87c41 100644 --- a/src/plugins/common.c +++ b/src/plugins/common.c @@ -22,6 +22,16 @@ int writeyes(void) return 0; } +int unsupported(int argc, char **argv) +{ + if (argc > 1) { + if (!strcmp(argv[1], "autoconf")) + puts("no"); + } + + return 0; +} + int autoconf_check_readable(const char *path) { if (0 == access(path, R_OK)) diff --git a/src/plugins/common.h b/src/plugins/common.h index 34ca054..4dc2b04 100644 --- a/src/plugins/common.h +++ b/src/plugins/common.h @@ -15,6 +15,9 @@ * @returns a success state to be passed on as the return value from main */ int writeyes(void); +/** Indicates that the plugin cannot produce output on the current platform. */ +int unsupported(int argc, char **argv); + /** Answer an autoconf request by checking the readability of the given file. */ int autoconf_check_readable(const char *); diff --git a/src/plugins/cpu-sysctl.c b/src/plugins/cpu-sysctl.c deleted file mode 100644 index 3ea6ead..0000000 --- a/src/plugins/cpu-sysctl.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (C) 2015 Steve Schnepp - All rights reserved. - * - * This copyrighted material is made available to anyone wishing to use, - * modify, copy, or redistribute it subject to the terms and conditions - * of the GNU General Public License v.2 or v.3. - */ -#include -#include -#include -#include -#include -#include -#include "common.h" -#include "plugins.h" - -#define SYSWARNING 30 -#define SYSCRITICAL 50 -#define USRWARNING 80 - -/* TODO: port support for env.foo_warning and env.foo_critical from mainline plugin */ - -static int print_stat_value(const char* field_name, const char* stat_value, int hz_) { - return printf("%s.value %llu\n", field_name, strtoull(stat_value, NULL, 0) * 100 / hz_); -} - -int cpu(int argc, char **argv) { - FILE *f; - char buff[256], *s; - int ncpu=0, extinfo=0, hz_; - bool scaleto100 = false; - if(argc > 1) { - if(!strcmp(argv[1], "config")) { - s = getenv("scaleto100"); - if(s && !strcmp(s, "yes")) - scaleto100 = true; - - if(!(f=fopen(PROC_STAT, "r"))) - return fail("cannot open " PROC_STAT); - while(fgets(buff, 256, f)) { - if(!strncmp(buff, "cpu", 3)) { - if(isdigit(buff[3])) - ncpu++; - if(buff[3] == ' ' && 0 == extinfo) { - strtok(buff+4, " \t"); - for(extinfo=1;strtok(NULL, " \t");extinfo++) - ; - } - } - } - fclose(f); - - if(ncpu < 1 || extinfo < 4) - return fail("cannot parse " PROC_STAT); - - puts("graph_title CPU usage"); - if(extinfo >= 7) - puts("graph_order system user nice idle iowait irq softirq"); - else - puts("graph_order system user nice idle"); - if(scaleto100) - puts("graph_args --base 1000 -r --lower-limit 0 --upper-limit 100"); - else - printf("graph_args --base 1000 -r --lower-limit 0 --upper-limit %d\n", 100 * ncpu); - puts("graph_vlabel %\n" - "graph_scale no\n" - "graph_info This graph shows how CPU time is spent.\n" - "graph_category system\n" - "graph_period second\n" - "system.label system\n" - "system.draw AREA"); - printf("system.max %d\n", 100 * ncpu); - puts("system.min 0\n" - "system.type DERIVE"); - printf("system.warning %d\n", SYSWARNING * ncpu); - printf("system.critical %d\n", SYSCRITICAL * ncpu); - puts("system.info CPU time spent by the kernel in system activities\n" - "user.label user\n" - "user.draw STACK\n" - "user.min 0"); - printf("user.max %d\n", 100 * ncpu); - printf("user.warning %d\n", USRWARNING * ncpu); - puts("user.type DERIVE\n" - "user.info CPU time spent by normal programs and daemons\n" - "nice.label nice\n" - "nice.draw STACK\n" - "nice.min 0"); - printf("nice.max %d\n", 100 * ncpu); - puts("nice.type DERIVE\n" - "nice.info CPU time spent by nice(1)d programs\n" - "idle.label idle\n" - "idle.draw STACK\n" - "idle.min 0"); - printf("idle.max %d\n", 100 * ncpu); - puts("idle.type DERIVE\n" - "idle.info Idle CPU time"); - if(scaleto100) - printf("system.cdef system,%d,/\n" - "user.cdef user,%d,/\n" - "nice.cdef nice,%d,/\n" - "idle.cdef idle,%d,/\n", ncpu, ncpu, ncpu, ncpu); - if(extinfo >= 7) { - puts("iowait.label iowait\n" - "iowait.draw STACK\n" - "iowait.min 0"); - printf("iowait.max %d\n", 100 * ncpu); - puts("iowait.type DERIVE\n" - "iowait.info CPU time spent waiting for I/O operations to finish\n" - "irq.label irq\n" - "irq.draw STACK\n" - "irq.min 0"); - printf("irq.max %d\n", 100 * ncpu); - puts("irq.type DERIVE\n" - "irq.info CPU time spent handling interrupts\n" - "softirq.label softirq\n" - "softirq.draw STACK\n" - "softirq.min 0"); - printf("softirq.max %d\n", 100 * ncpu); - puts("softirq.type DERIVE\n" - "softirq.info CPU time spent handling \"batched\" interrupts"); - if(scaleto100) - printf("iowait.cdef iowait,%d,/\n" - "irq.cdef irq,%d,/\n" - "softirq.cdef softirq,%d,/\n", ncpu, ncpu, ncpu); - } - if(extinfo >= 8) { - puts("steal.label steal\n" - "steal.draw STACK\n" - "steal.min 0"); - printf("steal.max %d\n", 100 * ncpu); - puts("steal.type DERIVE\n" - "steal.info The time that a virtual CPU had runnable tasks, but the virtual CPU itself was not running"); - if(scaleto100) - printf("steal.cdef steal,%d,/\n", ncpu); - } - if(extinfo >= 9) { - puts("guest.label guest\n" - "guest.draw STACK\n" - "guest.min 0"); - printf("guest.max %d\n", 100 * ncpu); - puts("guest.type DERIVE\n" - "guest.info The time spent running a virtual CPU for guest operating systems under the control of the Linux kernel."); - if(scaleto100) - printf("guest.cdef guest,%d,/\n", ncpu); - } - return 0; - } - if(!strcmp(argv[1], "autoconf")) - return autoconf_check_readable(PROC_STAT); - } - if(!(f=fopen(PROC_STAT, "r"))) - return fail("cannot open " PROC_STAT); - hz_ = getenvint("HZ", 100); - while(fgets(buff, 256, f)) { - if(!strncmp(buff, "cpu ", 4)) { - fclose(f); - if(!(s = strtok(buff+4, " \t"))) - break; - print_stat_value("user", s, hz_); - if(!(s = strtok(NULL, " \t"))) - break; - print_stat_value("nice", s, hz_); - if(!(s = strtok(NULL, " \t"))) - break; - print_stat_value("system", s, hz_); - if(!(s = strtok(NULL, " \t"))) - break; - print_stat_value("idle", s, hz_); - if(!(s = strtok(NULL, " \t"))) - return 0; - print_stat_value("iowait", s, hz_); - if(!(s = strtok(NULL, " \t"))) - return 0; - print_stat_value("irq", s, hz_); - if(!(s = strtok(NULL, " \t"))) - return 0; - print_stat_value("softirq", s, hz_); - if(!(s = strtok(NULL, " \t"))) - return 0; - print_stat_value("steal", s, hz_); - if(!(s = strtok(NULL, " \t"))) - return 0; - print_stat_value("guest", s, hz_); - return 0; - } - } - fclose(f); - return fail("no cpu line found in " PROC_STAT); -} diff --git a/src/plugins/p/cpu-darwin.c b/src/plugins/p/cpu-darwin.c new file mode 100644 index 0000000..064c786 --- /dev/null +++ b/src/plugins/p/cpu-darwin.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2015 Steve Schnepp - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include "common.h" +#include "plugins.h" + +int cpu(int argc, char **argv) { + if(argc > 1) { + if(!strcmp(argv[1], "config")) { + puts("graph_title CPU usage\n" + "graph_args --base 1000 -r --lower-limit 0 --upper-limit 100\n" + "graph_vlabel %\n" + "graph_scale no\n" + "graph_info This graph shows how CPU time is spent.\n" + "graph_category system\n" + "graph_period second\n" + + "system.label system\n" + "system.type DERIVE\n" + "system.draw AREA\n" + "system.info CPU time spent by the kernel in system activities\n" + + "user.label user\n" + "user.type DERIVE\n" + "user.draw STACK\n" + "user.info CPU time spent by normal programs and daemons\n" + + "nice.label nice\n" + "nice.type DERIVE\n" + "nice.draw STACK\n" + "nice.info CPU time spent by nice(1)d programs\n" + + "idle.label idle\n" + "idle.type DERIVE\n" + "idle.draw STACK\n" + "idle.info Idle CPU time"); + + return 0; + } + if(!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + host_t host = mach_host_self(); + host_cpu_load_info_data_t li; + mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT; + if (host_statistics(host, HOST_CPU_LOAD_INFO, (host_info_t)&li, &count) != KERN_SUCCESS) { + return fail("host_statistics"); + } + + printf("system.value %lu\n", li.cpu_ticks[CPU_STATE_SYSTEM]); + printf("user.value %lu\n", li.cpu_ticks[CPU_STATE_USER]); + printf("nice.value %lu\n", li.cpu_ticks[CPU_STATE_NICE]); + printf("idle.value %lu\n", li.cpu_ticks[CPU_STATE_IDLE]); + + return 0; +} diff --git a/src/plugins/p/cpu.c b/src/plugins/p/cpu-proc.c similarity index 100% rename from src/plugins/p/cpu.c rename to src/plugins/p/cpu-proc.c diff --git a/src/plugins/p/df-bsd.c b/src/plugins/p/df-bsd.c new file mode 100644 index 0000000..659bcf6 --- /dev/null +++ b/src/plugins/p/df-bsd.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2017 Bastiaan van Kesteren - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#define _DARWIN_FEATURE_64_BIT_INODE + +#include +#include +#include +#include "common.h" +#include "plugins.h" + +static int should_show(struct statfs mount) +{ + return !(mount.f_flags & MNT_RDONLY) + && strcmp(mount.f_fstypename, "autofs") != 0 + && strcmp(mount.f_fstypename, "devfs") != 0 + && strcmp(mount.f_mntonname, "/System/Volumes/Hardware") != 0 + && strcmp(mount.f_mntonname, "/System/Volumes/iSCPreboot") != 0 + && strcmp(mount.f_mntonname, "/System/Volumes/Preboot") != 0 + && strcmp(mount.f_mntonname, "/System/Volumes/Update") != 0 + && strcmp(mount.f_mntonname, "/System/Volumes/VM") != 0 + && strcmp(mount.f_mntonname, "/System/Volumes/xarts") != 0; +} + +static char *replace_slash(char *c) +{ + char *p = c; + + while (*p) { + if (*p == '/') { + *p = '_'; + } + p++; + } + return c; +} + +int df(int argc, char **argv) +{ + struct statfs *mounts; + int mountCount = getmntinfo(&mounts, MNT_NOWAIT); + + if (argc > 1) { + if (!strcmp(argv[1], "config")) { + puts("graph_title Disk usage in percent\n" + "graph_args --lower-limit 0 --upper-limit 100\n" + "graph_vlabel %\n" + "graph_scale no\n" + "graph_category disk"); + + for (int i = 0; i < mountCount; ++i) { + if (!should_show(mounts[i])) + continue; + + char *safeName = replace_slash(strdup(mounts[i].f_mntonname)); + printf("%s.label %s\n" + "%s.info %s\n", + safeName, mounts[i].f_mntonname, + safeName, mounts[i].f_fstypename); + } + + return 0; + } + if (!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + for (int i = 0; i < mountCount; ++i) { + if (!should_show(mounts[i])) + continue; + + printf("%s.value %lf\n", replace_slash(mounts[i].f_mntonname), + (100.0 / mounts[i].f_blocks) * (mounts[i].f_blocks - mounts[i].f_bfree)); + } + + return 0; +} diff --git a/src/plugins/p/df.c b/src/plugins/p/df-sunos.c similarity index 93% rename from src/plugins/p/df.c rename to src/plugins/p/df-sunos.c index b2ced05..7ff2ab0 100644 --- a/src/plugins/p/df.c +++ b/src/plugins/p/df-sunos.c @@ -10,11 +10,7 @@ #include #include #include - -#ifdef HAVE_MNTENT_H #include /* for getmntent(), et al. */ -#endif - #include /* for getopt() */ #include @@ -34,17 +30,6 @@ #define CGROUP_SUPER_MAGIC 0x27e0eb #define DEVPTS_SUPER_MAGIC 0x1cd1 - -#ifndef HAVE_MNTENT_H -int df(int argc, char **argv) -{ - if (argc && argv) { - /* Do nothing, but silence the warnings */ - } - return fail("getmntent() is not supported on your system"); -} -#else - static char *replace_slash(char *c) { char *p = c; @@ -143,4 +128,3 @@ int df(int argc, char **argv) return 0; } -#endif diff --git a/src/plugins/p/entropy-darwin.c b/src/plugins/p/entropy-darwin.c new file mode 100644 index 0000000..0b46936 --- /dev/null +++ b/src/plugins/p/entropy-darwin.c @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2008-13 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include "common.h" +#include "plugins.h" + +int entropy(int argc, char **argv) +{ + return unsupported(argc, argv); +} diff --git a/src/plugins/p/entropy.c b/src/plugins/p/entropy-proc.c similarity index 100% rename from src/plugins/p/entropy.c rename to src/plugins/p/entropy-proc.c diff --git a/src/plugins/p/forks-darwin.c b/src/plugins/p/forks-darwin.c new file mode 100644 index 0000000..89ea899 --- /dev/null +++ b/src/plugins/p/forks-darwin.c @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2008-2013 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include "common.h" +#include "plugins.h" + +int forks(int argc, char **argv) +{ + if (argc > 1) { + if (!strcmp(argv[1], "config")) { + puts("graph_title Fork rate\n" + "graph_args --base 1000 -l 0\n" + "graph_vlabel forks / ${graph_period}\n" + "graph_category processes\n" + "graph_info This graph shows the forking rate (new processes started).\n" + "forks.label forks\n" + "forks.type DERIVE\n" + "forks.min 0\n" + "forks.max 100000\n" + "forks.info The number of forks per second."); + print_warncrit("forks"); + return 0; + } + if (!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + printf("forks.value %d\n", getpid()); + + return 0; +} diff --git a/src/plugins/p/forks.c b/src/plugins/p/forks-proc.c similarity index 100% rename from src/plugins/p/forks.c rename to src/plugins/p/forks-proc.c diff --git a/src/plugins/p/fw_packets-darwin.c b/src/plugins/p/fw_packets-darwin.c new file mode 100644 index 0000000..1973e18 --- /dev/null +++ b/src/plugins/p/fw_packets-darwin.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2008-2013 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "plugins.h" + +int fw_packets(int argc, char **argv) +{ + if (argc > 1) { + if (!strcmp(argv[1], "config")) { + puts("graph_title Firewall Throughput\n" + "graph_args --base 1000 -l 0\n" + "graph_vlabel Packets/${graph_period}\n" + "graph_category network\n" + "received.label Received\n" + "received.graph no\n" + "received.type DERIVE\n" + "received.min 0\n" + "sent.label Sent\n" + "sent.draw AREA\n" + "sent.type DERIVE\n" + "sent.negative received\n" + "sent.min 0"); + return 0; + } + if (!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + int mib[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 }; + size_t bufferSize; + if (sysctl(mib, 6, NULL, &bufferSize, NULL, 0) != 0) + return 1; + + char *interfaces = malloc(bufferSize); + if (sysctl(mib, 6, interfaces, &bufferSize, NULL, 0) != 0) + return 1; + + uint64_t receivedSum = 0; + uint64_t sentSum = 0; + char *interfacesStart = interfaces; + while (interfaces < interfacesStart + bufferSize) { + struct if_msghdr *header = (struct if_msghdr *)interfaces; + if (header->ifm_type != RTM_IFINFO + || !(header->ifm_flags & IFF_UP) + || !(header->ifm_flags & IFF_RUNNING) + || header->ifm_flags & IFF_LOOPBACK + || header->ifm_flags & IFF_POINTOPOINT) + goto next; + + struct if_data *ifdata = &header->ifm_data; + if (ifdata->ifi_type != IFT_ETHER) + goto next; + + struct sockaddr_dl *sdl = (struct sockaddr_dl *)(header + 1); + char *name = strndup(sdl->sdl_data, sdl->sdl_nlen); + + int sockfd; + if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) + return 1; + + struct ifmediareq ifmr; + bzero(&ifmr, sizeof(ifmr)); + strcpy(ifmr.ifm_name, name); + if (ioctl(sockfd, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) + return 1; + + if ((ifmr.ifm_status & IFM_AVALID) && !(ifmr.ifm_status & IFM_ACTIVE)) + goto next; + + receivedSum += ifdata->ifi_ipackets; + sentSum += ifdata->ifi_opackets; + +next: + interfaces += header->ifm_msglen; + } + + printf("received.value %lu\n", receivedSum); + printf("sent.value %lu\n", sentSum); + + return 0; +} diff --git a/src/plugins/p/fw_packets.c b/src/plugins/p/fw_packets-proc.c similarity index 100% rename from src/plugins/p/fw_packets.c rename to src/plugins/p/fw_packets-proc.c diff --git a/src/plugins/p/if_err_-darwin.c b/src/plugins/p/if_err_-darwin.c new file mode 100644 index 0000000..04afb85 --- /dev/null +++ b/src/plugins/p/if_err_-darwin.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2008-2013 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "plugins.h" + +int if_err_(int argc, char **argv) +{ + char *interface = basename(argv[0]); + if (strncmp(interface, "if_err_", 7) != 0) + return fail("if_err_ invoked with invalid basename"); + interface += 7; + + int mib[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 }; + size_t bufferSize; + if (sysctl(mib, 6, NULL, &bufferSize, NULL, 0) != 0) + return 1; + + char *interfaces = malloc(bufferSize); + if (sysctl(mib, 6, interfaces, &bufferSize, NULL, 0) != 0) + return 1; + + char *interfacesStart = interfaces; + + if (argc > 1) { + if (!strcmp(argv[1], "autoconf")) + return writeyes(); + if (!strcmp(argv[1], "suggest")) { + while (interfaces < interfacesStart + bufferSize) { + struct if_msghdr *header = (struct if_msghdr *)interfaces; + if (header->ifm_type != RTM_IFINFO + || !(header->ifm_flags & IFF_UP) + || !(header->ifm_flags & IFF_RUNNING) + || header->ifm_flags & IFF_LOOPBACK + || header->ifm_flags & IFF_POINTOPOINT) + goto next; + + struct if_data *ifdata = &header->ifm_data; + if (ifdata->ifi_type != IFT_ETHER) + goto next; + + struct sockaddr_dl *sdl = (struct sockaddr_dl *)(header + 1); + char *name = strndup(sdl->sdl_data, sdl->sdl_nlen); + + int sockfd; + if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) + return 1; + + struct ifmediareq ifmr; + bzero(&ifmr, sizeof(ifmr)); + strcpy(ifmr.ifm_name, name); + if (ioctl(sockfd, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) + return 1; + + if ((ifmr.ifm_status & IFM_AVALID) && !(ifmr.ifm_status & IFM_ACTIVE)) + goto next; + + puts(name); + +next: + interfaces += header->ifm_msglen; + } + return 0; + } + if (!strcmp(argv[1], "config")) { + puts("graph_order rcvd trans"); + printf("graph_title %s errors\n", interface); + puts("graph_args --base 1000\n" + "graph_vlabel packets in (-) / out (+) per " + "${graph_period}\n" "graph_category network"); + printf("graph_info This graph shows the amount of " + "errors on the %s network interface.\n", + interface); + puts("rcvd.label packets\n" + "rcvd.type COUNTER\n" + "rcvd.graph no\n" + "rcvd.warning 1\n" + "trans.label packets\n" + "trans.type COUNTER\n" + "trans.negative rcvd\n" "trans.warning 1"); + print_warncrit("rcvd"); + print_warncrit("trans"); + return 0; + } + } + + while (interfaces < interfacesStart + bufferSize) { + struct if_msghdr *header = (struct if_msghdr *)interfaces; + struct if_data *ifdata = &header->ifm_data; + struct sockaddr_dl *sdl = (struct sockaddr_dl *)(header + 1); + char *name = strndup(sdl->sdl_data, sdl->sdl_nlen); + if (strcmp(name, interface) != 0) + goto next2; + + printf("rcvd.value %lu\n", ifdata->ifi_ierrors); + printf("trans.value %lu\n", ifdata->ifi_oerrors); + +next2: + interfaces += header->ifm_msglen; + } + + + return 0; +} diff --git a/src/plugins/p/if_err_.c b/src/plugins/p/if_err_-proc.c similarity index 100% rename from src/plugins/p/if_err_.c rename to src/plugins/p/if_err_-proc.c diff --git a/src/plugins/p/interrupts-darwin.c b/src/plugins/p/interrupts-darwin.c new file mode 100644 index 0000000..92f596e --- /dev/null +++ b/src/plugins/p/interrupts-darwin.c @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2008-13 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include "common.h" +#include "plugins.h" + +int interrupts(int argc, char **argv) +{ + return unsupported(argc, argv); +} diff --git a/src/plugins/p/interrupts.c b/src/plugins/p/interrupts-proc.c similarity index 100% rename from src/plugins/p/interrupts.c rename to src/plugins/p/interrupts-proc.c diff --git a/src/plugins/p/iostat-darwin.c b/src/plugins/p/iostat-darwin.c new file mode 100644 index 0000000..8c0afe1 --- /dev/null +++ b/src/plugins/p/iostat-darwin.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2018 Michal Sojka - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include +#include +#include "common.h" +#include "plugins.h" + +typedef void (*deviceCallback)(char *name, uint64_t reads, uint64_t writes); +static void enumerateDevices(deviceCallback cb); +static void enumerateDevice(void *context, io_iterator_t drivelist); +static void configCallback(char *name, uint64_t reads, uint64_t writes); +static void fetchCallback(char *name, uint64_t reads, uint64_t writes); + +int iostat(int argc, char **argv) +{ + if (argc > 1) { + if (!strcmp(argv[1], "config")) { + puts("graph_title IOstat\n" + "graph_args --base 1024\n" + "graph_vlabel blocks per ${graph_period} read (-) / written (+)\n" + "graph_category disk\n" + "graph_info This graph shows the I/O to and from block devices."); + + enumerateDevices(configCallback); + return 0; + } + if (!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + enumerateDevices(fetchCallback); + return 0; +} + +static void enumerateDevices(deviceCallback cb) +{ + io_iterator_t drivelist; + CFMutableDictionaryRef match = IOServiceMatching("IOMedia"); + CFDictionaryAddValue(match, CFSTR(kIOMediaWholeKey), kCFBooleanTrue); + IONotificationPortRef notifyPort = IONotificationPortCreate(kIOMainPortDefault); + if (IOServiceAddMatchingNotification(notifyPort, kIOFirstMatchNotification, match, &enumerateDevice, (void *)cb, &drivelist) != KERN_SUCCESS) + return; + + enumerateDevice((void *)cb, drivelist); +} + +static void enumerateDevice(void *context, io_iterator_t drivelist) +{ + deviceCallback cb = (deviceCallback)context; + io_registry_entry_t drive; + while ((drive = IOIteratorNext(drivelist))) { + io_registry_entry_t parent; + if (IORegistryEntryGetParentEntry(drive, kIOServicePlane, &parent) != KERN_SUCCESS) + continue; + + if (!IOObjectConformsTo(parent, "IOBlockStorageDriver")) + continue; + + CFDictionaryRef properties; + if (IORegistryEntryCreateCFProperties(drive, (CFMutableDictionaryRef *)&properties, kCFAllocatorDefault, kNilOptions) != KERN_SUCCESS) + continue; + + CFStringRef name = (CFStringRef)CFDictionaryGetValue(properties, CFSTR(kIOBSDNameKey)); + if (!name) + continue; + + CFIndex length = CFStringGetLength(name); + CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8); + char *nameZ = (char *)malloc(maxSize); + CFStringGetCString(name, nameZ, maxSize, kCFStringEncodingUTF8); + + CFDictionaryRef parentProperties; + if (IORegistryEntryCreateCFProperties(parent, (CFMutableDictionaryRef *)&parentProperties, kCFAllocatorDefault, kNilOptions) != KERN_SUCCESS) + continue; + + CFDictionaryRef statistics = (CFDictionaryRef)CFDictionaryGetValue(parentProperties, CFSTR(kIOBlockStorageDriverStatisticsKey)); + if (!statistics) + continue; + + CFNumberRef number; + uint64_t reads = 0; + if ((number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsReadsKey)))) + CFNumberGetValue(number, kCFNumberSInt64Type, &reads); + + uint64_t writes = 0; + if ((number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsWritesKey)))) + CFNumberGetValue(number, kCFNumberSInt64Type, &writes); + + cb(nameZ, reads, writes); + } +} + +void configCallback(char *name, __attribute__((unused)) uint64_t reads, __attribute__((unused)) uint64_t writes) +{ + printf("%s_read.label %s\n", name, name); + printf("%s_read.type DERIVE\n", name); + printf("%s_read.min 0\n", name); + printf("%s_read.graph no\n", name); + printf("%s_write.label %s\n", name, name); + printf("%s_write.info I/O on device %s\n", name, name); + printf("%s_write.type DERIVE\n", name); + printf("%s_write.min 0\n", name); + printf("%s_write.negative %s_read\n", name, name); +} + +void fetchCallback(char *name, uint64_t reads, uint64_t writes) +{ + printf("%s_read.value %lu\n", name, reads); + printf("%s_write.value %lu\n", name, writes); +} diff --git a/src/plugins/p/iostat.c b/src/plugins/p/iostat-proc.c similarity index 100% rename from src/plugins/p/iostat.c rename to src/plugins/p/iostat-proc.c diff --git a/src/plugins/p/load-sysctl.c b/src/plugins/p/load-bsd.c similarity index 100% rename from src/plugins/p/load-sysctl.c rename to src/plugins/p/load-bsd.c diff --git a/src/plugins/memory-sysctl.c b/src/plugins/p/memory-bsd.c similarity index 100% rename from src/plugins/memory-sysctl.c rename to src/plugins/p/memory-bsd.c diff --git a/src/plugins/p/memory-darwin.c b/src/plugins/p/memory-darwin.c new file mode 100644 index 0000000..9e00c59 --- /dev/null +++ b/src/plugins/p/memory-darwin.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2015 Steve Schnepp - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include +#include "common.h" +#include "plugins.h" + +int memory(int argc, char **argv) { + + if(argc > 1) { + if(!strcmp(argv[1], "config")) { + puts("graph_vlabel Bytes\n" + "graph_args --base 1024 -l 0\n" + "graph_title Memory usage\n" + "graph_category system\n" + "graph_info This graph shows what the machine uses memory for.\n" + + "wired.label Wired\n" + "wired.draw AREA\n" + "wired.info Nonswappable memory used by the kernel.\n" + + "active.label Active\n" + "active.draw STACK\n" + "active.info Recently-accessed memory.\n" + + "inactive.label Inactive\n" + "inactive.draw STACK\n" + "inactive.info Memory likely to be purged or swapped out.\n" + + "speculative.label Speculative\n" + "speculative.draw STACK\n" + "speculative.info File-backed/mmapped memory, speculatively read and cached.\n" + + "other.label Other\n" + "other.draw STACK\n" + + "free.label free\n" + "free.draw STACK\n" + "free.info Available for immediate use."); + + return 0; + } + if(!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + uint32_t pagesize; + size_t len = sizeof(pagesize); + if (sysctlbyname("vm.pagesize", &pagesize, &len, NULL, 0) < 0) { + return fail("sysctlbyname"); + } + + uint32_t totalPages; + len = sizeof(totalPages); + if (sysctlbyname("vm.pages", &totalPages, &len, NULL, 0) < 0) { + return fail("sysctlbyname"); + } + + struct vm_statistics64 stats; + host_t host = mach_host_self(); + mach_msg_type_number_t count = HOST_VM_INFO64_COUNT; + if (host_statistics64(host, HOST_VM_INFO64, (host_info64_t)&stats, &count) != KERN_SUCCESS) { + return fail("host_statistics64"); + } + + printf("wired.value %lu\n", stats.wire_count * pagesize); + printf("active.value %lu\n", stats.active_count * pagesize); + printf("inactive.value %lu\n", stats.inactive_count * pagesize); + printf("speculative.value %lu\n", stats.speculative_count * pagesize); + printf("other.value %lu\n", ((int64_t)totalPages - stats.wire_count - stats.active_count - stats.inactive_count - stats.free_count) * pagesize); + printf("free.value %lu\n", (stats.free_count - stats.speculative_count) * pagesize); + + return 0; +} diff --git a/src/plugins/p/memory.c b/src/plugins/p/memory-proc.c similarity index 100% rename from src/plugins/p/memory.c rename to src/plugins/p/memory-proc.c diff --git a/src/plugins/p/open_files-darwin.c b/src/plugins/p/open_files-darwin.c new file mode 100644 index 0000000..48a73db --- /dev/null +++ b/src/plugins/p/open_files-darwin.c @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2008-2013 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "plugins.h" + +int open_files(int argc, char **argv) +{ + if (argc > 1) { + if (!strcmp(argv[1], "config")) { + puts("graph_title File table usage\n" + "graph_args --base 1000 -l 0\n" + "graph_vlabel number of open files\n" + "graph_category system\n" + "graph_info This graph monitors the Linux open files table.\n" + "used.label open files\n" + "used.info The number of currently open files.\n" + "max.label max open files\n" + "max.info The maximum supported number of open files."); + return 0; + } + if (!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + uint32_t maxproc; + size_t len = sizeof(maxproc); + if (sysctlbyname("kern.maxproc", &maxproc, &len, NULL, 0) < 0) { + return fail("sysctlbyname"); + } + + uint32_t maxfiles; + len = sizeof(maxfiles); + if (sysctlbyname("kern.maxfiles", &maxfiles, &len, NULL, 0) < 0) { + return fail("sysctlbyname"); + } + + size_t pidBufferSize = sizeof(pid_t) * maxproc; + pid_t *pids = malloc(pidBufferSize); + uint32_t pidCount = proc_listallpids(pids, pidBufferSize); + + uint64_t sum = 0; + for (uint32_t i = 0; i < pidCount; ++i) { + int bufferSize; + if ((bufferSize = proc_pidinfo(pids[i], PROC_PIDLISTFDS, 0, NULL, 0)) < 0) { + return fail("proc_pidinfo"); + } + + struct proc_fdinfo *pfi = malloc(bufferSize); + if ((bufferSize = proc_pidinfo(pids[i], PROC_PIDLISTFDS, 0, pfi, bufferSize)) < 0) { + return fail("proc_pidinfo"); + } + sum += bufferSize / PROC_PIDLISTFD_SIZE; + } + + printf("used.value %lu\n" + "max.value %lu\n", + sum, + maxfiles); + + return 0; +} diff --git a/src/plugins/p/open_files.c b/src/plugins/p/open_files-proc.c similarity index 100% rename from src/plugins/p/open_files.c rename to src/plugins/p/open_files-proc.c diff --git a/src/plugins/p/open_inodes-darwin.c b/src/plugins/p/open_inodes-darwin.c new file mode 100644 index 0000000..4a73037 --- /dev/null +++ b/src/plugins/p/open_inodes-darwin.c @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2008-13 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include "common.h" +#include "plugins.h" + +int open_inodes(int argc, char **argv) +{ + return unsupported(argc, argv); +} diff --git a/src/plugins/p/open_inodes.c b/src/plugins/p/open_inodes-proc.c similarity index 100% rename from src/plugins/p/open_inodes.c rename to src/plugins/p/open_inodes-proc.c diff --git a/src/plugins/p/processes-darwin.c b/src/plugins/p/processes-darwin.c new file mode 100644 index 0000000..337f046 --- /dev/null +++ b/src/plugins/p/processes-darwin.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2008-13 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "plugins.h" + +/* TODO: The upstream plugin does way more nowawdays. */ + +int processes(int argc, char **argv) +{ + if (argc > 1) { + if (!strcmp(argv[1], "config")) { + puts("graph_title Number of Processes\n" + "graph_args --base 1000 -l 0 \n" + "graph_vlabel number of processes\n" + "graph_category processes\n" + "graph_info This graph shows the number of processes in the system.\n" + "processes.label processes\n" + "processes.draw LINE2\n" + "processes.info The current number of processes."); + return 0; + } + if (!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + uint32_t maxproc; + size_t len = sizeof(maxproc); + if (sysctlbyname("kern.maxproc", &maxproc, &len, NULL, 0) < 0) { + return fail("sysctlbyname"); + } + + size_t pidBufferSize = sizeof(pid_t) * maxproc; + pid_t *pids = malloc(pidBufferSize); + uint32_t pidCount = proc_listallpids(pids, pidBufferSize); + + printf("processes.value %u\n", pidCount); + + return 0; +} diff --git a/src/plugins/p/processes.c b/src/plugins/p/processes-proc.c similarity index 100% rename from src/plugins/p/processes.c rename to src/plugins/p/processes-proc.c diff --git a/src/plugins/p/swap-darwin.c b/src/plugins/p/swap-darwin.c new file mode 100644 index 0000000..9209288 --- /dev/null +++ b/src/plugins/p/swap-darwin.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2008-13 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include "common.h" +#include "plugins.h" + +int swap(int argc, char **argv) +{ + if (argc > 1) { + if (!strcmp(argv[1], "config")) { + puts("graph_title Swap in/out\n" + "graph_args -l 0 --base 1000\n" + "graph_vlabel pages per ${graph_period} in (-) / out (+)\n" + "graph_category system\n" + "swap_in.label swap\n" + "swap_in.type DERIVE\n" + "swap_in.max 100000\n" + "swap_in.min 0\n" + "swap_in.graph no\n" + "swap_out.label swap\n" + "swap_out.type DERIVE\n" + "swap_out.max 100000\n" + "swap_out.min 0\n" + "swap_out.negative swap_in"); + print_warncrit("swap_in"); + print_warncrit("swap_out"); + return 0; + } + if (!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + struct vm_statistics64 stats; + host_t host = mach_host_self(); + mach_msg_type_number_t count = HOST_VM_INFO64_COUNT; + if (host_statistics64(host, HOST_VM_INFO64, (host_info64_t)&stats, &count) != KERN_SUCCESS) { + return fail("host_statistics64"); + } + + printf("swap_in.value %lu\n", stats.swapins); + printf("swap_out.value %lu\n", stats.swapouts); + + return 0; +} diff --git a/src/plugins/p/swap.c b/src/plugins/p/swap-proc.c similarity index 100% rename from src/plugins/p/swap.c rename to src/plugins/p/swap-proc.c diff --git a/src/plugins/p/threads-darwin.c b/src/plugins/p/threads-darwin.c new file mode 100644 index 0000000..2bdeb12 --- /dev/null +++ b/src/plugins/p/threads-darwin.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2008-2013 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "plugins.h" + +int threads(int argc, char **argv) +{ + if (argc > 1) { + if (!strcmp(argv[1], "config")) { + puts("graph_title Number of threads\n" + "graph_vlabel number of threads\n" + "graph_category processes\n" + "graph_info This graph shows the number of threads.\n" + "threads.label threads\n" + "threads.info The current number of threads."); + return 0; + } + if(!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + uint32_t maxproc; + size_t len = sizeof(maxproc); + if (sysctlbyname("kern.maxproc", &maxproc, &len, NULL, 0) < 0) { + return fail("sysctlbyname"); + } + + uint64_t sum = 0; + size_t pidBufferSize = sizeof(pid_t) * maxproc; + pid_t *pids = malloc(pidBufferSize); + uint32_t pidCount = proc_listallpids(pids, pidBufferSize); + + for (uint32_t i = 0; i < pidCount; ++i) { + struct proc_taskinfo pti; + if (proc_pidinfo(pids[i], PROC_PIDTASKINFO, 0, &pti, sizeof(pti)) < 0) { + return fail("proc_pidinfo"); + } + sum += pti.pti_threadnum; + } + + printf("threads.value %llu\n", sum); + + return 0; +} diff --git a/src/plugins/p/threads.c b/src/plugins/p/threads-proc.c similarity index 100% rename from src/plugins/p/threads.c rename to src/plugins/p/threads-proc.c diff --git a/src/plugins/p/uptime-darwin.c b/src/plugins/p/uptime-darwin.c new file mode 100644 index 0000000..c59d957 --- /dev/null +++ b/src/plugins/p/uptime-darwin.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2008-2013 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include "common.h" +#include "plugins.h" + +int uptime(int argc, char **argv) +{ + if (argc > 1) { + if (!strcmp(argv[1], "config")) { + puts("graph_title Uptime\n" + "graph_args --base 1000 -l 0 \n" + "graph_vlabel uptime in days\n" + "graph_category system\n" + "uptime.label uptime\n" "uptime.draw AREA"); + print_warncrit("uptime"); + return 0; + } + if (!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + struct timeval now; + if (gettimeofday(&now, NULL) < 0) { + return fail("gettimeofday"); + } + + setutxent(); + struct utmpx *ute; + while ((ute = getutxent())) { + if (ute->ut_type == BOOT_TIME) { + printf("uptime.value %.2f\n", (float)(now.tv_sec - ute->ut_tv.tv_sec) / 86400); + } + } + + return 0; +} diff --git a/src/plugins/p/uptime.c b/src/plugins/p/uptime-proc.c similarity index 100% rename from src/plugins/p/uptime.c rename to src/plugins/p/uptime-proc.c From 724b6bca93a5eef91ca24264832591235bdddd13 Mon Sep 17 00:00:00 2001 From: Steve Mokris Date: Tue, 6 Sep 2022 20:00:21 -0400 Subject: [PATCH 07/10] plugins: more BSD plugins --- configure.ac | 45 +++++++- src/plugins/Makefile.am | 13 ++- src/plugins/p/cpu-bsd.c | 72 ++++++++++++ ...entropy-darwin.c => entropy-unsupported.c} | 0 src/plugins/p/forks-bsd.c | 52 +++++++++ src/plugins/p/fw_packets-unsupported.c | 18 +++ src/plugins/p/if_err_-unsupported.c | 18 +++ ...upts-darwin.c => interrupts-unsupported.c} | 0 src/plugins/p/iostat-unsupported.c | 15 +++ src/plugins/p/load-bsd.c | 3 +- src/plugins/p/memory-bsd.c | 106 +++++++----------- src/plugins/p/open_files-bsd.c | 54 +++++++++ ...des-darwin.c => open_inodes-unsupported.c} | 0 src/plugins/p/processes-bsd.c | 47 ++++++++ src/plugins/p/swap-bsd.c | 55 +++++++++ src/plugins/p/threads-bsd.c | 47 ++++++++ src/plugins/p/uptime-bsd.c | 46 ++++++++ 17 files changed, 514 insertions(+), 77 deletions(-) create mode 100644 src/plugins/p/cpu-bsd.c rename src/plugins/p/{entropy-darwin.c => entropy-unsupported.c} (100%) create mode 100644 src/plugins/p/forks-bsd.c create mode 100644 src/plugins/p/fw_packets-unsupported.c create mode 100644 src/plugins/p/if_err_-unsupported.c rename src/plugins/p/{interrupts-darwin.c => interrupts-unsupported.c} (100%) create mode 100644 src/plugins/p/iostat-unsupported.c create mode 100644 src/plugins/p/open_files-bsd.c rename src/plugins/p/{open_inodes-darwin.c => open_inodes-unsupported.c} (100%) create mode 100644 src/plugins/p/processes-bsd.c create mode 100644 src/plugins/p/swap-bsd.c create mode 100644 src/plugins/p/threads-bsd.c create mode 100644 src/plugins/p/uptime-bsd.c diff --git a/configure.ac b/configure.ac index 4873799..6d6e6c8 100644 --- a/configure.ac +++ b/configure.ac @@ -19,27 +19,64 @@ AC_CANONICAL_HOST case $host in *bsd* ) SYS_API='bsd' + DF_API='bsd' + ENTROPY_API='unsupported' + FW_PACKETS_API='unsupported' + IF_ERR_API='unsupported' + INTERRUPTS_API='unsupported' + IOSTAT_API='unsupported' LOAD_API='bsd' + OPEN_INODES_API='unsupported' + + LDFLAGS='-lkvm' ;; + *darwin* ) - # macOS (Darwin/XNU) is mostly-BSD-compatible, but has some deviations. SYS_API='darwin' + + # macOS (Darwin/XNU) is mostly-BSD-compatible, but has some deviations. DF_API='bsd' + ENTROPY_API='unsupported' + FW_PACKETS_API='darwin' + IF_ERR_API='darwin' + INTERRUPTS_API='unsupported' + IOSTAT_API='darwin' LOAD_API='bsd' - LDFLAGS+='-framework CoreFoundation -framework IOKit' + OPEN_INODES_API='unsupported' + + LDFLAGS='-framework CoreFoundation -framework IOKit' ;; + *) - # Linux takes APIs from a variety of sources. SYS_API='proc' + + # Linux takes APIs from a variety of sources. DF_API='sunos' - LOAD_API='bsd' + ENTROPY_API='proc' + FW_PACKETS_API='proc' + IF_ERR_API='proc' + INTERRUPTS_API='proc' + IOSTAT_API='proc' + LOAD_API='proc' + OPEN_INODES_API='proc' + + LDFLAGS='' ;; esac AC_SUBST([SYS_API]) + AC_SUBST([DF_API]) +AC_SUBST([ENTROPY_API]) +AC_SUBST([FW_PACKETS_API]) +AC_SUBST([IF_ERR_API]) +AC_SUBST([INTERRUPTS_API]) +AC_SUBST([IOSTAT_API]) AC_SUBST([LOAD_API]) +AC_SUBST([OPEN_INODES_API]) + +AC_SUBST([LDFLAGS]) AC_PROG_CC AC_PROG_CC_C_O diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index 9b61c8f..d57e5e3 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -17,22 +17,23 @@ munin_plugins_c_SOURCES = \ plugins.h \ p/cpu-$(SYS_API).c \ p/df-$(DF_API).c \ - p/entropy-$(SYS_API).c \ + p/entropy-$(ENTROPY_API).c \ p/external_.c \ p/forks-$(SYS_API).c \ - p/fw_packets-$(SYS_API).c \ - p/if_err_-$(SYS_API).c \ - p/interrupts-$(SYS_API).c \ - p/iostat-$(SYS_API).c \ + p/fw_packets-$(FW_PACKETS_API).c \ + p/if_err_-$(IF_ERR_API).c \ + p/interrupts-$(INTERRUPTS_API).c \ + p/iostat-$(IOSTAT_API).c \ p/load-$(LOAD_API).c \ p/memory-$(SYS_API).c \ p/open_files-$(SYS_API).c \ - p/open_inodes-$(SYS_API).c \ + p/open_inodes-$(INTERRUPTS_API).c \ p/processes-$(SYS_API).c \ p/swap-$(SYS_API).c \ p/threads-$(SYS_API).c \ p/uptime-$(SYS_API).c \ main.c +munin_plugins_c_LDADD = $(LDFLAGS) man_MANS = munin-plugins-c.1 CLEANFILES = $(man_MANS) EXTRA_DIST = munin-plugins-c.pod diff --git a/src/plugins/p/cpu-bsd.c b/src/plugins/p/cpu-bsd.c new file mode 100644 index 0000000..4f69abe --- /dev/null +++ b/src/plugins/p/cpu-bsd.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2015 Steve Schnepp - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include +#include +#include "common.h" +#include "plugins.h" + +int cpu(int argc, char **argv) { + if(argc > 1) { + if(!strcmp(argv[1], "config")) { + puts("graph_title CPU usage\n" + "graph_args --base 1000 -r --lower-limit 0 --upper-limit 100\n" + "graph_vlabel %\n" + "graph_scale no\n" + "graph_info This graph shows how CPU time is spent.\n" + "graph_category system\n" + "graph_period second\n" + + "intr.label intr\n" + "intr.type DERIVE\n" + "intr.draw AREA\n" + "intr.info CPU time spent by the kernel in interrupt handlers\n" + + "system.label system\n" + "system.type DERIVE\n" + "system.draw AREA\n" + "system.info CPU time spent by the kernel in system activities\n" + + "user.label user\n" + "user.type DERIVE\n" + "user.draw STACK\n" + "user.info CPU time spent by normal programs and daemons\n" + + "nice.label nice\n" + "nice.type DERIVE\n" + "nice.draw STACK\n" + "nice.info CPU time spent by nice(1)d programs\n" + + "idle.label idle\n" + "idle.type DERIVE\n" + "idle.draw STACK\n" + "idle.info Idle CPU time"); + + return 0; + } + if(!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + long cputicks[CPUSTATES]; + size_t len = sizeof(cputicks); + if (sysctlbyname("kern.cp_time", &cputicks, &len, NULL, 0) < 0) { + return fail("sysctlbyname"); + } + + printf("intr.value %lu\n", cputicks[CP_INTR]); + printf("system.value %lu\n", cputicks[CP_SYS]); + printf("user.value %lu\n", cputicks[CP_USER]); + printf("nice.value %lu\n", cputicks[CP_NICE]); + printf("idle.value %lu\n", cputicks[CP_IDLE]); + + return 0; +} diff --git a/src/plugins/p/entropy-darwin.c b/src/plugins/p/entropy-unsupported.c similarity index 100% rename from src/plugins/p/entropy-darwin.c rename to src/plugins/p/entropy-unsupported.c diff --git a/src/plugins/p/forks-bsd.c b/src/plugins/p/forks-bsd.c new file mode 100644 index 0000000..a8aa34f --- /dev/null +++ b/src/plugins/p/forks-bsd.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2008-2013 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include +#include "common.h" +#include "plugins.h" + +int forks(int argc, char **argv) +{ + if (argc > 1) { + if (!strcmp(argv[1], "config")) { + puts("graph_title Fork rate\n" + "graph_args --base 1000 -l 0\n" + "graph_vlabel forks / ${graph_period}\n" + "graph_category processes\n" + "graph_info This graph shows the forking rate (new processes started).\n" + "forks.label forks\n" + "forks.type DERIVE\n" + "forks.min 0\n" + "forks.max 100000\n" + "forks.info The number of forks per second."); + print_warncrit("forks"); + return 0; + } + if (!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + u_long forks, vforks, rforks; + size_t len = sizeof(u_long); + if (sysctlbyname("vm.stats.vm.v_forks", &forks, &len, NULL, 0) < 0) { + return fail("sysctlbyname"); + } + if (sysctlbyname("vm.stats.vm.v_vforks", &vforks, &len, NULL, 0) < 0) { + return fail("sysctlbyname"); + } + if (sysctlbyname("vm.stats.vm.v_rforks", &rforks, &len, NULL, 0) < 0) { + return fail("sysctlbyname"); + } + + printf("forks.value %d\n", forks + vforks + rforks); + + return 0; +} diff --git a/src/plugins/p/fw_packets-unsupported.c b/src/plugins/p/fw_packets-unsupported.c new file mode 100644 index 0000000..d80d76b --- /dev/null +++ b/src/plugins/p/fw_packets-unsupported.c @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2008-2013 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include "common.h" +#include "plugins.h" + +int fw_packets(int argc, char **argv) +{ + return unsupported(argc, argv); +} diff --git a/src/plugins/p/if_err_-unsupported.c b/src/plugins/p/if_err_-unsupported.c new file mode 100644 index 0000000..daafa97 --- /dev/null +++ b/src/plugins/p/if_err_-unsupported.c @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2008-2013 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include "common.h" +#include "plugins.h" + +int if_err_(int argc, char **argv) +{ + return unsupported(argc, argv); +} diff --git a/src/plugins/p/interrupts-darwin.c b/src/plugins/p/interrupts-unsupported.c similarity index 100% rename from src/plugins/p/interrupts-darwin.c rename to src/plugins/p/interrupts-unsupported.c diff --git a/src/plugins/p/iostat-unsupported.c b/src/plugins/p/iostat-unsupported.c new file mode 100644 index 0000000..1b5cea5 --- /dev/null +++ b/src/plugins/p/iostat-unsupported.c @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2008-13 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include "common.h" +#include "plugins.h" + +int iostat(int argc, char **argv) +{ + return unsupported(argc, argv); +} diff --git a/src/plugins/p/load-bsd.c b/src/plugins/p/load-bsd.c index ca4d751..1c3f1ae 100644 --- a/src/plugins/p/load-bsd.c +++ b/src/plugins/p/load-bsd.c @@ -11,8 +11,9 @@ #include #include #include -#include +#include #include +#include #include "common.h" #include "plugins.h" diff --git a/src/plugins/p/memory-bsd.c b/src/plugins/p/memory-bsd.c index 07fb433..601bf61 100644 --- a/src/plugins/p/memory-bsd.c +++ b/src/plugins/p/memory-bsd.c @@ -6,8 +6,6 @@ * of the GNU General Public License v.2 or v.3. */ -/* This plugin is compatible with munin-mainline version 2.0.25. */ - #include #include #include @@ -16,91 +14,67 @@ #include "common.h" #include "plugins.h" -#include - int memory(int argc, char **argv) { - if(argc > 1) { if(!strcmp(argv[1], "config")) { - printf( + puts( "graph_vlabel Bytes\n" "graph_args --base 1024 -l 0\n" "graph_title Memory usage\n" "graph_category system\n" "graph_info This graph shows what the machine uses memory for.\n" - ); - printf("apps.label apps\n"); - printf("apps.draw AREA\n"); - printf("apps.info Memory used by user-space applications.\n"); - - printf("free.label free\n"); - printf("free.draw STACK\n"); - printf("free.info Wasted memory. Memory that is not used for anything at all.\n"); - - printf("swap.label swap\n"); - printf("swap.draw STACK\n"); - printf("swap.info Swap space used.\n"); - - -if [ "$1" = "config" ]; then - echo 'graph_args --base 1024 -l 0 --vertical-label Bytes --upper-limit' $MEMMAX - echo 'graph_title Memory usage' - echo 'graph_category system' - echo 'graph_info This graph shows what the machine uses its memory for.' - echo 'graph_order active inactive wired cached free swap buffers' - echo 'active.label active' - echo 'active.info pages recently statistically used' - echo 'active.draw AREA' - echo 'inactive.label inactive' - echo 'inactive.info pages recently statistically unused' - echo 'inactive.draw STACK' - echo 'wired.label wired' - echo 'wired.info pages that are fixed into memory, usually for kernel purposes, but also sometimes for special use in processes' - echo 'wired.draw STACK' - echo 'cached.label cache' - echo 'cached.info pages that have percolated from inactive to a status where they maintain their data, but can often be immediately reused' - echo 'cached.draw STACK' - echo 'free.label free' - echo 'free.info pages without data content' - echo 'free.draw STACK' - echo 'swap.label swap' - echo 'swap.info Swap space used' - echo 'swap.draw STACK' - echo 'buffers.label buffers' - echo 'buffers.info pages used for filesystem buffers' - echo 'buffers.draw LINE' - exit 0 -fi - - - + "wired.label wired\n" + "wired.info pages that are fixed into memory for the kernel\n" + "wired.draw AREA\n" + // "user_wired.label user_wired\n" + // "user_wired.info pages that are fixed into memory for user processes\n" + // "user_wired.draw STACK\n" + "active.label active\n" + "active.info pages recently statistically used\n" + "active.draw STACK\n" + "inactive.label inactive\n" + "inactive.info pages recently statistically unused\n" + "inactive.draw STACK\n" + "cached.label cache\n" + "cached.info pages that have percolated from inactive to a status where they maintain their data, but can often be immediately reused\n" + "cached.draw STACK\n" + "laundry.label laundry\n" + "laundry.info pages to be swapped out to disk\n" + "laundry.draw STACK\n" + "free.label free\n" + "free.info pages without data content\n" + "free.draw STACK\n" + ); return 0; } if(!strcmp(argv[1], "autoconf")) return writeyes(); } - struct vmtotal s; - size_t len = sizeof(s); - - if (sysctlbyname("vm.total", &s, &len, NULL, 0) < 0) { - return fail("sysctl"); - } - - double ldavg = l.ldavg[0]; - double fscale = l.fscale; - - printf("# vm.loadavg, ldavg:%f fscale:%f -", ldavg, fscale); - printf("\n"); + size_t len = sizeof(u_long); + u_long v_page_size; if (sysctlbyname("vm.stats.vm.v_page_size", &v_page_size, &len, NULL, 0) < 0) return fail("sysctlbyname v_page_size"); + u_long v_wire_count; if (sysctlbyname("vm.stats.vm.v_wire_count", &v_wire_count, &len, NULL, 0) < 0) return fail("sysctlbyname v_wire_count"); + // u_long v_user_wire_count; if (sysctlbyname("vm.stats.vm.v_user_wire_count", &v_user_wire_count, &len, NULL, 0) < 0) return fail("sysctlbyname v_user_wire_count"); + u_long v_active_count; if (sysctlbyname("vm.stats.vm.v_active_count", &v_active_count, &len, NULL, 0) < 0) return fail("sysctlbyname v_active_count"); + u_long v_inactive_count; if (sysctlbyname("vm.stats.vm.v_inactive_count", &v_inactive_count, &len, NULL, 0) < 0) return fail("sysctlbyname v_inactive_count"); + u_long v_cache_count; if (sysctlbyname("vm.stats.vm.v_cache_count", &v_cache_count, &len, NULL, 0) < 0) return fail("sysctlbyname v_cache_count"); + u_long v_laundry_count; if (sysctlbyname("vm.stats.vm.v_laundry_count", &v_laundry_count, &len, NULL, 0) < 0) return fail("sysctlbyname v_laundry_count"); + u_long v_free_count; if (sysctlbyname("vm.stats.vm.v_free_count", &v_free_count, &len, NULL, 0) < 0) return fail("sysctlbyname v_free_count"); + + printf("wired.value %u\n", v_wire_count * v_page_size); + // printf("user_wired.value %u\n", v_user_wire_count * v_page_size); + printf("active.value %u\n", v_active_count * v_page_size); + printf("inactive.value %u\n", v_inactive_count * v_page_size); + printf("cached.value %u\n", v_cache_count * v_page_size); + printf("laundry.value %u\n", v_laundry_count * v_page_size); + printf("free.value %u\n", v_free_count * v_page_size); - double load_1 = ldavg / fscale; - printf("load.value %.2f\n", load_1); return 0; } diff --git a/src/plugins/p/open_files-bsd.c b/src/plugins/p/open_files-bsd.c new file mode 100644 index 0000000..e5443cc --- /dev/null +++ b/src/plugins/p/open_files-bsd.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2008-2013 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include +#include +#include "common.h" +#include "plugins.h" + +int open_files(int argc, char **argv) +{ + if (argc > 1) { + if (!strcmp(argv[1], "config")) { + puts("graph_title File table usage\n" + "graph_args --base 1000 -l 0\n" + "graph_vlabel number of open files\n" + "graph_category system\n" + "graph_info This graph monitors the Linux open files table.\n" + "used.label open files\n" + "used.info The number of currently open files.\n" + "max.label max open files\n" + "max.info The maximum supported number of open files."); + return 0; + } + if (!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + uint32_t maxfiles; + size_t len = sizeof(maxfiles); + if (sysctlbyname("kern.maxfiles", &maxfiles, &len, NULL, 0) < 0) { + return fail("sysctlbyname"); + } + + uint32_t openfiles; + len = sizeof(openfiles); + if (sysctlbyname("kern.openfiles", &openfiles, &len, NULL, 0) < 0) { + return fail("sysctlbyname"); + } + + printf("used.value %lu\n" + "max.value %lu\n", + openfiles, + maxfiles); + + return 0; +} diff --git a/src/plugins/p/open_inodes-darwin.c b/src/plugins/p/open_inodes-unsupported.c similarity index 100% rename from src/plugins/p/open_inodes-darwin.c rename to src/plugins/p/open_inodes-unsupported.c diff --git a/src/plugins/p/processes-bsd.c b/src/plugins/p/processes-bsd.c new file mode 100644 index 0000000..d05cddf --- /dev/null +++ b/src/plugins/p/processes-bsd.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2008-13 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "plugins.h" + +/* TODO: The upstream plugin does way more nowawdays. */ + +int processes(int argc, char **argv) +{ + if (argc > 1) { + if (!strcmp(argv[1], "config")) { + puts("graph_title Number of Processes\n" + "graph_args --base 1000 -l 0 \n" + "graph_vlabel number of processes\n" + "graph_category processes\n" + "graph_info This graph shows the number of processes in the system.\n" + "processes.label processes\n" + "processes.draw LINE2\n" + "processes.info The current number of processes."); + return 0; + } + if (!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + kvm_t *kd = kvm_open(NULL, NULL, NULL, 0, NULL); + if (!kd) + return 1; + + int processCount = 0; + kvm_getprocs(kd, KERN_PROC_PROC, 0, &processCount); + printf("processes.value %u\n", processCount); + + return 0; +} diff --git a/src/plugins/p/swap-bsd.c b/src/plugins/p/swap-bsd.c new file mode 100644 index 0000000..759fde8 --- /dev/null +++ b/src/plugins/p/swap-bsd.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2008-13 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include +#include "common.h" +#include "plugins.h" + +int swap(int argc, char **argv) +{ + if (argc > 1) { + if (!strcmp(argv[1], "config")) { + puts("graph_title Swap in/out\n" + "graph_args -l 0 --base 1000\n" + "graph_vlabel pages per ${graph_period} in (-) / out (+)\n" + "graph_category system\n" + "swap_in.label swap\n" + "swap_in.type DERIVE\n" + "swap_in.max 100000\n" + "swap_in.min 0\n" + "swap_in.graph no\n" + "swap_out.label swap\n" + "swap_out.type DERIVE\n" + "swap_out.max 100000\n" + "swap_out.min 0\n" + "swap_out.negative swap_in"); + print_warncrit("swap_in"); + print_warncrit("swap_out"); + return 0; + } + if (!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + u_long v_swappgsout, v_swappgsin; + size_t len = sizeof(u_long); + if (sysctlbyname("vm.stats.vm.v_swappgsout", &v_swappgsout, &len, NULL, 0) < 0) { + return fail("sysctlbyname"); + } + if (sysctlbyname("vm.stats.vm.v_swappgsin", &v_swappgsin, &len, NULL, 0) < 0) { + return fail("sysctlbyname"); + } + + printf("swap_in.value %lu\n", v_swappgsin); + printf("swap_out.value %lu\n", v_swappgsout); + + return 0; +} diff --git a/src/plugins/p/threads-bsd.c b/src/plugins/p/threads-bsd.c new file mode 100644 index 0000000..73de40f --- /dev/null +++ b/src/plugins/p/threads-bsd.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2008-13 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "plugins.h" + +int threads(int argc, char **argv) +{ + if (argc > 1) { + if (!strcmp(argv[1], "config")) { + puts("graph_title Number of threads\n" + "graph_vlabel number of threads\n" + "graph_category processes\n" + "graph_info This graph shows the number of threads.\n" + "threads.label threads\n" + "threads.info The current number of threads."); + return 0; + } + if (!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + kvm_t *kd = kvm_open(NULL, NULL, NULL, 0, NULL); + if (!kd) + return 1; + + int processAndThreadCount = 0; + kvm_getprocs(kd, KERN_PROC_ALL, 0, &processAndThreadCount); + + int processCount = 0; + kvm_getprocs(kd, KERN_PROC_PROC, 0, &processCount); + + printf("threads.value %u\n", processAndThreadCount - processCount); + + return 0; +} diff --git a/src/plugins/p/uptime-bsd.c b/src/plugins/p/uptime-bsd.c new file mode 100644 index 0000000..7b65d59 --- /dev/null +++ b/src/plugins/p/uptime-bsd.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008-2013 Helmut Grohne - All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2 or v.3. + */ + +#include +#include +#include +#include +#include "common.h" +#include "plugins.h" + +int uptime(int argc, char **argv) +{ + if (argc > 1) { + if (!strcmp(argv[1], "config")) { + puts("graph_title Uptime\n" + "graph_args --base 1000 -l 0 \n" + "graph_vlabel uptime in days\n" + "graph_category system\n" + "uptime.label uptime\n" "uptime.draw AREA"); + print_warncrit("uptime"); + return 0; + } + if (!strcmp(argv[1], "autoconf")) + return writeyes(); + } + + struct timeval now; + if (gettimeofday(&now, NULL) < 0) { + return fail("gettimeofday"); + } + + struct timeval bootTime; + size_t len = sizeof(bootTime); + if (sysctlbyname("kern.boottime", &bootTime, &len, NULL, 0) < 0) { + return fail("sysctlbyname"); + } + + printf("uptime.value %.2f\n", (float)(now.tv_sec - bootTime.tv_sec) / 86400); + + return 0; +} From 0f3296318fc94ea53e635aed3dc06ecf76d503b5 Mon Sep 17 00:00:00 2001 From: Steve Mokris Date: Fri, 9 Sep 2022 11:33:50 -0400 Subject: [PATCH 08/10] plugins: fix macOS 'other' memory calculation --- src/plugins/p/memory-darwin.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/plugins/p/memory-darwin.c b/src/plugins/p/memory-darwin.c index 9e00c59..1f23793 100644 --- a/src/plugins/p/memory-darwin.c +++ b/src/plugins/p/memory-darwin.c @@ -42,7 +42,7 @@ int memory(int argc, char **argv) { "other.label Other\n" "other.draw STACK\n" - "free.label free\n" + "free.label Free\n" "free.draw STACK\n" "free.info Available for immediate use."); @@ -75,8 +75,10 @@ int memory(int argc, char **argv) { printf("active.value %lu\n", stats.active_count * pagesize); printf("inactive.value %lu\n", stats.inactive_count * pagesize); printf("speculative.value %lu\n", stats.speculative_count * pagesize); - printf("other.value %lu\n", ((int64_t)totalPages - stats.wire_count - stats.active_count - stats.inactive_count - stats.free_count) * pagesize); - printf("free.value %lu\n", (stats.free_count - stats.speculative_count) * pagesize); + + int64_t freePages = stats.free_count - stats.speculative_count; + printf("other.value %lu\n", ((int64_t)totalPages - stats.wire_count - stats.active_count - stats.inactive_count - freePages) * pagesize); + printf("free.value %lu\n", freePages * pagesize); return 0; } From b63257b5d3e56ed721b8d6f4aac796d0eb4a84fe Mon Sep 17 00:00:00 2001 From: Steve Mokris Date: Sun, 11 Sep 2022 18:04:29 -0400 Subject: [PATCH 09/10] plugins: scale macOS CPU counters by number of CPUs, limit to 0 --- src/plugins/p/cpu-darwin.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/plugins/p/cpu-darwin.c b/src/plugins/p/cpu-darwin.c index 064c786..d4669e7 100644 --- a/src/plugins/p/cpu-darwin.c +++ b/src/plugins/p/cpu-darwin.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "common.h" #include "plugins.h" @@ -24,21 +25,25 @@ int cpu(int argc, char **argv) { "graph_period second\n" "system.label system\n" + "system.min 0\n" "system.type DERIVE\n" "system.draw AREA\n" "system.info CPU time spent by the kernel in system activities\n" "user.label user\n" + "user.min 0\n" "user.type DERIVE\n" "user.draw STACK\n" "user.info CPU time spent by normal programs and daemons\n" "nice.label nice\n" + "nice.min 0\n" "nice.type DERIVE\n" "nice.draw STACK\n" "nice.info CPU time spent by nice(1)d programs\n" "idle.label idle\n" + "idle.min 0\n" "idle.type DERIVE\n" "idle.draw STACK\n" "idle.info Idle CPU time"); @@ -49,6 +54,12 @@ int cpu(int argc, char **argv) { return writeyes(); } + unsigned int cpuCount; + size_t len = sizeof(cpuCount); + if (sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0) < 0) { + return fail("sysctlbyname"); + } + host_t host = mach_host_self(); host_cpu_load_info_data_t li; mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT; @@ -56,10 +67,10 @@ int cpu(int argc, char **argv) { return fail("host_statistics"); } - printf("system.value %lu\n", li.cpu_ticks[CPU_STATE_SYSTEM]); - printf("user.value %lu\n", li.cpu_ticks[CPU_STATE_USER]); - printf("nice.value %lu\n", li.cpu_ticks[CPU_STATE_NICE]); - printf("idle.value %lu\n", li.cpu_ticks[CPU_STATE_IDLE]); + printf("system.value %lu\n", li.cpu_ticks[CPU_STATE_SYSTEM] / cpuCount); + printf("user.value %lu\n", li.cpu_ticks[CPU_STATE_USER] / cpuCount); + printf("nice.value %lu\n", li.cpu_ticks[CPU_STATE_NICE] / cpuCount); + printf("idle.value %lu\n", li.cpu_ticks[CPU_STATE_IDLE] / cpuCount); return 0; } From 7b2914a47b08307d5ec0e7efb4ac25a4422c580d Mon Sep 17 00:00:00 2001 From: Steve Mokris Date: Sun, 11 Sep 2022 18:58:51 -0400 Subject: [PATCH 10/10] plugins: try again to fix macOS 'other' memory calculation --- src/plugins/p/memory-darwin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/p/memory-darwin.c b/src/plugins/p/memory-darwin.c index 1f23793..498ff14 100644 --- a/src/plugins/p/memory-darwin.c +++ b/src/plugins/p/memory-darwin.c @@ -77,7 +77,7 @@ int memory(int argc, char **argv) { printf("speculative.value %lu\n", stats.speculative_count * pagesize); int64_t freePages = stats.free_count - stats.speculative_count; - printf("other.value %lu\n", ((int64_t)totalPages - stats.wire_count - stats.active_count - stats.inactive_count - freePages) * pagesize); + printf("other.value %lu\n", MAX(0, (int64_t)totalPages - stats.wire_count - stats.active_count - stats.inactive_count - freePages) * pagesize); printf("free.value %lu\n", freePages * pagesize); return 0;