mnc,mpc: move them to own repo

This commit is contained in:
Steve Schnepp 2013-03-02 20:22:46 +01:00
parent e5ceabe428
commit 2e03d0c551
21 changed files with 5 additions and 1220 deletions

View File

@ -1,24 +0,0 @@
CC=gcc
CFLAGS=-W -Wall -pedantic -Wextra -g -O2
OBJS=main.o
LINKS=
%.o: %.c
${CC} ${CFLAGS} -c $< -o $@
all: munin-node-c
munin-node-c: ${OBJS}
${CC} ${CFLAGS} $^ -o $@
clean:
rm -f munin-node-c ${OBJS} ${LINKS}
rm -Rf plugins
plugins: plugins/.munin-plugins-busybox.installed
plugins/.munin-plugins-busybox.installed:
mkdir -p plugins
cd ../munin-plugins-busybox && $(MAKE)
cd plugins && for i in $$(find ../../munin-plugins-busybox -type l); do ln -s $$i; done
touch plugins/.munin-plugins-busybox.installed
.PHONY: all clean plugins

View File

@ -1,28 +1,5 @@
This is a rewrite of munin node in C.
Pro:
----
It has moved together with munin-plugins-c to its own repo:
The purpose is multiple:
* reducing resource usage for embedded plateforms, specially when paired
with the C rewrite of the core plugins.
* no need for Perl
* Everything runs from inetd.
Cons:
-----
* You lose flexibility
It is compiled code, so you have to create binaries. Even one for each
architecture.
* Not all the features are implemented
- root uid is not supported. All plugins are run with a single user, usually nobody.
- no socket is opened. Everything runs from inetd.
GPLv2 - (C) 2013 Steve SCHNEPP <steve.schnepp@pwkf.org>
munin-c.git

View File

@ -1,145 +0,0 @@
#include <libgen.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <limits.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <dirent.h>
char VERSION[] = "1.0.0";
int verbose = 0;
char* host = "";
char* plugin_dir = "plugins";
char* spoolfetch_dir = "";
int main(int argc, char *argv[]) {
int optch;
extern int opterr;
int optarg_len;
char format[] = "vd:h:s:";
char line[LINE_MAX];
opterr = 1;
while ((optch = getopt(argc, argv, format)) != -1)
switch (optch) {
case 'v':
verbose ++;
break;
case 'd':
optarg_len = strlen(optarg);
plugin_dir = (char *) malloc(optarg_len + 1);
strcpy(plugin_dir, optarg);
break;
case 'h':
optarg_len = strlen(optarg);
host = (char *) malloc(optarg_len + 1);
strcpy(host, optarg);
break;
case 's':
optarg_len = strlen(optarg);
spoolfetch_dir = (char *) malloc(optarg_len + 1);
strcpy(spoolfetch_dir, optarg);
break;
}
/* get default hostname if not precised */
if (! strlen(host)) {
host = (char *) malloc(HOST_NAME_MAX + 1);
gethostname(host, HOST_NAME_MAX);
}
printf("# munin node at %s\n", host);
while (fgets(line, LINE_MAX, stdin) != NULL) {
char* cmd;
char* arg;
line[LINE_MAX-1] = '\0';
cmd = strtok(line, " \t\n");
if(cmd == NULL)
arg = NULL;
else
arg = strtok(NULL, " \t\n");
if (!cmd || strlen(cmd) == 0) {
printf("# empty cmd\n");
} else if (strcmp(cmd, "version") == 0) {
printf("munin c node version: %s\n", VERSION);
} else if (strcmp(cmd, "nodes") == 0) {
printf("%s\n", host);
printf(".\n");
} else if (strcmp(cmd, "quit") == 0) {
return(0);
} else if (strcmp(cmd, "list") == 0) {
DIR* dirp = opendir(plugin_dir);
struct dirent* dp;
while ((dp = readdir(dirp)) != NULL) {
char cmdline[LINE_MAX];
char* plugin_filename = dp->d_name;;
if (plugin_filename[0] == '.') {
/* No dotted plugin */
continue;
}
snprintf(cmdline, LINE_MAX, "%s/%s", plugin_dir, plugin_filename);
if (access(cmdline, X_OK) == 0) {
printf("%s ", plugin_filename);
}
}
printf("\n");
closedir(dirp);
} else if (
strcmp(cmd, "config") == 0 ||
strcmp(cmd, "fetch") == 0
) {
char cmdline[LINE_MAX];
pid_t pid;
if(arg == NULL) {
printf("# no plugin given\n");
continue;
}
if(arg[0] == '.' || strchr(arg, '/')) {
printf("# invalid plugin character");
continue;
}
snprintf(cmdline, LINE_MAX, "%s/%s", plugin_dir, arg);
if (access(cmdline, X_OK) == -1) {
printf("# unknown plugin: %s\n", arg);
continue;
}
if(0 == (pid = vfork())) {
execl(cmdline, arg, cmd, NULL);
/* according to vfork(2) we must use _exit */
_exit(1);
} else if(pid < 0) {
printf("# fork failed\n");
continue;
} else {
waitpid(pid, NULL, 0);
}
printf(".\n");
} else if (strcmp(cmd, "cap") == 0) {
printf("cap ");
if (strlen(spoolfetch_dir)) {
printf("spool ");
}
printf("\n");
} else if (strcmp(cmd, "spoolfetch") == 0) {
printf("# not implem yet cmd: %s\n", cmd);
} else {
printf("# unknown cmd: %s\n", cmd);
}
}
return 0;
}

