diff --git a/common.am b/common.am index 8686f90..7ee063d 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)#' $@ + sed -i '' -e 's#@@pkglibexecdir@@#$(pkglibexecdir)#' -e 's#@@CONFDIR@@#$(sysconfdir)#' $@ +SUFFIXES = .1 .pod # vim:ft=make diff --git a/configure.ac b/configure.ac index d50fbc5..6d6e6c8 100644 --- a/configure.ac +++ b/configure.ac @@ -15,6 +15,69 @@ 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* ) + 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* ) + 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' + OPEN_INODES_API='unsupported' + + LDFLAGS='-framework CoreFoundation -framework IOKit' + ;; + + *) + SYS_API='proc' + + # Linux takes APIs from a variety of sources. + DF_API='sunos' + 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/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/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 diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index 603d602..d57e5e3 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -15,24 +15,25 @@ 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-$(ENTROPY_API).c \ p/external_.c \ - p/forks.c \ - p/fw_packets.c \ - p/if_err_.c \ - p/interrupts.c \ - p/iostat.c \ - p/load.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-$(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-$(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/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/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/cpu-darwin.c b/src/plugins/p/cpu-darwin.c new file mode 100644 index 0000000..d4669e7 --- /dev/null +++ b/src/plugins/p/cpu-darwin.c @@ -0,0 +1,76 @@ +/* + * 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 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.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"); + + return 0; + } + if(!strcmp(argv[1], "autoconf")) + 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; + 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] / 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; +} 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.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/entropy-unsupported.c b/src/plugins/p/entropy-unsupported.c new file mode 100644 index 0000000..0b46936 --- /dev/null +++ b/src/plugins/p/entropy-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 entropy(int argc, char **argv) +{ + return unsupported(argc, argv); +} 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/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/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_-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/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.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/interrupts-unsupported.c b/src/plugins/p/interrupts-unsupported.c new file mode 100644 index 0000000..92f596e --- /dev/null +++ b/src/plugins/p/interrupts-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 interrupts(int argc, char **argv) +{ + return unsupported(argc, argv); +} 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/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 new file mode 100644 index 0000000..1c3f1ae --- /dev/null +++ b/src/plugins/p/load-bsd.c @@ -0,0 +1,56 @@ +/* + * 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 +#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; +} 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/memory-bsd.c b/src/plugins/p/memory-bsd.c new file mode 100644 index 0000000..601bf61 --- /dev/null +++ b/src/plugins/p/memory-bsd.c @@ -0,0 +1,80 @@ +/* + * 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 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.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(); + } + + 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); + + return 0; +} diff --git a/src/plugins/p/memory-darwin.c b/src/plugins/p/memory-darwin.c new file mode 100644 index 0000000..498ff14 --- /dev/null +++ b/src/plugins/p/memory-darwin.c @@ -0,0 +1,84 @@ +/* + * 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); + + int64_t freePages = stats.free_count - stats.speculative_count; + 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; +} 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-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_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.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/open_inodes-unsupported.c b/src/plugins/p/open_inodes-unsupported.c new file mode 100644 index 0000000..4a73037 --- /dev/null +++ b/src/plugins/p/open_inodes-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 open_inodes(int argc, char **argv) +{ + return unsupported(argc, argv); +} 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/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-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/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-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/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-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; +} 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