From 45d332217d02acbaa961a0c7bba6fcd4c91fec53 Mon Sep 17 00:00:00 2001 From: ellen56 Date: Wed, 17 Jun 2009 07:03:00 +0000 Subject: [PATCH] API to handle metrics of RMC git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@3594 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- xCAT-rmc/plugin/rmcmetrix.pm | 462 +++++++++++++++++++++++++++++++++++ 1 file changed, 462 insertions(+) create mode 100755 xCAT-rmc/plugin/rmcmetrix.pm diff --git a/xCAT-rmc/plugin/rmcmetrix.pm b/xCAT-rmc/plugin/rmcmetrix.pm new file mode 100755 index 000000000..ff23b3f17 --- /dev/null +++ b/xCAT-rmc/plugin/rmcmetrix.pm @@ -0,0 +1,462 @@ +#!/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; + + 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"; + $ret = xCAT_monitoring::rrdutil::push_data_to_rrd($rrd, $metrix{$attr}{summary}, $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"; + $ret = xCAT_monitoring::rrdutil::push_data_to_rrd($rrd, $metrix{$attr}{$nnlist}{summary}, $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){ + @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 = undef; + 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, 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=3 lsrsrc-api -i -s $rsrc"."::\'Name==\"$name\"\'::Name::NodeNameList::$attr"; + @output = xCAT::Utils->runcmd($cmd, 0); + if($::RUNCMD_RC){ + $line = join '', @output; + return ($::RUNCMD_RC, $line); + } + &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} += 1; + } + + } + } + + 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 @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 $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/){ + 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({}); + $summary{$a}{$n}{$timestamp}{sum} = $sum; + $summary{$a}{$n}{$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"; + $summetrix{$attribute}{$time}{sum} += $summary{$attribute}{$nodename}{$time}{sum}; + $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){ + $code = xCAT_monitoring::rrdutil::push_data_to_rrd("$rrdcluster/$attribute.rrd", $summetrix{$attribute}{$time}{sum}, $summetrix{$attribute}{$time}{num}, $step, $time, 'GAUGE'); + if($code != 0){ + return($code, "Can't push data to $rrdcluster/$attribute.rrd"); + } + } + } + + return (0, 'Success'); +} +