#!/usr/bin/env perl use strict; use warnings; use LWP::Simple; use Data::Dumper; use RRD::Simple (); use LWP::UserAgent; use LWP::Protocol::socks; my $rrd_path = "/srv/appdrift"; my $score_url = "http://128.39.121.4/purser/scoreboard.txt"; my @group_colors = qw( 003300 003366 0000FF 66FF66 669999 666699 FF99FF 9900CC 660066 660033 FF0000 663300 FFCCCC 66FFFF 993333 000066 3366CC CC00CC 800000 CC0099 ); # Check if string is in array sub in_array { my $str = shift; my $arr = shift; my %a = map { $_ => 1 } @{$arr}; return 1 if (exists $a{$str}); return 0; } my $group_info = {}; my @group_names = (); my $content = get($score_url); if (!defined($content) || !$content || length $content < 1) { print STDERR "Could not fetch scoreboard!"; exit 1; } my @content = split /^-+$/m, $content; shift @content; if (scalar @content < 1) { print STDERR "Scoreboard seems to be empty!"; exit 1; } for my $section (@content) { my ($position, $user, $balance, $endpoint, $time_up, $time_maint, $time_down) = (undef); for my $line (split /\n/, $section) { next if (length $line < 1); if ($line =~ /Position: (.*)/i) { $position = $1; } elsif ($line =~ /User: (.*)/i) { $1 =~ /gruppe(\d+)/; $user = sprintf("gruppe%02d", $1); } elsif ($line =~ /Balance: (.*)/i) { $balance = $1; } elsif ($line =~ /Endpoint: (.*)/i) { $endpoint = $1; } elsif ($line =~ /time_up: (.*)/i) { $time_up = $1; } elsif ($line =~ /time_maint: (.*)/i) { $time_maint = $1; } elsif ($line =~ /time_down: (.*)/i) { $time_down = $1; } } $group_info->{'rrd_groups'}->{$user} = "GAUGE"; $group_info->{'position'}->{$user} = $position; $group_info->{'balance'}->{$user} = $balance; $group_info->{'uptime'}->{$user} = $time_up; $group_info->{'downtime'}->{$user} = $time_down; $group_info->{'maintenance'}->{$user} = $time_maint; $group_info->{'server'}->{$user} = $endpoint; } @group_names = sort keys %{$group_info->{'rrd_groups'}}; $#group_colors = $#group_names; for my $group (@group_names) { my ($users, $posts, $comments) = (undef); my $content = get("http://".$group_info->{'server'}->{$group}); if (defined($content) && length $content > 1) { for my $line (split /\n/, $content) { last if (defined($users) && defined($posts) && defined($comments)); last if ($line =~ /Last activity/i); next if (length $line < 1); if ($line =~ /Users:[^0-9]*(\d+)/i) { $users = $1; } elsif ($line =~ /Posts:[^0-9]*(\d+)/i) { $posts = $1; } elsif ($line =~ /Comments:[^0-9]*(\d+)/i) { $comments = $1; } } } $group_info->{'users'}->{$group} = $users; $group_info->{'posts'}->{$group} = $posts; $group_info->{'comments'}->{$group} = $comments; } my %g_rrd_info = ( destination => "$rrd_path/graph", periods => [ qw(day week month) ], interlaced => "", extended_legend => "true", timestamp => "both", ); for my $group (@group_names) { my %rrd_info = %g_rrd_info; $rrd_info{'destination'} = "$rrd_path/graph/$group"; my $uptime_rrd = RRD::Simple->new( file => "$rrd_path/rrd/$group-uptime.rrd" ); my $users_rrd = RRD::Simple->new( file => "$rrd_path/rrd/$group-users.rrd" ); mkdir "$rrd_path/graph/$group" unless ( -d "$rrd_path/graph/$group" ); $uptime_rrd->create(uptime => "GAUGE", maintenance => "GAUGE", downtime => "GAUGE") unless ( -f "$rrd_path/rrd/$group-uptime.rrd" ); $users_rrd->create(users => "GAUGE", maintenance => "GAUGE", downtime => "GAUGE") unless ( -f "$rrd_path/rrd/$group-users.rrd" ); $uptime_rrd->update( uptime => $group_info->{'uptime'}->{$group}, maintenance => $group_info->{'maintenance'}->{$group}, downtime => $group_info->{'downtime'}->{$group}, ); $users_rrd->update( users => $group_info->{'users'}->{$group}, posts => $group_info->{'posts'}->{$group}, comments => $group_info->{'comments'}->{$group}, ); $uptime_rrd->graph( %rrd_info, basename => "all-times", sources => [ qw(uptime maintenance downtime) ], source_colors => [ qw(00CC00 0000FF FF0000) ], title => "Time stats group: $group", vertical_label => "Time/seconds", ); $uptime_rrd->graph( %rrd_info, basename => "uptime", sources => [ qw(uptime) ], source_colors => [ qw(00CC00) ], title => "Uptime stats group: $group", vertical_label => "Time/seconds", ); $uptime_rrd->graph( %rrd_info, basename => "maintenance", sources => [ qw(maintenance) ], source_colors => [ qw(0000FF) ], title => "Uptime stats group: $group", vertical_label => "Time/seconds", ); $uptime_rrd->graph( %rrd_info, basename => "downtime", sources => [ qw(downtime) ], source_colors => [ qw(FF0000) ], title => "Uptime stats group: $group", vertical_label => "Time/seconds", ); $users_rrd->graph( %rrd_info, basename => "all-user-stats", sources => [ qw(users posts comments) ], source_colors => [ qw(00CC00 0000FF FF0000) ], title => "Users/Posts/Comments for $group", vertical_label => "Count", ); $users_rrd->graph( %rrd_info, basename => "users", sources => [ qw(users) ], source_colors => [ qw(00CC00) ], title => "User count for $group", vertical_label => "Nr. of users", ); $users_rrd->graph( %rrd_info, basename => "posts", sources => [ qw(posts) ], source_colors => [ qw(0000FF) ], title => "Post count for $group", vertical_label => "Nr. of posts", ); $users_rrd->graph( %rrd_info, basename => "comments", sources => [ qw(comments) ], source_colors => [ qw(FF0000) ], title => "Comment count for $group", vertical_label => "Nr. of comments", ); } my $pos_rrd = "$rrd_path/rrd/positions.rrd"; my $bal_rrd = "$rrd_path/rrd/balance.rrd"; my $upt_rrd = "$rrd_path/rrd/uptime.rrd"; my $dwn_rrd = "$rrd_path/rrd/downtime.rrd"; my $mnt_rrd = "$rrd_path/rrd/maintenance.rrd"; my $usr_rrd = "$rrd_path/rrd/users.rrd"; my $pst_rrd = "$rrd_path/rrd/posts.rrd"; my $cmt_rrd = "$rrd_path/rrd/comments.rrd"; my $position_rrd = RRD::Simple->new( file => "$pos_rrd" ); my $balance_rrd = RRD::Simple->new( file => "$bal_rrd" ); my $uptime_rrd = RRD::Simple->new( file => "$upt_rrd" ); my $downtime_rrd = RRD::Simple->new( file => "$dwn_rrd" ); my $maint_rrd = RRD::Simple->new( file => "$mnt_rrd" ); my $user_rrd = RRD::Simple->new( file => "$usr_rrd" ); my $post_rrd = RRD::Simple->new( file => "$pst_rrd" ); my $comment_rrd = RRD::Simple->new( file => "$cmt_rrd" ); $position_rrd->create(%{$group_info->{'rrd_groups'}}) unless ( -f "$pos_rrd" ); $balance_rrd->create(%{$group_info->{'rrd_groups'}}) unless ( -f "$bal_rrd" ); $uptime_rrd->create(%{$group_info->{'rrd_groups'}}) unless ( -f "$upt_rrd" ); $downtime_rrd->create(%{$group_info->{'rrd_groups'}}) unless ( -f "$dwn_rrd" ); $maint_rrd->create(%{$group_info->{'rrd_groups'}}) unless ( -f "$mnt_rrd" ); $user_rrd->create(%{$group_info->{'rrd_groups'}}) unless ( -f "$usr_rrd" ); $post_rrd->create(%{$group_info->{'rrd_groups'}}) unless ( -f "$pst_rrd" ); $comment_rrd->create(%{$group_info->{'rrd_groups'}}) unless ( -f "$cmt_rrd" ); my @pos_sources = $position_rrd->sources("$pos_rrd"); my @bal_sources = $balance_rrd->sources("$bal_rrd"); my @upt_sources = $uptime_rrd->sources("$upt_rrd"); my @dwn_sources = $downtime_rrd->sources("$dwn_rrd"); my @mnt_sources = $maint_rrd->sources("$mnt_rrd"); my @usr_sources = $user_rrd->sources("$usr_rrd"); my @pst_sources = $user_rrd->sources("$pst_rrd"); my @cmt_sources = $comment_rrd->sources("$cmt_rrd"); for my $group (@group_names) { $position_rrd->add_source("$pos_rrd", $group => $group_info->{'rrd_groups'}->{$group}) unless (in_array($group, \@pos_sources)); $balance_rrd->add_source("$bal_rrd", $group => $group_info->{'rrd_groups'}->{$group}) unless (in_array($group, \@bal_sources)); $uptime_rrd->add_source("$upt_rrd", $group => $group_info->{'rrd_groups'}->{$group}) unless (in_array($group, \@upt_sources)); $downtime_rrd->add_source("$dwn_rrd", $group => $group_info->{'rrd_groups'}->{$group}) unless (in_array($group, \@dwn_sources)); $maint_rrd->add_source("$mnt_rrd", $group => $group_info->{'rrd_groups'}->{$group}) unless (in_array($group, \@mnt_sources)); $user_rrd->add_source("$usr_rrd", $group => $group_info->{'rrd_groups'}->{$group}) unless (in_array($group, \@usr_sources)); $post_rrd->add_source("$pst_rrd", $group => $group_info->{'rrd_groups'}->{$group}) unless (in_array($group, \@pst_sources)); $comment_rrd->add_source("$cmt_rrd", $group => $group_info->{'rrd_groups'}->{$group}) unless (in_array($group, \@cmt_sources)); } $position_rrd->update(%{$group_info->{'position'}}); $balance_rrd->update(%{$group_info->{'balance'}}); $uptime_rrd->update(%{$group_info->{'uptime'}}); $downtime_rrd->update(%{$group_info->{'downtime'}}); $maint_rrd->update(%{$group_info->{'maintenance'}}); $user_rrd->update(%{$group_info->{'users'}}); $post_rrd->update(%{$group_info->{'posts'}}); $comment_rrd->update(%{$group_info->{'comments'}}); $g_rrd_info{'sources'} = [ @group_names ]; $g_rrd_info{'source_colors'} = [ @group_colors ]; $position_rrd->graph( %g_rrd_info, basename => "positions", title => "Positions", vertical_label => "Position", ); $balance_rrd->graph( %g_rrd_info, basename => "balance", title => "Balances", vertical_label => "Balance", ); $uptime_rrd->graph( %g_rrd_info, basename => "uptime", title => "Uptime per group", vertical_label => "Uptime/seconds", ); $downtime_rrd->graph( %g_rrd_info, basename => "downtime", title => "Downtime per group", vertical_label => "Downtime/seconds", ); $maint_rrd->graph( %g_rrd_info, basename => "maintenance", title => "Maintenance per group", vertical_label => "Maintenance/seconds", ); $uptime_rrd->graph( %g_rrd_info, basename => "uptime", title => "Uptime per group", vertical_label => "Uptime/seconds", ); $user_rrd->graph( %g_rrd_info, basename => "users", title => "Number of users per group", vertical_label => "Nr. of users", ); $post_rrd->graph( %g_rrd_info, basename => "posts", title => "Number of posts per group", vertical_label => "Nr. of posts", ); $comment_rrd->graph( %g_rrd_info, basename => "comments", title => "Number of comments per group", vertical_label => "Nr. of comments", ); delete $g_rrd_info{'sources'}; delete $g_rrd_info{'source_colors'}; for my $group (@group_names) { my %rrd_info = %g_rrd_info; $rrd_info{'destination'} = "$rrd_path/graph/$group"; $balance_rrd->graph( %rrd_info, basename => "balance", sources => [ $group ], source_colors => [ qw(00CC00) ], title => "Balance for $group", vertical_label => "Balance", ); $position_rrd->graph( %rrd_info, basename => "position", sources => [ $group ], source_colors => [ qw(00CC00) ], title => "Position for $group", vertical_label => "Position", ); }