1
0
Fork 0
mirror of https://github.com/munin-monitoring/contrib.git synced 2025-07-22 22:25:23 +00:00

Merge branch 'master' of git://github.com/munin-monitoring/contrib

This commit is contained in:
Mike Koss 2012-02-20 01:23:31 -08:00
commit 1edc7e7dc3
10 changed files with 541 additions and 48 deletions

View file

@ -0,0 +1,98 @@
#!/usr/bin/env python
"""
gunicorn_status - A munin plugin for Linux to monitor the memory
usage of gunicorn processes
Copyright (C) 2012 Azavea, Inc.
Author: Andrew Jennings
Like Munin, this plugin is licensed under the GNU GPL v2 license
http://www.opensource.org/licenses/GPL-2.0
If you've put your gunicorn pid somewhere other than the
default /var/run/gunicorn.pid, you can add a section like
this to your munin-node's plugin configuration:
[gunicorn_*]
env.gunicorn_pid_path [path to your gunicorn pid]
This plugin supports the following munin configuration parameters:
#%# family=auto contrib
#%# capabilities=autoconf
"""
import sys, os
from subprocess import check_output
# set path to your gunicorn pid
try:
GUNICORN_PID_PATH = os.environ['gunicorn_pid_path']
except:
GUNICORN_PID_PATH = "/var/run/gunicorn.pid"
class GunicornMemoryStatus():
master_pid = ''
"""
The Gunicorn master process pid, as a string
"""
def __init__(self):
try:
self._get_master_pid()
except:
raise Exception("Couldn't read gunicorn pid information")
def print_total_memory(self):
print ('total_memory.value %d' % self._get_total_memory())
def _get_master_pid(self):
master_pid_file = open(GUNICORN_PID_PATH)
self.master_pid = master_pid_file.read().rstrip()
master_pid_file.close()
return True
def _get_total_memory(self):
master = self._get_master_memory()
total = master +self. _get_worker_memory()
total_in_mb = total / 1024
return total_in_mb
def _get_master_memory(self):
master = int(check_output(
['ps', '--pid', self.master_pid, '-o', 'rss', '--no-headers']))
return master
def _get_worker_memory(self):
worker_processes = check_output(
['ps', '--ppid', self.master_pid, '-o', 'rss', '--no-headers'])
process_memory_usage = [int(rss) for rss in worker_processes.splitlines()]
worker_memory_usage = sum(process_memory_usage)
return worker_memory_usage
def print_config():
print "graph_title Gunicorn - Memory Usage"
print "graph_args --base 1024 -l 0"
print "graph_vlabel Megabytes"
print "graph_category gunicorn"
print "total_memory.label Total Memory"
if __name__ == "__main__":
if len(sys.argv) == 2 and sys.argv[1] == 'config':
print_config()
elif len(sys.argv) == 2 and sys.argv[1] == 'autoconf':
try:
open(GUNICORN_PID_PATH).close()
print "yes"
except:
print "no"
# Some docs say it'll be called with fetch, some say no arg at all
elif len(sys.argv) == 1 or (len(sys.argv) == 2 and sys.argv[1] == 'fetch'):
try:
status = GunicornMemoryStatus()
status.print_total_memory()
except:
sys.exit("Couldn't retrieve gunicorn memory usage information")

113
plugins/gunicorn/gunicorn_status Executable file
View file

