mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 03:12:30 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			489 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			489 lines
		
	
	
		
			15 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');
 | |
| }
 | |
| 
 |