View File

@ -1,18 +0,0 @@
CC=gcc
CFLAGS=-W -Wall -pedantic -Wextra -g -O2
OBJS=main.o common.o cpu.o entropy.o forks.o fw_packets.o interrupts.o \
if_err_.o load.o open_files.o open_inodes.o processes.o swap.o threads.o \
uptime.o
LINKS=cpu entropy forks fw_packets interrupts if_err_eth0 load open_files \
open_inodes processes swap threads uptime
%.o:%.c
${CC} ${CFLAGS} -c $< -o $@
all:munin-plugins-busybox
strip -s munin-plugins-busybox
for l in ${LINKS}; do test -f $$l || ln -s munin-plugins-busybox $$l; done
munin-plugins-busybox:${OBJS}
${CC} ${CFLAGS} $^ -o $@
clean:
rm -f munin-plugins-busybox ${OBJS} ${LINKS}
.PHONY:all clean

View File

@ -1,36 +1,5 @@
What is this?
~~~~~~~~~~~~~
This is a rewrite of commonly used munin plugins in C as a single binary.
The purpose is reducing resource usage:
* disk space: the binary is smaler than the plugins together
* more diskspace: it has no dependencies on other programs
* less forks: it does not fork internally
* faster startup: it doesn't start perl or shell
* less memory: just a small C program
* less file accesses: one binary for many plugins
This can be useful for machines with restricted resources like embedded
machines.
This is a rewrite of munin plugins in C.
What plugins are included?
~~~~~~~~~~~~~~~~~~~~~~~~~~
cpu entropy forks fw_packets interrupts load open_files open_inodes
processes swap uptime
They have moved together with munin-node-c to its own repo:
Disadvantages?
~~~~~~~~~~~~~~
You lose flexibility. You can no longer just edit the plugin and if you try
you have to be very careful not to break it. If you want to deploy this you
have to create one binary for each architecture.
How to use?
~~~~~~~~~~~
After compiling there will be binary munin-plugins-busybox. You can just
replace symlinks in /etc/munin/plugins/ with symlinks to this binary.
License?
~~~~~~~~
(C) 2008 Helmut Grohne <helmut@subdivi.de>
At your choice GPLv2 or GPLv3 applies to *.c *.h and Makefile
# vim7:spelllang=en
# vim:textwidth=75
munin-c.git

View File

