mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 19:32:31 +00:00 
			
		
		
		
	git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@12572 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
		
			
				
	
	
		
			473 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			473 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env perl
 | |
| # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
 | |
| package xCAT_monitoring::rmcmetrix;
 | |
| #Modules to use:
 | |
| #use threads;
 | |
| #use threads::shared;
 | |
| 
 | |
| BEGIN
 | |
| {
 | |
|   $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
 | |
| }
 | |
| 
 | |
| use lib "$::XCATROOT/lib/perl";
 | |
| use xCAT::Table;
 | |
| use xCAT::Utils;
 | |
| use xCAT_monitoring::rrdutil;
 | |
| 
 | |
| 1;
 | |
| #metrix{Attr}{NodeNameList}{Name} = value
 | |
| #NodeNameList could be NodeNameList | summary | number
 | |
| #Attr	could be Attribute | summary | number
 | |
| %metrix={};
 | |
| 
 | |
| ######################################
 | |
| #sub print_metrix
 | |
| #Description:
 | |
| #	to print all content of %metrix, for debug
 | |
| #Input:
 | |
| #	None
 | |
| #Return:
 | |
| #	None
 | |
| #####################################
 | |
| sub print_metrix
 | |
| {
 | |
| 	my $key1;
 | |
| 	my $key2;
 | |
| 	my $key3;
 | |
| 	my $value;
 | |
| 	while(($key1, $key2) = each %metrix){
 | |
| 		if(! exists($metrix{$key1}{$key2})){
 | |
| 			print "$key1=>$key2\n";
 | |
| 			next;
 | |
| 		}
 | |
| 		while(($key2, $key3) = each %{$metrix{$key1}}){
 | |
| 			if(! exists($metrix{$key1}{$key2}{$key3})){
 | |
| 				print "$key1.$key2=>$key3\n";
 | |
| 			}
 | |
| 			while(($key3, $value) = each %{$metrix{$key1}{$key2}}){
 | |
| 				print "$key1.$key2.$key3=>$value\n";
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| }
 | |
| 
 | |
| #######################################
 | |
| #sub update_metrix2rrd
 | |
| #Description:
 | |
| #	update RRDtool database based on content of %metrix,
 | |
| #	all statistic be stored as GAUGE in RRDtool,
 | |
| #Input:
 | |
| #	$step the base interval in seconds with which data will be fed into the RRD
 | |
| #Return:
 | |
| #	None
 | |
| #####################################
 | |
| 
 | |
| sub update_metrix2rrd
 | |
| {
 | |
| 	my $step = shift @_;
 | |
| 	my $ret = 0;
 | |
| 	my $attr;
 | |
| 	my $nnlist;
 | |
| 	my $name;
 | |
| 	my $value;
 | |
| 	my $rmcrrdroot = "/var/rrd";
 | |
| 	my $rrddir = undef;
 | |
| 	my $rrd = undef;
 | |
| 	my $process_time = xCAT::Utils->runcmd("date +%s", 0);
 | |
| 	$process_time = (int $process_time/$step)*$step;
 | |
| 	my $temp = undef;
 | |
| 
 | |
| 	while(($attr, $nnlist) = each %metrix){
 | |
| 		while(($nnlist, $name) = each %{$metrix{$attr}}){
 | |
| 			if($nnlist eq 'number'){
 | |
| 				next;
 | |
| 			}
 | |
| 			$rrddir = "$rmcrrdroot/$nnlist";
 | |
| 			if(! -d $rrddir){
 | |
| 				xCAT::Utils->runcmd("mkdir -p $rrddir");
 | |
| 			}
 | |
| 			if($nnlist eq 'summary'){
 | |
| 				$rrd = "$rrddir/"."$attr.rrd";
 | |
| 				$temp = $metrix{$attr}{summary}/$metrix{$attr}{number};
 | |
| 				$ret = xCAT_monitoring::rrdutil::push_data_to_rrd($rrd, $temp, $metrix{$attr}{number}, $step, $process_time, 'GAUGE');
 | |
| 				if($ret != 0){
 | |
| 					return ($ret, "Can't push data to $rrd\n");
 | |
| 				}
 | |
| 			} else {
 | |
| 				while(($name, $value) = each %{$metrix{$attr}{$nnlist}}){
 | |
| 					if($name eq 'number'){
 | |
| 						next;
 | |
| 					}
 | |
| 					if($name eq 'summary'){
 | |
| 						$rrd = "$rrddir/$attr.rrd";
 | |
| 						$temp = $metrix{$attr}{$nnlist}{summary}/$metrix{$attr}{$nnlist}{number};
 | |
| 						$ret = xCAT_monitoring::rrdutil::push_data_to_rrd($rrd, $temp, $metrix{$attr}{$nnlist}{number}, $step, $process_time, 'GAUGE');
 | |
| 						if($ret != 0){
 | |
| 							return($ret, "Can't push data to $rrd\n");
 | |
| 						}
 | |
| 					} else {
 | |
| 						$rrd = "$rrddir/$attr"."_$name.rrd";
 | |
| 						xCAT_monitoring::rrdutil::push_data_to_rrd($rrd, $metrix{$attr}{$nnlist}{$name}, 'null', $step, $process_time, 'GAUGE');
 | |
| 						if($ret != 0){
 | |
| 							return($ret, "Can't push data to $rrd\n");
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	return (0, "Success");
 | |
| 
 | |
| }
 | |
| 
 | |
| ######################################
 | |
| #sub parse_lsrsrc_output
 | |
| #Description:
 | |
| #	parse the output of lsrsrc and store the information to %metrix
 | |
| #Input:
 | |
| #	resource class
 | |
| #	array of attributes
 | |
| #	array of output of lsrsrc command
 | |
| #Return:
 | |
| #	0 Success
 | |
| #	!0 Fail
 | |
| #####################################
 | |
| sub parse_lsrsrc_output
 | |
| {
 | |
| 	my ($rsrc, $pattr, $output) = @_;
 | |
| 	my $nnlist = undef;
 | |
| 	my $name = undef;
 | |
| 	my $line = undef;
 | |
| 	my $attr = undef;
 | |
| 	my @value = ();
 | |
| 	my $i = undef; 
 | |
| 	my %count = {};
 | |
| 	
 | |
| 	foreach $line (@$output){
 | |
| 	    if ($line =~ /^ERROR/) { next;}   #skip the lines with error
 | |
| 		@value = split /::/, $line;
 | |
| 		$name = $value[0];
 | |
| 		$name =~ s/[^A-Za-z0-9]+/'.'/;
 | |
| 		if($name eq ''){
 | |
| 			$name = 'null';
 | |
| 		}
 | |
| 		$value[1] =~ /{(\w+)}/;
 | |
| 		$nnlist = $1;
 | |
| 		$i = 2;
 | |
| 		foreach $attr (@$pattr){
 | |
| 			if($rsrc eq 'IBM.Processor'){
 | |
| 				$metrix{$attr}{$nnlist}{$name} += $value[$i];
 | |
| 			} else {
 | |
| 				$metrix{$attr}{$nnlist}{$name} = $value[$i];
 | |
| 			}
 | |
| 			$metrix{$attr}{$nnlist}{summary} += $value[$i];
 | |
| 			$metrix{$attr}{$nnlist}{number} += 1;
 | |
| 			$i++;
 | |
| 		}
 | |
| 		if($rsrc eq 'IBM.Processor'){
 | |
| 			$count{$nnlist}{$name} += 1;
 | |
| 		}
 | |
| 	}
 | |
| 	if($rsrc eq 'IBM.Processor'){
 | |
| 		foreach $nnlist (keys %count){
 | |
| 			foreach $name (keys %{$count{$nnlist}}){
 | |
| 				if ($count{$nnlist}{$name} > 1) {
 | |
| 					foreach $attr (@$pattr){
 | |
| 						$metrix{$attr}{$nnlist}{$name} /= $count{$nnlist}{$name};
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	
 | |
| 	return 0;
 | |
| 
 | |
| }
 | |
| 
 | |
| ######################################
 | |
| #sub getmetrix
 | |
| #Description:
 | |
| #	Get %metrix using lsrsrc-api, and store to RRD
 | |
| #Input:
 | |
| #	$rsrc	the resource class of RMC, such as "IBM.EthernetDevice"
 | |
| #	$rname	the resource name of resouce class, if ($rname eq "__ALL__") then all
 | |
| #		resource name will be monitoring
 | |
| #	$attrlist the list of attributes of the monitoring resource
 | |
| #	$minute the interval to collect data in minute
 | |
| #Return:
 | |
| #	0 Success
 | |
| #	!0 Fail
 | |
| #####################################
 | |
| sub getmetrix
 | |
| {
 | |
| 	my ($rsrc, $rname, $attrlist, $minute) = @_;
 | |
| 	my @attrs = ();
 | |
| 	my $attr = undef;
 | |
| 	my $nnlist = undef;
 | |
| 	my @names = ();
 | |
| 	my $name = undef;
 | |
| 	my @output = ();
 | |
| 	my $rrd = undef;
 | |
| 	my $line = undef;
 | |
| 	my $ret = 0;
 | |
| 	my $msg = undef;
 | |
| 	my $cmd = undef;
 | |
| 
 | |
| 	@attrs = split /,/, $attrlist;
 | |
| 	
 | |
| 	$attr = join '::', @attrs;
 | |
| #	if(xCAT::Utils->isMN()){
 | |
| #		if($rname eq "__ALL__"){
 | |
| #			$cmd = "CT_MANAGEMENT_SCOPE=1 lsrsrc-api -i -s $rsrc"."::::Name::NodeNameList::$attr";
 | |
| #			@output = xCAT::Utils->runcmd($cmd, 0);
 | |
| #			if($::RUNCMD_RC  != 0){
 | |
| #				$line = join '', @output;
 | |
| #				return ($::RUNCMD_RC, $line);
 | |
| #			}
 | |
| #			&parse_lsrsrc_output($rsrc, \@attrs, \@output);
 | |
| #		} else {
 | |
| #			@names = split /,/, $rname;
 | |
| #			foreach $name (@names){
 | |
| #				$cmd = "CT_MANAGEMENT_SCOPE=1 lsrsrc-api -i -s $rsrc"."::\'Name==\"$name\"\'::Name::NodeNameList::$attr";
 | |
| #				@output = xCAT::Utils->runcmd($cmd, 0);
 | |
| #				if($::RUNCMD_RC != 0){
 | |
| #					$line = join '', @output;
 | |
| #					return ($::RUNCMD_RC, $line);
 | |
| #				}
 | |
| #				&parse_lsrsrc_output($rsrc, \@attrs, \@output);
 | |
| #			}
 | |
| #		}
 | |
| #	}
 | |
| 
 | |
| 	if($rname eq "__ALL__"){
 | |
| 		$cmd = "CT_MANAGEMENT_SCOPE=3 lsrsrc-api -i -s $rsrc"."::::Name::NodeNameList::$attr";
 | |
| 		@output = xCAT::Utils->runcmd($cmd, -1);
 | |
| 		#if($::RUNCMD_RC != 0){
 | |
| 		#	$line = join '', @output;
 | |
| 		#	return ($::RUNCMD_RC, $line);
 | |
| 		#}
 | |
|                 #print "+++++ rsrc=$rsrc\nattrs=@attrs\noutput=@output\n";
 | |
| 		&parse_lsrsrc_output($rsrc, \@attrs, \@output);
 | |
| 	} else {
 | |
| 		@names = split /,/, $rname;
 | |
| 		foreach $name (@names){
 | |
| 			$cmd = "CT_MANAGEMENT_SCOPE=3 lsrsrc-api -i -s $rsrc"."::\'Name==\"$name\"\'::Name::NodeNameList::$attr";
 | |
| 			@output = xCAT::Utils->runcmd($cmd, -1);
 | |
| 			#if($::RUNCMD_RC){
 | |
| 			#	$line = join '', @output;
 | |
| 			#	return ($::RUNCMD_RC, $line);
 | |
| 			#}
 | |
|                         #print "--- rsrc=$rsrc\nattrs=@attrs\noutput=@output\n";
 | |
| 			&parse_lsrsrc_output($rsrc, \@attrs, \@output);
 | |
| 		}
 | |
| 	}
 | |
| 	foreach $attr (keys %metrix){
 | |
| 		foreach $nnlist (keys %{$metrix{$attr}}){
 | |
| 			if(($nnlist ne 'summary') && ($nnlist ne 'number')){
 | |
| 				$metrix{$attr}{summary} += $metrix{$attr}{$nnlist}{summary};
 | |
| 				$metrix{$attr}{number} += $metrix{$attr}{$nnlist}{number};
 | |
| 			}
 | |
| 			
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	my $step = $minute * 60;
 | |
| 	($ret, $msg) = &update_metrix2rrd($step);
 | |
| 	
 | |
| 	return ($ret, $msg);
 | |
| }
 | |
| 
 | |
| ######################################
 | |
| #sub get_metrix_conf
 | |
| #Description:
 | |
| #	Get configure for table monsetting, and return an array 
 | |
| #Input:
 | |
| #	None;
 | |
| #Return:
 | |
| #	an array of configuration (rsrc0, attrlist0, minute0, rsrc1, attrlist1,minute1, ...)
 | |
| #####################################
 | |
| sub get_metrix_conf
 | |
| {
 | |
| 	my @conf = ();
 | |
| 	my @tmp = ();
 | |
| 	my $rsrc = undef;
 | |
| 	my $namelist = undef;
 | |
| 	my $attrlist = undef;
 | |
| 	my $minute = undef;
 | |
| 	my $key = undef;
 | |
| 	my $value = undef;
 | |
| 	my $conftable = xCAT::Table->new('monsetting');
 | |
| 	if($conftable){
 | |
| 		@tmp = $conftable->getAttribs({'name'=>'rmcmon'}, ('key','value'));
 | |
| 		foreach (@tmp) {
 | |
| 			$key = $_->{key};
 | |
| 			$value = $_->{value};
 | |
| 			if($key =~ /^rmetrics_(\S+)/){
 | |
| 				push @conf, $1;
 | |
| 				if($value =~ /\]/){
 | |
| 					($namelist, $value) = split /\]/, $value;
 | |
| 					$namelist =~ s/\[//;
 | |
| 				} else {
 | |
| 					$namelist = "__ALL__";
 | |
| 				}
 | |
| 				push @conf, $namelist;
 | |
| 
 | |
| 				($attrlist, $minute) = split /:/, $value;
 | |
| 				push @conf, $attrlist;
 | |
| 				push @conf, $minute;
 | |
| 			}
 | |
| 		}
 | |
| 		$conftable->close;
 | |
| 	}
 | |
| 	return @conf;
 | |
| }
 | |
| 
 | |
| ######################################
 | |
| #sub get_sum_metrix
 | |
| #Description:
 | |
| #	Consolidates data collected by SNs and MN  and stores to local RRD
 | |
| #Input:
 | |
| #	$attrlist the list of attributes of the monitoring resource
 | |
| #Return:
 | |
| #	0 Success
 | |
| #	!0 Fail
 | |
| #####################################
 | |
| sub get_sum_metrix
 | |
| {
 | |
| 	my $code = undef;
 | |
| 	my $msg = undef;
 | |
| 	my ($attrlist, $minute) = @_;
 | |
| 	my $result = undef;
 | |
| 	my @rmc_nodes = ();
 | |
| 	my @svc_nodes = ();
 | |
| 	my $node = undef;
 | |
| 	my $temp = undef;
 | |
| #	my @threads = ();
 | |
| #	my $current_thread = 0;
 | |
| 	my $i = undef;
 | |
| #	my %summary:shared; #summary{$attr}{$node}
 | |
| 	my %summary = {};
 | |
| 	my @attributes = ();
 | |
| 	my $attribute = undef;
 | |
| 	my $nodename = undef;
 | |
| 	my $time = undef;
 | |
| #	my $end:shared;
 | |
|     my %summetrix = {};
 | |
| 	my $end = undef;
 | |
|        	$end = xCAT::Utils->runcmd("date +%s", 0);
 | |
| #	my $step:shared;
 | |
| 	my $step = undef;
 | |
| 	$step = $minute * 60;
 | |
| 	#to share %summary
 | |
| 	@attributes = split /,/, $attrlist;
 | |
| #	foreach $attribute (@attributes){
 | |
| #		$summary{$attribute} = &share({});
 | |
| #	}
 | |
| 	$result = `lsrsrc-api -s IBM.MngNode::::Name 2>&1`;
 | |
| 	chomp($result);
 | |
| 	@rmc_nodes=split(/\n/, $result);
 | |
| 	foreach $node (@rmc_nodes){
 | |
| 		if(xCAT::Utils->isSN($node)){
 | |
| 			push @svc_nodes, $node;
 | |
| 		}
 | |
| 	}
 | |
| 	$node = `hostname`;
 | |
| 	chomp($node);
 | |
| 	push @svc_nodes, $node;
 | |
| 	foreach $node (@svc_nodes){
 | |
| #		$threads[$current_thread] = threads->new(\&getsum, $attrlist, $node);
 | |
| #		$current_thread++;
 | |
| 		&getsum($attrlist, $node);
 | |
| 	}
 | |
| 
 | |
| 	sub getsum{
 | |
| 		my ($attrs, $n) = @_;
 | |
| 		my @attr = split /,/,$attrs;
 | |
| 		my $a = undef;
 | |
| 		my $start = undef;
 | |
| 		my $result = undef;
 | |
| 		my $timestamp = undef;
 | |
| 		my $sum = undef;
 | |
| 		my $num = undef;
 | |
| 		my $localhost = `hostname`;
 | |
| 		chomp($localhost);
 | |
| 		foreach $a (@attr){
 | |
| 			if(-f "/var/rrd/cluster/$a.rrd"){
 | |
| 				$start = `rrdtool last /var/rrd/cluster/$a.rrd`;
 | |
| 				chomp($start);
 | |
| 			} else {
 | |
| 				$start = ((int $end/$step) - 244)*$step;
 | |
| 			}
 | |
| 			if($n eq $localhost){
 | |
| 				$result = xCAT_monitoring::rrdutil::RRD_fetch("/var/rrd/summary/$a.rrd",$start, $end);
 | |
| 			} else {
 | |
| 				$result = xCAT_monitoring::rrdutil::RRD_fetch("summary/$a.rrd",$start, $end, $n);
 | |
| 			}
 | |
| 			my $line = pop(@$result);
 | |
| 			if($line =~ /ERROR/){
 | |
| 				return (-1, $line);
 | |
| 			} else {
 | |
| 				push @$result, $line;
 | |
| 			}
 | |
| #			$summary{$a}{$n} = &share({});
 | |
| 			foreach $line (@$result){
 | |
| 				if($line =~ /[NaNQ|nan]/){
 | |
| 					next;
 | |
| 				} elsif ($line =~ /^(\d+): (\S+) (\S+)/){
 | |
| 					$timestamp = $1;
 | |
| 					$sum = $2;
 | |
| 					$num = $3;
 | |
| #					$summary{$a}{$n}{$timestamp} = &share({});
 | |
| #					$summary{$a}{$n}{$timestamp}{sum} = &share({});
 | |
| #					$summary{$a}{$n}{$timestamp}{num} = &share({});
 | |
| 					$summetrix{$a}{$timestamp}{sum} += $sum * $num;
 | |
| 					$summetrix{$a}{$timestamp}{num} += $num;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		return (0, 'Success');
 | |
| 	}
 | |
| 	
 | |
| #	for($i=0; $i<$current_thread; $i++){
 | |
| #		($code, $msg) = $threads[$i]->join();
 | |
| #		if($code != 0){
 | |
| #			warn("$msg\n");
 | |
| #		}
 | |
| #	}
 | |
| 
 | |
| #	my %summetrix = {};
 | |
| #	foreach $attribute (keys %summary){
 | |
| #		foreach $nodename (keys %{$summary{$attribute}}){
 | |
| #			foreach $time (keys %{$summary{$attribute}{$nodename}}){
 | |
| #				print "$attribute.$nodename.$time $summary{$attribute}{$nodename}{$time}{sum} $summary{$attribute}{$nodename}{$time}{num}\n";
 | |
| #				$temp = $summary{$attribute}{$nodename}{$time}{sum} * $summary{$attribute}{$nodename}{$time}{num};
 | |
| #				$summetrix{$attribute}{$time}{sum} += $temp;
 | |
| #				$summetrix{$attribute}{$time}{num} += $summary{$attribute}{$nodename}{$time}{num};
 | |
| #			}
 | |
| #		}
 | |
| 		
 | |
| #	}
 | |
| 
 | |
| 	my $rrdcluster = "/var/rrd/cluster";
 | |
| 	if(! -d $rrdcluster){
 | |
| 		system("mkdir -p $rrdcluster");
 | |
| 	}
 | |
| 	foreach $attribute (keys %summetrix){
 | |
| 		my @times = keys(%{$summetrix{$attribute}});
 | |
| 		my @sorttimes = sort @times;
 | |
| 		foreach $time (@sorttimes){
 | |
| 			$temp = $summetrix{$attribute}{$time}{sum}/$summetrix{$attribute}{$time}{num};
 | |
| 			$code = xCAT_monitoring::rrdutil::push_data_to_rrd("$rrdcluster/$attribute.rrd", $temp, $summetrix{$attribute}{$time}{num}, $step, $time, 'GAUGE');
 | |
| 			if($code != 0){
 | |
| 				return($code, "Can't push data to $rrdcluster/$attribute.rrd");
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return (0, 'Success');
 | |
| }
 | |
| 
 |