@ -0,0 +1,113 @@
#!/usr/bin/env python
"""
gunicorn_status - A munin plugin for Linux to monitor gunicorn processes
Copyright (C) 2012 Azavea, Inc.
Author: Andrew Jennings
Like Munin, this plugin is licensed under the GNU GPL v2 license
http://www.opensource.org/licenses/GPL-2.0
If you've put your gunicorn pid somewhere other than the
default /var/run/gunicorn.pid, you can add a section like
this to your munin-node's plugin configuration:
[gunicorn_*]
env.gunicorn_pid_path [path to your gunicorn pid]
This plugin supports the following munin configuration parameters:
#%# family=auto contrib
#%# capabilities=autoconf
"""
import sys, os
from subprocess import check_output
from time import sleep
# set path to your gunicorn pid
try:
GUNICORN_PID_PATH = os.environ['gunicorn_pid_path']
except:
GUNICORN_PID_PATH = "/var/run/gunicorn.pid"
class GunicornStatus():
master_pid = ''
"""
The gunicorn master process pid, as a string
"""
worker_pids = ''
"""
The list of gunicorn processes as strings
"""
def __init__(self):
try:
self._get_master_pid()
self._get_worker_pids(self.master_pid)
except:
sys.exit("Couldn't read gunicorn pid")
def print_total_workers(self):
print ('total_workers.value %d' % self._worker_count())
def print_idle_workers(self):
print ('idle_workers.value %d' % self._idle_worker_count())
def _get_master_pid(self):
master_pid_file = open(GUNICORN_PID_PATH)
self.master_pid = master_pid_file.read().rstrip()
master_pid_file.close()
def _get_worker_pids(self, master_pid):
children = check_output(
['ps', '--ppid', master_pid, '-o', 'pid', '--no-headers'])
self.worker_pids = [pid.strip() for pid in children.splitlines()]
def _worker_count(self):
return len(self.worker_pids)
def _idle_worker_count(self):
idle_workers = 0
for pid in self.worker_pids:
before = self._cpu_time(pid)
sleep(0.50)
after = self._cpu_time(pid)
if before == after:
idle_workers += 1
return idle_workers
def _cpu_time(self, pid):
proc_info = open('/proc/%s/stat' % pid).read()
proc_info = [field.rstrip() for field in proc_info.split()]
user_time = int(proc_info[13].rstrip())
kernel_time = int(proc_info[14].rstrip())
return user_time + kernel_time
def print_config():
print "graph_title Gunicorn - Status"
print "graph_args -l 0"
print "graph_vlabel Number of workers"
print "graph_category gunicorn"
print "total_workers.label Total Workers"
print "idle_workers.label Idle Workers"
if __name__ == "__main__":
if len(sys.argv) == 2 and sys.argv[1] == 'config':
print_config()
elif len(sys.argv) == 2 and sys.argv[1] == 'autoconf':
try:
open(GUNICORN_PID_PATH).close()
print "yes"
except:
print "no"
# Some docs say it'll be called with fetch, some say no arg at all
elif len(sys.argv) == 1 or (len(sys.argv) == 2 and sys.argv[1] == 'fetch'):
status = GunicornStatus()
try:
status.print_total_workers()
status.print_idle_workers()
except:
sys.exit("Couldn't retrieve gunicorn status")

View file