@ -1,74 +0,0 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
extern char **environ;
int writeyes(void) {
puts("yes");
return 0;
}
int autoconf_check_readable(const char *path) {
if(0 == access(path, R_OK))
return writeyes();
else {
printf("no (%s is not readable, errno=%d)\n", path, errno);
return 0;
}
}
int getenvint(const char *name, int defvalue) {
const char *value;
value = getenv(name);
if(value == NULL)
return defvalue;
return atoi(value);
}
const char *getenv_composed(const char *name1, const char *name2) {
char **p;
size_t len1 = strlen(name1), len2 = strlen(name2);
for(p = environ; *p; ++p) {
if(0 == strncmp(*p, name1, len1) &&
0 == strncmp(len1 + *p, name2, len2) &&
(*p)[len1 + len2] == '=')
return len1 + len2 + 1 + *p;
}
return NULL;
}
void print_warning(const char *name) {
const char *p;
p = getenv_composed(name, "_warning");
if(p == NULL)
p = getenv("warning");
if(p == NULL)
return;
printf("%s.warning %s\n", name, p);
}
void print_critical(const char *name) {
const char *p;
p = getenv_composed(name, "_critical");
if(p == NULL)
p = getenv("critical");
if(p == NULL)
return;
printf("%s.critial %s\n", name, p);
}
void print_warncrit(const char *name) {
print_warning(name);
print_critical(name);
}
int fail(const char *message) {
fputs(message, stderr);
fputc('\n', stderr);
return 1;
}

View File

@ -1,15 +0,0 @@
#ifndef COMMON_H
#define COMMON_H
#define PROC_STAT "/proc/stat"
int writeyes(void);
int autoconf_check_readable(const char *);
int getenvint(const char *, int);
const char *getenv_composed(const char *, const char *);
void print_warning(const char *);
void print_critical(const char *);
void print_warncrit(const char *);
int fail(const char *);
#endif

View File

@ -1,175 +0,0 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#include <stdlib.h>
#include "common.h"
#define SYSWARNING 30
#define SYSCRITICAL 50
#define USRWARNING 80
/* TODO: port support for env.foo_warning and env.foo_critical from mainline plugin */
int cpu(int argc, char **argv) {
FILE *f;
char buff[256], *s;
int ncpu=0, extinfo=0, scaleto100=0, hz;
if(argc > 1) {
if(!strcmp(argv[1], "config")) {
s = getenv("scaleto100");
if(s && !strcmp(s, "yes"))
scaleto100=1;
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] == ' ') {
s = strtok(buff+4, " \t");
for(extinfo=0;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;
printf("user.value %ld\n", atol(s) * 100 / hz);
if(!(s = strtok(NULL, " \t")))
break;
printf("nice.value %ld\n", atol(s) * 100 / hz);
if(!(s = strtok(NULL, " \t")))
break;
printf("system.value %ld\n", atol(s) * 100 / hz);
if(!(s = strtok(NULL, " \t")))
break;
printf("idle.value %ld\n", atol(s) * 100 / hz);
if(!(s = strtok(NULL, " \t")))
return 0;
printf("iowait.value %ld\n", atol(s) * 100 / hz);
if(!(s = strtok(NULL, " \t")))
return 0;
printf("irq.value %ld\n", atol(s) * 100 / hz);
if(!(s = strtok(NULL, " \t")))
return 0;
printf("softirq.value %ld\n", atol(s) * 100 / hz);
if(!(s = strtok(NULL, " \t")))
return 0;
printf("steal.value %ld\n", atol(s) * 100 / hz);
if(!(s = strtok(NULL, " \t")))
return 0;
printf("guest.value %ld\n", atol(s) * 100 / hz);
return 0;
}
}
fclose(f);
return fail("no cpu line found in " PROC_STAT);
}

View File

