1
0
Fork 0
mirror of https://github.com/munin-monitoring/contrib.git synced 2025-07-25 10:28:36 +00:00
Munin-Contrib/plugins/jenkins/jenkins_
Chris Butler bceabb82fb jenkins: Added support for jobs folders
Newer versions of Jenkins have support for grouping jobs into "folders",
for example when using a multibranch setup, the main "job" will actually
be a folder containing a job for each branch.

This changeset adds a "jobDepth" parameter that can be used to control
how far down the folder tree to report on.
2018-06-10 13:26:15 +02:00

199 lines
5.2 KiB
Perl
Executable file

#!/usr/bin/env perl
# -*- perl -*-
=head1 NAME
jenkins_ - Plugin for displaying Jenkins Stats
=head1 INTERPRETATION
This plugin displays the following charts:
1) The Status of each Build
2) Number of Jobs in the Build Queue
3) Number of Builds, currently running
You can set the modes with naming the softlink:
1) jenkins_results
2) jenkins_queue
3) jenkins_running
=head1 CONFIGURATION
This plugin is configurable environment variables.
env.url Jenkins Host
env.port Jenkins Port
env.context Jenkins Context path
env.user User for the API Tokent
env.apiToken Jenkins API Token (see https://wiki.jenkins-ci.org/display/JENKINS/Authenticating+scripted+clients)
env.jobDepth How far into job "folders" should the plugin check for jobs
Example:
[jenkins_*]
env.url localhost
env.port 4040
env.context /jenkins
env.user user
env.apiToken aaaa0f6e48b92cbbbbddecdb72dc1dad
=head1 AUTHOR
Philipp Haussleiter <philipp@haussleiter.de> (email)
=head1 LICENSE
GPLv2
=cut
# MAIN
use warnings;
use strict;
use JSON;
use File::Basename;
use URI;
# VARS
my $url = ($ENV{'url'} || 'localhost');
my $port = ($ENV{'port'} || '4040');
my $user = ($ENV{'user'} || '');
my $apiToken = ($ENV{'apiToken'} || '');
my $context = ($ENV{'context'} || '');
my $jobDepth = ($ENV{'jobDepth'} || 1);
my $wgetBin = "/usr/bin/wget";
my $type = basename($0);
$type =~ s/jenkins_//;
my %states = (
'blue' =>'stable',
'blue_anime' =>'stable',
'yellow'=>'unstable',
'yellow_anime'=>'unstable',
'red'=>'failing',
'red_anime'=>'failing',
'disabled'=>'disabled',
'notbuilt' => 'disabled',
'notbuilt_anime' =>'disabled',
'aborted'=>'failing',
'aborted_anime'=>'failing'
);
my $auth = ( $user ne "" and $apiToken ne "" ? " --auth-no-challenge --user=$user --password=$apiToken" : "" );
if ( exists $ARGV[0] and $ARGV[0] eq "config" ) {
if( $type eq "results" ) {
print "graph_args --base 1000 -l 0\n";
print "graph_title Jenkins Build Results\n";
print "graph_vlabel Build Results\n";
print "graph_category devel\n";
print "graph_info The Graph shows the Status of each Build\n";
print "build_disabled.draw AREA\n";
print "build_disabled.label disabled\n";
print "build_disabled.type GAUGE\n";
print "build_disabled.colour 8A8A8A\n";
print "build_failing.draw STACK\n";
print "build_failing.label failing\n";
print "build_failing.type GAUGE\n";
print "build_failing.colour E61217\n";
print "build_unstable.draw STACK\n";
print "build_unstable.label unstable\n";
print "build_unstable.type GAUGE\n";
print "build_unstable.colour F3E438\n";
print "build_stable.draw STACK\n";
print "build_stable.label stable\n";
print "build_stable.type GAUGE\n";
print "build_stable.colour 294D99\n";
exit;
}
if( $type eq "queue" ) {
print "graph_args --base 1000 -l 0\n";
print "graph_title Jenkins Queue Length\n";
print "graph_vlabel Number of Jobs in Queue\n";
print "graph_category devel\n";
print "graph_info The Graph shows the Number of Jobs in the Build Queue\n";
print "build_count.label Jobs in Queue\n";
print "build_count.type GAUGE\n";
exit;
}
if( $type eq "running" ) {
print "graph_args --base 1000 -l 0\n";
print "graph_title Jenkins Builds Running\n";
print "graph_vlabel Builds currently running\n";
print "graph_category devel\n";
print "graph_info The Graph shows the Number of Builds, currently running\n";
print "build_running.label running Builds\n";
print "build_running.type GAUGE\n";
exit;
}
} else {
my $cmd = "$wgetBin $auth -qO- $url:$port$context";
my $tree = 'jobs[name,color]';
for (2..$jobDepth) {
$tree = "jobs[name,color,$tree]";
}
if( $type eq "results" ) {
my $result = `$cmd'/api/json?depth=$jobDepth&tree=$tree'`;
my $parsed = decode_json($result);
my $counts = parse_results($parsed->{'jobs'});
foreach my $status (keys %{$counts}) {
print "build_$status.value $counts->{$status}\n";
}
exit;
}
if( $type eq "running" ) {
my $result = `$cmd'/api/json?depth=$jobDepth&tree=$tree'`;
my $parsed = decode_json($result);
my $count = parse_running_builds($parsed->{'jobs'});
print "build_running.value ", $count, "\n";
exit;
}
if( $type eq "queue" ) {
my $result = `$cmd/queue/api/json`;
my $parsed = decode_json($result);
print "build_count.value ", scalar( @{$parsed->{'items'}} ), "\n";
exit;
}
}
sub parse_running_builds {
my $builds = shift;
my $count = 0;
foreach my $cur (@{$builds}) {
if( defined($cur->{'jobs'}) ) {
$count += parse_running_builds($cur->{'jobs'});
} elsif( defined ($cur->{'color'}) and $cur->{'color'} =~ /anime$/ ) {
$count += 1;
}
}
return $count;
}
sub parse_results {
my $builds = shift;
my %counts = ('stable' => 0, 'unstable' => 0, 'failing' => 0, 'disabled' => 0);
foreach my $cur(@{$builds}) {
if( defined($cur->{'jobs'}) ) {
my $new_counts = parse_results($cur->{'jobs'});
foreach my $new_count_key (keys %{$new_counts}) {
$counts{$new_count_key} += $new_counts->{$new_count_key};
}
} elsif (defined($cur->{'color'})) {
if (defined($states{$cur->{'color'}})) {
$counts{$states{$cur->{'color'}}} += 1;
} else {
warn "Ignoring unknown color " . $cur->{'color'} . "\n"
}
}
}
return \%counts;
}