Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5379464
  • 博文数量: 1144
  • 博客积分: 11974
  • 博客等级: 上将
  • 技术积分: 12312
  • 用 户 组: 普通用户
  • 注册时间: 2005-04-13 20:06
文章存档

2017年(2)

2016年(14)

2015年(10)

2014年(28)

2013年(23)

2012年(29)

2011年(53)

2010年(86)

2009年(83)

2008年(43)

2007年(153)

2006年(575)

2005年(45)

分类: 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();
}
阅读(2032) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~