@ -1,36 +0,0 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "common.h"
#define ENTROPY_AVAIL "/proc/sys/kernel/random/entropy_avail"
int entropy(int argc, char **argv) {
FILE *f;
int entropy;
if(argc > 1) {
if(!strcmp(argv[1], "config")) {
puts("graph_title Available entropy\n"
"graph_args --base 1000 -l 0\n"
"graph_vlabel entropy (bytes)\n"
"graph_scale no\n"
"graph_category system\n"
"graph_info This graph shows the amount of entropy available in the system.\n"
"entropy.label entropy\n"
"entropy.info The number of random bytes available. This is typically used by cryptographic applications.");
print_warncrit("entropy");
return 0;
}
if(!strcmp(argv[1], "autoconf"))
return autoconf_check_readable(ENTROPY_AVAIL);
}
if(!(f=fopen(ENTROPY_AVAIL, "r")))
return fail("cannot open " ENTROPY_AVAIL);
if(1 != fscanf(f, "%d", &entropy)) {
fclose(f);
return fail("cannot read from " ENTROPY_AVAIL);
}
fclose(f);
printf("entropy.value %d\n", entropy);
return 0;
}

View File

@ -1,38 +0,0 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "common.h"
int forks(int argc, char **argv) {
FILE *f;
char buff[256];
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 autoconf_check_readable(PROC_STAT);
}
if(!(f=fopen(PROC_STAT, "r")))
return fail("cannot open " PROC_STAT);
while(fgets(buff, 256, f)) {
if(!strncmp(buff, "processes ", 10)) {
fclose(f);
printf("forks.value %s", buff+10);
return 0;
}
}
fclose(f);
return fail("no processes line found in " PROC_STAT);
}

View File

@ -1,55 +0,0 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#include "common.h"
#define PROC_NET_SNMP "/proc/net/snmp"
int fw_packets(int argc, char **argv) {
FILE *f;
char buff[1024], *s;
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.draw AREA\n"
"received.type DERIVE\n"
"received.min 0\n"
"forwarded.label Forwarded\n"
"forwarded.draw LINE2\n"
"forwarded.type DERIVE\n"
"forwarded.min 0");
return 0;
}
if(!strcmp(argv[1], "autoconf"))
return autoconf_check_readable(PROC_NET_SNMP);
}
if(!(f=fopen(PROC_NET_SNMP, "r")))
return fail("cannot open " PROC_NET_SNMP);
while(fgets(buff, 1024, f)) {
if(!strncmp(buff, "Ip: ", 4) && isdigit(buff[4])) {
fclose(f);
if(!(s = strtok(buff+4, " \t")))
break;
if(!(s = strtok(NULL, " \t")))
break;
if(!(s = strtok(NULL, " \t")))
break;
printf("received.value %s\n", s);
if(!(s = strtok(NULL, " \t")))
break;
if(!(s = strtok(NULL, " \t")))
break;
if(!(s = strtok(NULL, " \t")))
break;
printf("forwarded.value %s\n", s);
return 0;
}
}
fclose(f);
return fail("no ip line found in " PROC_NET_SNMP);
}

View File

@ -1,118 +0,0 @@
#include <ctype.h>
#include <libgen.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "common.h"
#define PROC_NET_DEV "/proc/net/dev"
int if_err_(int argc, char **argv) {
char *interface;
size_t interface_len;
FILE *f;
char buff[256], *s;
int i;
interface = basename(argv[0]);
if(strncmp(interface, "if_err_", 7) != 0)
return fail("if_err_ invoked with invalid basename");
interface += 7;
interface_len = strlen(interface);
if(argc > 1) {
if(!strcmp(argv[1], "autoconf"))
return autoconf_check_readable(PROC_NET_DEV);
if(!strcmp(argv[1], "suggest")) {
if(NULL == (f = fopen(PROC_NET_DEV, "r")))
return 1;
while(fgets(buff, 256, f)) {
for(s=buff;*s == ' ';++s)
;
i = 0;
if(!strncmp(s, "lo:", 3))
continue;
if(!strncmp(s, "sit", 3)) {
for(i=3; isdigit(s[i]); ++i)
;
if(s[i] == ':')
continue;
}
while(s[i] != ':' && s[i] != '\0')
++i;
if(s[i] != ':')
continue; /* a header line */
s[i] = '\0';
puts(s);
}
fclose(f);
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;
}
}
if(NULL == (f = fopen(PROC_NET_DEV, "r")))
return 1;
while(fgets(buff, 256, f)) {
for(s=buff;*s == ' ';++s)
;
if(0 != strncmp(s, interface, interface_len))
continue;
s += interface_len;
if(*s != ':')
continue;
++s;
while(*s == ' ')
++s;
for(i=1;i<3;++i) {
while(isdigit(*s))
++s;
while(isspace(*s))
++s;
}
for(i=0;isdigit(s[i]);++i)
;
printf("rcvd.value ");
fwrite(s, 1, i, stdout);
putchar('\n');
s += i;
while(isspace(*s))
++s;
for(i=4;i<11;++i) {
while(isdigit(*s))
++s;
while(isspace(*s))
++s;
}
for(i=0;isdigit(s[i]);++i)
;
printf("trans.value ");
fwrite(s, 1, i, stdout);
putchar('\n');
}
fclose(f);
return 0;
}