@ -13,7 +13,7 @@ Requires perl and either WWW::Mechanize or Net::Telnet.
=head1 CONFIGURATION
The plugin needs HTML access to the router. If you can get to http://YOUR_ROUTER/,
and are greeting with a page titled "THOMSON TG585 v7", then you can probably use this plugin.
and are greeting with a page titled "THOMSON TG585 v7", then you can probably use this plugin.
This is a wildcard plugin, so you will need to create symlinks to this plugin (or create copies if your filesystem doesn't support linking). Links should be of the form:
@ -1112,25 +1112,45 @@ else {
sub TelnetError {
my $errmsg = shift;
my @parts;
if ( $mode eq 'bandwidth' ) {
@parts = qw(down up);
}
elsif ( $mode eq 'power' ) {
@parts = qw(downout upout downline upline downsn upsn);
}
elsif ( $mode eq 'uptime' ) {
@parts = qw(Box DSL iNet);
}
elsif ( $mode eq 'errors' ) {
@parts = qw(downFEC upFEC downCRC upCRC downHEC upHEC);
}
foreach (@parts) {
my %parts = (
'atm' => [qw(RXCells RxErrors RxOctets TxCells TxErrors TxOctets)],
'bandwidth' => [qw(down downrate up uprate)],
'conntrack' =>
[qw(Active closing expected halfopen ICMP idle loose mcast non TCP TCPclosing TCPestablished TCPopen UDP)],
'dhcpclient' =>
[qw(ACKs Corrupted DECLINEs DISCOVERs failures INFORMs NAKs OFFERs Other RELEASEs REPLIES REQUESTs)],
'dhcprelay' =>
[qw(badc bogusg bogusr clientp corrupta missinga missingc packets serverp)],
'dhcpserver' =>
[qw(ACKs BOOTP Corrupted DECLINE DISCOVER dropped failures INFORM NAKs OFFERs Other RELEASE REQUEST)],
'dns' =>
[qw(corrupted discard external forwarded negative resolved spoofed spurious unknown)],
'errors' => [qw(downCRC downFEC downHEC upCRC upFEC upHEC)],
'firewall' =>
[qw(DroppedForward DroppedInput DroppedOutput ParsedForward ParsedInput ParsedOutput)],
'ids' => [qw(Active Collisions New Recycled Searches)],
'igmphost' =>
[qw(badchecksum badqueries badttl failing invalidmembership norouter receivedforour reportsreceived reportstransmitted toolong toosmall v1membershipq v2membershipq v3membershipq v3membershipr)],
'igmpproxy' =>
[qw(badchecksum badleavereports badqueries badreports badttl election igmpleavereports mrdadvertise mrdbad mrdsolicits mrdterminate noroute queriesfail toolong tooshort v1queriesr v1queriess v1reportsr v2queriesr v2queriess v2reportsr v3queriesr v3queriess v3reportsr)],
'power' => [qw(downline downout downsn upline upout upsn)],
'protoicmp' =>
[qw(echor echorepr echoreps echos errorsr errorss maskr maskrepr maskreps masks paramr params quenchr quenchs redirectr redirects timeexceedr timeexceeds timestampr timestamprepr timestampreps timestamps unreachabler unreachables)],
'protoip' =>
[qw(droppedfrags forwarded fragerrs fragged fragments fwderrors herrors hostdrop hostfwd hostrec noroute reassembled reserrors totfrags)],
'prototcp' =>
[qw(accepts attempts drops errors established received retransmitted transmitted)],
'protoudp' => [qw(dropped errors received transmitted)],
'uptime' => [qw(Box DSL iNet)]
);
foreach ( @{$parts{$mode}} ) {
print "$_.value U\n";
print "$_.extinfo $errmsg\n";
}
print "# Sending \"exit\"\n" if $MUNIN_DEBUG;
if ( defined $telnet ) {
$telnet->errmode('return');
$telnet->print('exit');
$telnet->close;
}
@ -1141,7 +1161,8 @@ else {
$telnet = new Net::Telnet(
Host => $host,
Prompt => '/{.*}.*=>$/',
ErrMode => \&TelnetError
ErrMode => \&TelnetError,
Timeout => 10
);
print "# Logging in...\n" if $MUNIN_DEBUG;

50
plugins/php/php_apc.php Normal file
View file

@ -0,0 +1,50 @@
<?php
$ret = array();
if(function_exists("apc_cache_info") && function_exists("apc_sma_info"))
{
switch ($_GET["act"])
{
case "memory":
$tmp = apc_sma_info();
$ret["mem_used"] = $tmp["seg_size"]-$tmp["avail_mem"];
$ret["mem_avail"] = $tmp["avail_mem"];
break;
case "hits":
$tmp = apc_cache_info();
$ret["num_hits"] = $tmp["num_hits"];
$ret["num_misses"] = $tmp["num_misses"];
break;
case "percents":
$tmp = apc_sma_info();
$ret["memory"] = 100-(($tmp["avail_mem"] / $tmp["seg_size"])*100);
$tmp = apc_cache_info();
$ret["hits"] = ($tmp["num_hits"] / ( $tmp["num_hits"]+$tmp["num_misses"]) ) * 100;
$ret["misses"] = ($tmp["num_misses"] / ( $tmp["num_hits"]+$tmp["num_misses"]) ) * 100;
break;
}
} else {
switch ($_GET["act"])
{
case "memory":
$ret["mem_size"] = 0;
$ret["mem_used"] = 0;
break;
case "hits":
$ret["num_hits"] = 0;
$ret["num_misses"] = 0;
break;
case "percents":
$ret["memory"] = 0;
$ret["hits"] = 0;
$ret["misses"] = 0;
break;
}
}
foreach($ret as $key => $val) echo "$key.value $val\n";
?>

Binary file not shown.

View file

@ -96,8 +96,8 @@ $graphsRef->{listeners} = {
info => 'This graph shows us the various counts for listener states we are tracking',
},
datasrc => [
{ name => 'maxlisteners', draw => 'STACK', min => '0', label => 'Max Listeners', type => 'GAUGE' },
{ name => 'currlisteners', draw => 'AREA', min => '0', label => 'Current Listeners', type => 'GAUGE' },
{ name => 'maxlisteners', draw => 'AREA', min => '0', label => 'Max Listeners', type => 'GAUGE' },
{ name => 'currlisteners', draw => 'STACK', min => '0', label => 'Current Listeners', type => 'GAUGE' },
],
};
@ -121,8 +121,8 @@ $graphsRef->{sid_listeners} = {
info => 'This graph shows us the various counts for listener states we are tracking',
},
datasrc => [
{ name => 'maxlisteners', draw => 'STACK', min => '0', label => 'Max Listeners', type => 'GAUGE', xmlkey => 'MAXLISTENERS' },
{ name => 'currlisteners', draw => 'AREA', min => '0', label => 'Current Listeners', type => 'GAUGE', xmlkey => 'CURRENTLISTENERS' },
{ name => 'maxlisteners', draw => 'AREA', min => '0', label => 'Max Listeners', type => 'GAUGE', xmlkey => 'MAXLISTENERS' },
{ name => 'currlisteners', draw => 'STACK', min => '0', label => 'Current Listeners', type => 'GAUGE', xmlkey => 'CURRENTLISTENERS' },
{ name => 'peaklisteners', draw => 'LINE2', min => '0', label => 'Peak Listeners', type => 'GAUGE', xmlkey => 'PEAKLISTENERS' },
{ name => 'uniqlisteners', draw => 'LINE2', min => '0', label => 'Unique Listeners', type => 'GAUGE', xmlkey => 'UNIQUELISTENERS' },
],
@ -133,7 +133,7 @@ if (defined($ARGV[0]) && ($ARGV[0] eq 'config')) {
exit;
}
if (defined($ARGV[0]) && ($ARGV[0] eq 'autoconf')) {
if (defined($ARGV[0]) && (($ARGV[0] eq 'autoconf') || ($ARGV[0] eq 'suggest'))) {
check_autoconf();
exit;
}
@ -234,7 +234,7 @@ sub print_listener_data {
}
}
}
print "multigraph shoutcast2_active\n";
print "multigraph shoutcast2_listeners\n";
foreach my $dsrc (@{$graphsRef->{listeners}->{datasrc}}) {
if ($dsrc->{name} eq 'maxlisteners') {
print "$dsrc->{name}.value $maxListeners\n";

View file

@ -17,26 +17,19 @@ style="AREA"
cpus=$(grep -c ^processor /proc/cpuinfo)
run_watchdog() { # should also trap kill and term signals
while :; do
sleep ${watchdog:-600}
touch -d now-${timeout:-1200}sec $cache
[ $pidfile -nt $cache ] || break
done
[ -f $pidfile ] || exit # may have been removed by terminating daemon
kill $(cat $pidfile)
rm -f $pidfile $cache
kill -0 $(cat $pidfile) 2> /dev/null || rm -f $pidfile
}
run_acquire() {
echo "$$" > $pidfile
$pluginfull watchdog &
mpstat -P ALL $interval |
awk -v cpus=$cpus '$2>=0&&$2<10 {print $2, systime(), (100-$11)/cpus}' >> $cache
rm -f $pidfile $cache
}
run_daemon() {
run_watchdog
if [ -f $pidfile ]; then
touch $pidfile
else
@ -92,4 +85,3 @@ exit 0
# acquire which needs a different pid than watchdog, otherwise watchdog
# could/will kill itself when expiring before the watched process is killed.
# not a POSIX feature.

View file

@ -1,23 +1,26 @@
#!/usr/local/bin/perl -w
#!/usr/bin/env perl
# -*- perl -*-
# Plugin to monitor number of irqs
# Plugin to monitor the system uptime
#
#%# family=auto
#%# capabilities=autoconf
use strict;
use warnings;
my %IN;
my $sysctl = defined($ENV{sysctl}) ? $ENV{sysctl} : '/sbin/sysctl';
my $ostype = `uname -s`;
chomp ($ostype);
if (defined($ARGV[0]) and ($ARGV[0] eq 'autoconf')) {
if ( -x $sysctl ) {
print "yes\n";
}else{
print "no (sysctl binary not found)\n";
};
exit;
if ( -x $sysctl ) {
print "yes\n";
} else {
print "no (sysctl binary not found)\n";
};
exit;
};
if (defined($ARGV[0]) and ($ARGV[0] eq 'config')) {
@ -26,12 +29,12 @@ graph_title Uptime
graph_args --base 1000 -l 0
graph_vlabel days
graph_category system
compile.label kernel age
compile.label Kernel age
compile.type GAUGE
compile.min 0
compile.max 1000
compile.draw AREA
uptime.label uptime
uptime.label Uptime
uptime.type GAUGE
uptime.min 0
uptime.max 1000
@ -44,13 +47,15 @@ use Date::Parse;
my $kern=`sysctl -n kern.version`;
$kern=~ /:\s+(.*\S)\s+\w+\@/;
print "Compile: $1\n";
#print "Compile: $1\n";
$kern=str2time($1);
my $boot=`sysctl -n kern.boottime`;
$boot=~ / sec = (\d+)/;
print "Boot: $1\n";
$boot=$1;
my $boot=`sysctl -n kern.boottime`; # OpenBSD will return seconds from the epoch
if ($ostype ne "OpenBSD") {
$boot=~ / sec = (\d+)/;
#print "Boot: $1\n";
$boot=$1;
}
my $now=time;