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
This commit is contained in:
parent
b231f0c745
commit
45d332217d
462
xCAT-rmc/plugin/rmcmetrix.pm
Executable file
462
xCAT-rmc/plugin/rmcmetrix.pm
Executable file
@ -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');
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user