mirror of
https://github.com/munin-monitoring/contrib.git
synced 2018-11-08 00:59:34 +01:00
boinc_credit: Initial commit
New plugin to track your BOINC credit across all your projects.
This commit is contained in:
parent
13a585f290
commit
480eb0f363
234
plugins/other/boinc_credit
Executable file
234
plugins/other/boinc_credit
Executable file
@ -0,0 +1,234 @@
|
||||
#!/usr/bin/perl
|
||||
# -*- cperl -*-
|
||||
|
||||
=head1 NAME
|
||||
|
||||
boinc_credit - Munin plugin to monitor BOINC credit for a user
|
||||
|
||||
=head1 APPLICABLE SYSTEMS
|
||||
|
||||
Any
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
All that should be needed is to add the following to your config:
|
||||
|
||||
[boinc_credit]
|
||||
env.cpid 1234abcd....
|
||||
|
||||
Where the value is your Cross Project ID (CPID).
|
||||
|
||||
=head1 MAGIC MARKERS
|
||||
|
||||
#%# family=auto contrib
|
||||
#%# capabilities=autoconf
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
1.0
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Paul Saunders <darac+munin@darac.org.uk>
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use lib $ENV{'MUNIN_LIBDIR'};
|
||||
use Munin::Plugin;
|
||||
|
||||
my $CPID = $ENV{cpid};
|
||||
my $STATSURL = $ENV{statsurl}
|
||||
|| "http://boinc.netsoft-online.com/get_user.php?cpid=$CPID";
|
||||
my $TICK = $ENV{tick} || 60; # minutes
|
||||
|
||||
my $ret;
|
||||
if ( !eval "require XML::Simple;" ) {
|
||||
$ret += "Could not load XML::Simple; ";
|
||||
}
|
||||
if ( !eval "require LWP::Simple;" ) {
|
||||
$ret += "Could not load LWP::Simple; ";
|
||||
}
|
||||
|
||||
if ( defined $ARGV[0] and $ARGV[0] eq 'autoconf' ) {
|
||||
|
||||
# Can't auto configure at the moment.
|
||||
# At least, until we can calculate CPID
|
||||
print "no\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my $lastread;
|
||||
|
||||
sub save_data {
|
||||
my @projdata = @_;
|
||||
|
||||
# Do we need to save this data?
|
||||
if ( !defined $lastread or time >= $lastread + ( $TICK * 60 ) ) {
|
||||
$lastread = time;
|
||||
|
||||
my @save_vector;
|
||||
push @save_vector, $lastread;
|
||||
foreach (@projdata) {
|
||||
|
||||
# Serialise the hash
|
||||
my @tempbuf;
|
||||
foreach my $key ( keys %{$_} ) {
|
||||
push @tempbuf, $key . '¬' . $_->{$key};
|
||||
}
|
||||
push @save_vector, join( '^^', @tempbuf );
|
||||
}
|
||||
save_state(@save_vector);
|
||||
}
|
||||
}
|
||||
|
||||
sub load_data {
|
||||
|
||||
# Bring the data back in
|
||||
my @save_vector = restore_state();
|
||||
|
||||
# Read the timestamp, Do we need to refresh the data?
|
||||
$lastread = shift @save_vector;
|
||||
|
||||
my @projarray;
|
||||
foreach (@save_vector) {
|
||||
my $hashref;
|
||||
foreach ( split /\^\^/ ) {
|
||||
my ( $key, $value ) = split /¬/;
|
||||
$hashref->{$key} = $value;
|
||||
}
|
||||
push @projarray, $hashref;
|
||||
}
|
||||
|
||||
if ( !defined $lastread or time >= ( $lastread + ( $TICK * 60 ) ) ) {
|
||||
|
||||
# Data is stale
|
||||
|
||||
eval {
|
||||
|
||||
# Fetch the XML
|
||||
my $content;
|
||||
unless ( defined( $content = LWP::Simple::get $STATSURL) ) {
|
||||
die "Could not get $STATSURL";
|
||||
}
|
||||
my $xmlref = XML::Simple::XMLin( $content, ForceArray => 1 );
|
||||
|
||||
my @temparray;
|
||||
foreach ( @{ $xmlref->{project} } ) {
|
||||
my $temphash;
|
||||
$temphash->{name} = $_->{name}[0];
|
||||
$temphash->{id} = $_->{project_id}[0];
|
||||
$temphash->{credit} = $_->{total_credit}[0];
|
||||
$temphash->{creditfract} =
|
||||
$_->{total_credit}[0] / $xmlref->{total_credit}[0];
|
||||
$temphash->{totalcredit} = $xmlref->{total_credit}[0];
|
||||
$temphash->{rank} = $_->{project_rank_total_credit}[0];
|
||||
|
||||
push @temparray, $temphash;
|
||||
}
|
||||
|
||||
# If the above threw an error, we won't overwrite the old data
|
||||
@projarray = @temparray;
|
||||
|
||||
1;
|
||||
} or do {
|
||||
print $@;
|
||||
}
|
||||
}
|
||||
return @projarray;
|
||||
}
|
||||
|
||||
# Project Colours from http://boinc.netsoft-online.com/e107_plugins/forum/forum_viewtopic.php?3
|
||||
sub rgb($$$) {
|
||||
return sprintf( '%02x%02x%02x', shift, shift, shift );
|
||||
}
|
||||
my %project_colour = (
|
||||
'climatepredition.net' => rgb( 0, 139, 69 ),
|
||||
'Predictor@Home' => rgb( 135, 206, 235 ),
|
||||
'SETI@home' => rgb( 65, 105, 225 ),
|
||||
'Einstein@Home' => rgb( 255, 165, 0 ),
|
||||
'Rosetta@home' => rgb( 238, 130, 238 ),
|
||||
'PrimeGrid' => rgb( 205, 197, 191 ),
|
||||
'LHC@home' => rgb( 255, 127, 80 ),
|
||||
'World Community Grid' => rgb( 250, 128, 114 ),
|
||||
'BURP' => rgb( 0, 255, 127 ),
|
||||
'SZTAKI Desktop Grid' => rgb( 205, 79, 57 ),
|
||||
'uFluids' => rgb( 0, 0, 0 ),
|
||||
'SIMAP' => rgb( 143, 188, 143 ),
|
||||
'Folding@Home' => rgb( 153, 50, 204 ),
|
||||
'MalariaControl' => rgb( 30, 144, 255 ),
|
||||
'The Lattice Project' => rgb( 0, 100, 0 ),
|
||||
'Pirates@Home' => rgb( 127, 255, 0 ),
|
||||
'BBC Climate Change Experiment' => rgb( 205, 173, 0 ),
|
||||
'Leiden Classical' => rgb( 140, 34, 34 ),
|
||||
'SETI@home Beta' => rgb( 152, 245, 255 ),
|
||||
'RALPH@Home' => rgb( 250, 240, 230 ),
|
||||
'QMC@HOME' => rgb( 144, 238, 144 ),
|
||||
'XtremLab' => rgb( 130, 130, 130 ),
|
||||
'HashClash' => rgb( 255, 105, 180 ),
|
||||
'cpdn seasonal' => rgb( 255, 255, 255 ),
|
||||
'Chess960@Home Alpha' => rgb( 165, 42, 42 ),
|
||||
'vtu@home' => rgb( 255, 0, 0 ),
|
||||
'LHC@home alpha' => rgb( 205, 133, 63 ),
|
||||
'TANPAKU' => rgb( 189, 183, 107 ),
|
||||
'other' => rgb( 255, 193, 37 ),
|
||||
'Rectilinear Crossing Number' => rgb( 83, 134, 139 ),
|
||||
'Nano-Hive@Home' => rgb( 193, 205, 193 ),
|
||||
'Spinhenge@home' => rgb( 255, 240, 245 ),
|
||||
'RieselSieve' => rgb( 205, 183, 158 ),
|
||||
'Project Neuron' => rgb( 139, 58, 98 ),
|
||||
'RenderFarm@Home' => rgb( 210, 105, 30 ),
|
||||
'Docking@Home' => rgb( 178, 223, 238 ),
|
||||
'proteins@home' => rgb( 0, 0, 255 ),
|
||||
'DepSpid' => rgb( 139, 90, 43 ),
|
||||
'ABC@home' => rgb( 222, 184, 135 ),
|
||||
'BOINC alpha test' => rgb( 245, 245, 220 ),
|
||||
'WEP-M+2' => rgb( 0, 250, 154 ),
|
||||
'Zivis Superordenador Ciudadano' => rgb( 255, 239, 219 ),
|
||||
'SciLINC' => rgb( 240, 248, 255 ),
|
||||
'APS@Home' => rgb( 205, 91, 69 ),
|
||||
'PS3GRID' => rgb( 0, 139, 139 ),
|
||||
'Superlink@Technion' => rgb( 202, 255, 112 ),
|
||||
'BRaTS@Home' => rgb( 255, 106, 106 ),
|
||||
'Cosmology@Home' => rgb( 240, 230, 140 ),
|
||||
'SHA 1 Collision Search' => rgb( 255, 250, 205 ),
|
||||
);
|
||||
|
||||
if ( defined $ARGV[0] and $ARGV[0] eq 'config' ) {
|
||||
if ($ret) {
|
||||
print $ret;
|
||||
exit 1;
|
||||
}
|
||||
my @projdata = load_data();
|
||||
print <<EOF;
|
||||
graph_args --base 1000 --logarithmic
|
||||
graph_vlabel Cobblestones
|
||||
graph_category boinc
|
||||
graph_title BOINC Total Credit
|
||||
EOF
|
||||
foreach ( sort { $a->{id} <=> $b->{id} } @projdata ) {
|
||||
my $fieldname = 'proj' . $_->{id};
|
||||
print <<EOF;
|
||||
$fieldname.label $_->{name}
|
||||
$fieldname.type GAUGE
|
||||
$fieldname.info Total Credit for project $_->{name}
|
||||
EOF
|
||||
if ( exists $project_colour{ $_->{name} } ) {
|
||||
print "$fieldname.colour $project_colour{$_->{name}}\n";
|
||||
}
|
||||
}
|
||||
save_data(@projdata);
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my @projdata = load_data();
|
||||
foreach ( sort { $a->{id} <=> $b->{id} } @projdata ) {
|
||||
my $fieldname = 'proj' . $_->{id};
|
||||
print "$fieldname.value $_->{credit}\n";
|
||||
printf "$fieldname.extinfo %.2f%% of Total Credit (%.2f out of %.2f)\n",
|
||||
$_->{creditfract} * 100, $_->{credit}, $_->{totalcredit};
|
||||
}
|
||||
save_data(@projdata);
|
||||
exit 0;
|
Loading…
Reference in New Issue
Block a user