View File

@ -1,46 +0,0 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "common.h"
int interrupts(int argc, char **argv) {
FILE *f;
char buff[256];
if(argc > 1) {
if(!strcmp(argv[1], "config")) {
puts("graph_title Interrupts and context switches\n"
"graph_args --base 1000 -l 0\n"
"graph_vlabel interrupts & ctx switches / ${graph_period}\n"
"graph_category system\n"
"graph_info This graph shows the number of interrupts and context switches on the system. These are typically high on a busy system.\n"
"intr.info Interrupts are events that alter sequence of instructions executed by a processor. They can come from either hardware (exceptions, NMI, IRQ) or software.");
puts("ctx.info A context switch occurs when a multitasking operatings system suspends the currently running process, and starts executing another.\n"
"intr.label interrupts\n"
"ctx.label context switches\n"
"intr.type DERIVE\n"
"ctx.type DERIVE\n"
"intr.max 100000\n"
"ctx.max 100000\n"
"intr.min 0\n"
"ctx.min 0");
print_warncrit("intr");
print_warncrit("ctx");
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);
while(fgets(buff, 256, f)) {
if(!strncmp(buff, "intr ", 5)) {
buff[5 + strcspn(buff + 5, " \t\n")] = '\0';
printf("intr.value %s\n", buff+5);
} else if(!strncmp(buff, "ctxt ", 5)) {
buff[5 + strcspn(buff + 5, " \t\n")] = '\0';
printf("ctx.value %s\n", buff+5);
}
}
fclose(f);
return 0;
}

View File

@ -1,36 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "common.h"
#define PROC_LOADAVG "/proc/loadavg"
int load(int argc, char **argv) {
FILE *f;
float val;
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();
}
if(!(f=fopen(PROC_LOADAVG, "r")))
return fail("cannot open " PROC_LOADAVG);
if(1 != fscanf(f, "%*f %f", &val)) {
fclose(f);
return fail("cannot read from " PROC_LOADAVG);
}
fclose(f);
printf("load.value %.2f\n", val);
return 0;
}

View File

