全部博文(1144)
分类: LINUX
2009-10-14 14:57:10
#!/usr/local/bin/perl use lib ('/export/web/ipanalyze.example.com/data/lib'); use strict; use GD; use DBI; use CGI qw(:standard); use GD::Graph::lines; use GD::Graph::pie; use IPAnalyze::Auth; use IPAnalyze::Misc; use IPAnalyze::IPmath; my %cfg; open(CONFIG, '/export/web/ipanalyze.example.com/data/ipanalyze.conf') || die "cannot open config: $!\n"; while(){ s/^(.*)\s*#.*/$1/; next if(/^$/); chomp; if(/^(\S+)\s*=>\s?(.+)/){ $cfg{$1} = $2; } } close CONFIG; my $d_dbh; until($d_dbh){ $d_dbh = DBI->connect ($cfg{d_dsn}, $cfg{d_dbun}, $cfg{d_dbpw}, {RaiseError => 1}); warn "$DBI::errstr\n" if($DBI::errstr); sleep 1; } my $q = new CGI(); my $auth = IPAnalyze::Auth->new(); my $misc = IPAnalyze::Misc->new(); my $ipmath = IPAnalyze::IPmath->new(); my $font = gdSmallFont; my ($cols,$rows) = (960,1800); # 80 As fit in 480 my $length = sprintf('%.0f',($cols/6)); my %e = ( 30 => 'A', 29 => 'B', 28 => 'C', 27 => 'D', 26 => 'E', 25 => 'F', 24 => 'G', 23 => 'H', 22 => 'I', 21 => 'J', 20 => 'K', 19 => 'L' ); if(my($username,$access) = $auth->check_access($d_dbh,$q,$cfg{app})){ unless($access > 0){ my @error = ("Access denied."); print $q->header(-expires=>'now'); $misc->show_error($cfg{html_dir},\@error); exit; } if($q->param('cidr')){ warn "creating utilization graph of CIDR allocations for ${username}\n"; my %cidr = (30 => $q->param('30'), 29 => $q->param('29'), 28 => $q->param('28'), 27 => $q->param('27'), 26 => $q->param('26'), 25 => $q->param('25'), 24 => $q->param('24'), ); my $graph = GD::Graph::pie->new(500,300); my @data = ( [ "/30", "/25", "/29", "/26", "/27", "/28", "/24"], [$cidr{30},$cidr{25},$cidr{29},$cidr{26},$cidr{27},$cidr{28},$cidr{24}], ); my $gd = $graph->plot(\@data) or die $graph->error; print $q->header(-type=>'image/png',-expires=>'now'); binmode STDOUT; print $gd->png; }elsif((defined(my $high=$q->param('high'))) && (defined(my $low=$q->param('low')))){ die "invalid high: $high\n" unless($high == int($high)); die "invalid low: $low\n" unless($low == int($low)); die "low must be le high\n" unless($low <= $high); warn "creating utilization graph of ${low}% to ${high}% for ${username}\n"; # to answer the question: # "how many customers are ge $low and le $high? " my $sql = 'SELECT usage_history FROM data WHERE enable_monitoring = 1'; my $sth = $d_dbh->prepare($sql); $sth->execute; my @entries; my (@zero,@low,@med,@high); while(my $row = $sth->fetchrow_arrayref){ my @history = (split /:/, $row->[0]); until(@history == 30){ unshift @history, undef; # most current is highest element } foreach(0..29){ if(defined($history[$_])){ if($q->param('all')){ if($history[$_] >= 80){ $high[$_]++; }elsif($history[$_] >= 40){ $med[$_]++; }elsif($history[$_] > 0){ $low[$_]++; }else{ $zero[$_]++; } }else{ if($history[$_] >= $low && $history[$_] <= $high){ $entries[$_]++; } } } } } my @data = ($q->param('all')) ? ([29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0], [@high], [@med], [@low], [@zero]) : ([29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0], [@entries]); my $y_label = 'Number of Networks'; $y_label .= " ge ${low} and le ${high}" unless($q->param('all')); my $graph = GD::Graph::lines->new(500,300); $graph->set(x_label => 'Days Ago', y_label => $y_label, x_label_position => 1/2, title => '30 Day Usage History', y_tick_number => 10, line_width => 2, x_label_skip => 0, dclrs => [ qw(lgreen lblue lyellow lred) ]) || die $graph->error; if($q->param('all')){ my @legend = qw/>=80% >=40% >0% 0%/; $graph->set_legend(@legend); } my $gd = $graph->plot(\@data); print $q->header(-type=>'image/png',-expires=>'now'); binmode STDOUT; print $gd->png; }elsif(my $netid = $q->param('netid')){ die "invalid netid: $netid from $ENV{'REMOTE_ADDR'}\n" unless($netid == int($netid)); warn "creating graph for ${username} netid ${netid}\n"; my $sql = 'SELECT usage_history FROM data WHERE netid = ' . $d_dbh->quote($netid); my $sth = $d_dbh->prepare($sql); $sth->execute; my $row = $sth->fetchrow_arrayref; my @history = (split /:/, $row->[0]); until(@history == 30){ unshift @history, undef; } my $graph = GD::Graph::lines->new(500,300); $graph->set(x_label => 'Days Ago', y_label => 'Percent Alive', title => '30 Day Usage History', x_label_position => 1/2, y_min_value => 0, y_max_value => 100, y_tick_number => 10, line_width => 2, x_label_skip => 0, dclrs => [ qw /black/ ]) || die $graph->error; my @data = ([29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0], [@history]); my $gd = $graph->plot(\@data); print $q->header(-type=>'image/png',-expires=>'now'); binmode STDOUT; print $gd->png; }elsif($q->param('utilizations')){ my $sql = 'SELECT netblock,cidr FROM data WHERE netblock IS NOT NULL'; my $sth = $d_dbh->prepare($sql); $sth->execute; my %used; while(my $row = $sth->fetchrow_arrayref){ $used{$row->[0]} = $row->[1]; } # now we have a built hash of what is in use # get info on what is total if($q->param('mode') eq 'full'){ $sql = 'SELECT netblock,cidr FROM grandparent_networks'; }else{ $sql = 'SELECT netblock,cidr FROM parent_networks'; } $sth = $d_dbh->prepare($sql); $sth->execute; my %total; while(my $row = $sth->fetchrow_arrayref){ $total{$row->[0]} = $row->[1]; } my ($string,@lines); my $r=0; for(map { $_->[0] } sort { $a->[1] <=> $b->[1] || $a->[2] <=> $b->[2] || $a->[3] <=> $b->[3] || $a->[4] <=> $b->[4] } map { [ $_, split /\./ ] } keys %total){ my @netblocks = $ipmath->get_netblocks($_,$total{$_},30); my ($skip,$l); foreach my $block (@netblocks){ $r++; if($skip){ $string .= $l; $skip--; }else{ if(my $cidr = $used{$block}){ $string .= $e{$cidr}; $l = $e{$cidr}; if($cidr != 30){ $skip = ((2 ** (30-$cidr)) - 1); # how many other 30s are in $cidr } }else{ $string .= 'U'; } } if($r == $length){ push @lines, $string; $string = undef; $r=0; } } } push @lines, $string if($string); my $im = new GD::Image($cols,$rows); my %c = ( 'white' => $im->colorAllocate(255,255,255), 'black' => $im->colorAllocate(0,0,0) ); $im->transparent($c{white}); $im->interlaced('true'); my $n=1; my $col=0; foreach my $line (@lines){ if($n > $rows){ # need bigger image warn "overflow: $col\n"; }else{ $im->string($font,1,$col,$line,$c{black}); $col += 10; } $n++; } my $line = 'Key: '; foreach my $key (reverse sort keys %e){ $line .= $e{$key} . ' = /' . $key . ', '; } chop($line); chop($line); $col += 10; $im->string($font,54,$col,$line,$c{black}); print $q->header(-type=>'image/png',-expires=>'now'); binmode STDOUT; print $im->png(); }else{ print $q->header(), $q->start_html(), "confused\n", $q->end_html(); } }else{ print $q->header(), $q->start_html(), "bad sess_id\n", $q->end_html(); }