@ -1,86 +0,0 @@
#include <libgen.h>
#include <string.h>
#include <stdio.h>
#include "common.h"
int cpu(int argc, char **argv);
int entropy(int argc, char **argv);
int forks(int argc, char **argv);
int fw_packets(int argc, char **argv);
int if_err_(int argc, char **argv);
int interrupts(int argc, char **argv);
int load(int argc, char **argv);
int open_files(int argc, char **argv);
int open_inodes(int argc, char **argv);
int processes(int argc, char **argv);
int swap(int argc, char **argv);
int threads(int argc, char **argv);
int uptime(int argc, char **argv);
int busybox(int argc, char **argv) {
if(argc < 2)
return fail("missing parameter");
if(0 != strcmp(argv[1], "listplugins"))
return fail("unknown parameter");
puts("cpu\nentropy\nforks\nfw_packets\ninterrupts\nload\n"
"open_files\nopen_inodes\nswap\nthreads\nuptime");
return 0;
}
int main(int argc, char **argv) {
char *progname;
progname = basename(argv[0]);
switch(*progname) {
case 'c':
if(!strcmp(progname, "cpu"))
return cpu(argc, argv);
break;
case 'e':
if(!strcmp(progname, "entropy"))
return entropy(argc, argv);
break;
case 'f':
if(!strcmp(progname, "forks"))
return forks(argc, argv);
if(!strcmp(progname, "fw_packets"))
return fw_packets(argc, argv);
break;
case 'i':
if(!strcmp(progname, "interrupts"))
return interrupts(argc, argv);
if(!strncmp(progname, "if_err_", 6))
return if_err_(argc, argv);
break;
case 'l':
if(!strcmp(progname, "load"))
return load(argc, argv);
break;
case 'm':
if(!strcmp(progname, "munin-plugins-busybox"))
return busybox(argc, argv);
break;
case 'o':
if(!strcmp(progname, "open_files"))
return open_files(argc, argv);
if(!strcmp(progname, "open_inodes"))
return open_inodes(argc, argv);
break;
case 'p':
if(!strcmp(progname, "processes"))
return processes(argc, argv);
break;
case 's':
if(!strcmp(progname, "swap"))
return swap(argc, argv);
break;
case 't':
if(!strcmp(progname, "threads"))
return threads(argc, argv);
break;
case 'u':
if(!strcmp(progname, "uptime"))
return uptime(argc, argv);
break;
}
return fail("unknown basename");
}

View File

@ -1,49 +0,0 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "common.h"
#define FS_FILE_NR "/proc/sys/fs/file-nr"
/* TODO: support env.warning and friends after the upstream plugin is fixed */
int open_files(int argc, char **argv) {
FILE *f;
int alloc, freeh, avail;
if(argc > 1) {
if(!strcmp(argv[1], "config")) {
if(!(f=fopen(FS_FILE_NR, "r")))
return fail("cannot open " FS_FILE_NR);
if(1 != fscanf(f, "%*d %*d %d", &avail)) {
fclose(f);
return fail("cannot read from " FS_FILE_NR);
}
fclose(f);
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. Tune by modifying " FS_FILE_NR
".");
printf("used.warning %d\nused.critical %d\n",
(int)(avail*0.92), (int)(avail*0.98));
return 0;
}
if(!strcmp(argv[1], "autoconf"))
return autoconf_check_readable(FS_FILE_NR);
}
if(!(f=fopen(FS_FILE_NR, "r")))
return fail("cannot open " FS_FILE_NR);
if(3 != fscanf(f, "%d %d %d", &alloc, &freeh, &avail)) {
fclose(f);
return fail("cannot read from " FS_FILE_NR);
}
fclose(f);
printf("used.value %d\nmax.value %d\n", alloc-freeh, avail);
return 0;
}

View File

@ -1,38 +0,0 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "common.h"
#define FS_INODE_NR "/proc/sys/fs/inode-nr"
int open_inodes(int argc, char **argv) {
FILE *f;
int nr, freen;
if(argc > 1) {
if(!strcmp(argv[1], "config")) {
puts("graph_title Inode table usage\n"
"graph_args --base 1000 -l 0\n"
"graph_vlabel number of open inodes\n"
"graph_category system\n"
"graph_info This graph monitors the Linux open inode table.\n"
"used.label open inodes\n"
"used.info The number of currently open inodes.\n"
"max.label inode table size\n"
"max.info The size of the system inode table. This is dynamically adjusted by the kernel.");
print_warncrit("used");
print_warncrit("max");
return 0;
}
if(!strcmp(argv[1], "autoconf"))
return autoconf_check_readable(FS_INODE_NR);
}
if(!(f=fopen(FS_INODE_NR, "r")))
return fail("cannot open " FS_INODE_NR);
if(2 != fscanf(f, "%d %d", &nr, &freen)) {
fclose(f);
return fail("cannot read from " FS_INODE_NR);
}
fclose(f);
printf("used.value %d\nmax.value %d\n", nr-freen, nr);
return 0;
}

View File

@ -1,42 +0,0 @@
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <ctype.h>
#include "common.h"
/* TODO: The upstream plugin does way more nowawdays. */
int processes(int argc, char **argv) {
DIR *d;
struct dirent *e;
char *s;
int n=0;
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();
}
if(!(d = opendir("/proc")))
return fail("cannot open /proc");
while((e = readdir(d))) {
for(s=e->d_name;*s;++s)
if(!isdigit(*s))
break;
if(!*s)
++n;
}
closedir(d);
printf("processes.value %d\n", n);
return 0;
}

View File

@ -1,66 +0,0 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "common.h"
int swap(int argc, char **argv) {
FILE *f;
char buff[256];
int in, out;
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 autoconf_check_readable(PROC_STAT);
}
if(!access("/proc/vmstat", F_OK)) {
in=out=0;
if(!(f=fopen("/proc/vmstat", "r")))
return fail("cannot open /proc/vmstat");
while(fgets(buff, 256, f)) {
if(!in && !strncmp(buff, "pswpin ", 7)) {
++in;
printf("swap_in.value %s", buff+7);
}
else if(!out && !strncmp(buff, "pswpout ", 8)) {
++out;
printf("swap_out.value %s", buff+8);
}
}
fclose(f);
if(!(in*out))
return fail("no usable data on /proc/vmstat");
return 0;
} else {
if(!(f=fopen(PROC_STAT, "r")))
return fail("cannot open " PROC_STAT);
while(fgets(buff, 256, f)) {
if(!strncmp(buff, "swap ", 5)) {
fclose(f);
if(2 != sscanf(buff+5, "%d %d", &in, &out))
return fail("bad data on " PROC_STAT);
printf("swap_in.value %d\nswap_out.value %d\n", in, out);
return 0;
}
}
fclose(f);
return fail("no swap line found in " PROC_STAT);
}
}

View File

@ -1,70 +0,0 @@
#include <ctype.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include "common.h"
int threads(int argc, char **argv) {
FILE *f;
char buff[256];
const char *s;
int i, sum;
DIR *d;
struct dirent *e;
if(argc > 1) {
if(!strcmp(argv[1], "autoconf")) {
i = getpid();
sprintf(buff, "/proc/%d/status", i);
if(NULL == (f = fopen(buff, "r")))
return fail("failed to open /proc/$$/status");
while(fgets(buff, 256, f))
if(!strncmp(buff, "Threads:", 8)) {
fclose(f);
return writeyes();
}
fclose(f);
puts("no");
return 0;
}
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(NULL == (d = opendir("/proc")))
return fail("cannot open /proc");
sum = 0;
while((e = readdir(d))) {
for(s=e->d_name;*s;++s)
if(!isdigit(*s))
break;
if(*s) /* non-digit found */
continue;
snprintf(buff, 256, "/proc/%s/status", e->d_name);
if(!(f = fopen(buff, "r")))
continue; /* process has vanished */
while(fgets(buff, 256, f)) {
if(strncmp(buff, "Threads:", 8))
continue;
if(1 != sscanf(buff+8, "%d", &i)) {
fclose(f);
closedir(d);
return fail("failed to parse "
"/proc/somepid/status");
}
sum += i;
}
fclose(f);
}
closedir(d);
printf("threads.value %d\n", sum);
return 0;
}

View File

@ -1,30 +0,0 @@
#include <stdio.h>
#include <string.h>
#include "common.h"
int uptime(int argc, char **argv) {
FILE *f;
float uptime;
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"
"uptime.label uptime\n"
"uptime.draw AREA");
print_warncrit("uptime");
return 0;
}
if(!strcmp(argv[1], "autoconf"))
return writeyes();
}
if(!(f=fopen("/proc/uptime", "r")))
return fail("cannot open /proc/uptime");
if(1 != fscanf(f, "%f", &uptime)) {
fclose(f);
return fail("cannot read from /proc/uptime");
}
fclose(f);
printf("uptime.value %.2f\n", uptime/86400);
return 0;
}