#!/usr/bin/perl

#
# Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. 
#
#  $Id:oracle_cell_combined_metrics.pl 
#
#
# NAME  
#   oracle_cell_combined_metrics.pl
#
# DESC 
#
# This script gets all the Cell Disk metrics of the CELL.   
#
# NOTES
#
# MODIFIED  (MM/DD/YY)
#    spalapu 11/10/09 - Merge Metrics, add Host Interconnect..
#    spalapu 11/06/09 - Combine metrics into one call
#    spalapu 03/19/08 - Add Copyright statements
#    spalapu 03/18/08 - 
#    spalapu 03/17/08 - 
#    spalapu 03/13/08 - change object_type to objectType
#    spalapu 02/13/08 - new file
#   spalapud 10/07/06 	Created the file.
# 

use XML::Parser;
use Class::Struct;
use Switch;
require emx::oracle_cell::oracle_cell_common;

our %celldisks;  # Hash of metrics
our %griddisks;  # Hash of metrics
our %cells;  # Hash of metrics
our %cellfs;  # Hash of metrics
our %iormca;  # Hash of metrics
our %iormdb;  # Hash of metrics
our %iormcg;  # Hash of metrics
our %interconnects;  # Hash of metrics
our $celldisk;
our $griddisk;
our $cell;
our $cellfilesystem;
our $iormdb;
our $iormca;
our $iormcg;
our $interconnect;
$griddisk = 0;
$ipaddress=doPing(@ARGV);

if($ipaddress eq "") {
  print "em_error=Failed to ping Cell\n";
  exit -1;
}
my $command = "ssh -l cellmonitor $ipaddress cellcli  -xml -e 'list metriccurrent  '";

my $xmlout = `$command`;
my $parser = XML::Parser->new( Handlers => {
                                      Start=>\&handle_start,
                                      End=>\&handle_end,
				      Char=> \&characterData,
                                     });
my $myinf;
my $alertState;
my $collectionTime;
my $metricObjectName;
my $metricType;
my $metricValue;
my $objectType;
$parser->parse( $xmlout);
#-----  Print out the Celldisk information --------------
my $read_throughput;
my $write_throughput;
my $read_reqs;
my $write_reqs;
       foreach $celldisk (keys %celldisks)
       {
          $read_throughput=0;
          $write_throughput=0;
          $read_reqs=0;
          $write_reqs=0;
          $read_throughput =$celldisks{$celldisk}{CD_IO_BY_R_LG} + $celldisks{$celldisk}{CD_IO_BY_R_SM};
          $write_throughput=$celldisks{$celldisk}{CD_IO_BY_W_LG} + $celldisks{$celldisk}{CD_IO_BY_W_SM};
          $read_reqs=$celldisks{$celldisk}{CD_IO_RQ_R_LG} + $celldisks{$celldisk}{CD_IO_RQ_R_SM};
          $write_reqs=$celldisks{$celldisk}{CD_IO_RQ_W_LG} + $celldisks{$celldisk}{CD_IO_RQ_W_SM};
#Since the latency times are in microsecs it is required to convert it into millisecs.
          $celldisks{$celldisk}{CD_IO_TM_R_SM} =  $celldisks{$celldisk}{CD_IO_TM_R_SM}/1000;
          $celldisks{$celldisk}{CD_IO_TM_R_LG} =  $celldisks{$celldisk}{CD_IO_TM_R_LG}/1000;
          $celldisks{$celldisk}{CD_IO_TM_W_SM} =  $celldisks{$celldisk}{CD_IO_TM_W_SM}/1000;
          $celldisks{$celldisk}{CD_IO_TM_W_LG} =  $celldisks{$celldisk}{CD_IO_TM_W_LG}/1000;
          print "em_result=CELLDISK|".$celldisks{$celldisk}{name}."|".$cellname."|".$realmname."|".$osstimestamp."|".$read_throughput."|".$celldisks{$celldisk}{CD_IO_BY_R_SM_time}."|".$write_throughput."|".$celldisks{$celldisk}{CD_IO_BY_W_SM_time}."|".$read_reqs."|".$celldisks{$celldisk}{CD_IO_RQ_R_SM_time}."|".$write_reqs."|".$celldisks{$celldisk}{CD_IO_RQ_W_SM_time}."|".$celldisks{$celldisk}{CD_IO_RQ_R_SM}."|".$celldisks{$celldisk}{CD_IO_TM_R_SM}."|".$celldisks{$celldisk}{CD_IO_RQ_W_SM}."|".$celldisks{$celldisk}{CD_IO_TM_W_SM}."|".$celldisks{$celldisk}{CD_IO_RQ_R_LG}."|".$celldisks{$celldisk}{CD_IO_TM_R_LG}."|".$celldisks{$celldisk}{CD_IO_RQ_W_LG}."|".$celldisks{$celldisk}{CD_IO_TM_W_LG}."|"."\n";
       }
       foreach $griddisk (keys %griddisks)
       {
          $read_throughput=0;
          $write_throughput=0;
          $read_reqs=0;
          $write_reqs=0;
          $read_throughput =$griddisks{$griddisk}{GD_IO_BY_R_LG} + $griddisks{$griddisk}{GD_IO_BY_R_SM};
          $write_throughput=$griddisks{$griddisk}{GD_IO_BY_W_LG} + $griddisks{$griddisk}{GD_IO_BY_W_SM};
          $read_reqs=$griddisks{$griddisk}{GD_IO_RQ_R_LG} + $griddisks{$griddisk}{GD_IO_RQ_R_SM};
          $write_reqs=$griddisks{$griddisk}{GD_IO_RQ_W_LG} + $griddisks{$griddisk}{GD_IO_RQ_W_SM};
          print "em_result=GRIDDISK|".$griddisks{$griddisk}{name}."|".$cellname."|".$realmname."|".$osstimestamp."|".$read_throughput."|".$griddisks{$griddisk}{GD_IO_BY_R_SM_time}."|".$write_throughput."|".$griddisks{$griddisk}{GD_IO_BY_W_SM_time}."|".$read_reqs."|".$griddisks{$griddisk}{GD_IO_RQ_R_SM_time}."|".$write_reqs."|".$griddisks{$griddisk}{GD_IO_RQ_W_SM_time}."|||||||||"."\n";
       }
       foreach $cell (keys %cells)
       {
          print "em_result=CELL|".$cellname."|".$realmname."|".$cells{$cell}{CL_CPUT}."|".$cells{$cell}{CL_FANS}."|".$cells{$cell}{CL_RUNQ}."|".$cells{$cell}{CL_TEMP}."|".$cells{$cell}{N_NIC_NW}."|".$cells{$cell}{N_NIC_RCV_SEC}."|".$cells{$cell}{N_NIC_TRANS_SEC}."||||||||||||"."\n";
       }
       foreach $fs (keys %cellfs)
       {
          print "em_result=CELL_FS|".$cellfs{$fs}{name}."|".$cellname."|".$realmname."|".$cellfs{$fs}{util}."|||||||||||||||||"."\n";
       }

       foreach $database (keys %iormdb)
       {
          print "em_result=IORM_DB|".$iormdb{$database}{name}."|".$cellname."|".$realmname."|".$iormtimestamp."|Database*_Statistics|INTER_DATABASE|".$iormdb{$database}{DB_IO_RQ_SM}."|".$iormdb{$database}{DB_IO_WT_SM}."|".$iormdb{$database}{DB_IO_RQ_LG}."|". $iormdb{$database}{DB_IO_WT_LG}."|".$iormdb{$database}{DB_IO_RQ_SM_time}."||||||||||\n";
       }

       foreach $category (keys %iormca)
       {
          print "em_result=IORM_CATEGORY|".$iormca{$category}{name}."|".$cellname."|".$realmname."|".$iormtimestamp."|Category*_Statistics|CATEGORY|".$iormca{$category}{DB_IO_RQ_SM}."|".$iormca{$category}{DB_IO_WT_SM}."|".$iormca{$category}{DB_IO_RQ_LG}."|". $iormca{$category}{DB_IO_WT_LG}."|".$iormca{$category}{DB_IO_RQ_SM_time}."||||||||||\n";
       }

       foreach $cg (keys %iormcg)
       {
          print "em_result=IORM_CONSUMERGROUP|".$iormcg{$cg}{name}."|".$cellname."|".$realmname."|".$iormtimestamp."|ConsmerGroup*_Statistics|INTER_DATABASE|".$iormcg{$cg}{CG_IO_RQ_SM}."|".$iormcg{$cg}{CG_IO_WT_SM}."|".$iormcg{$cg}{CG_IO_RQ_LG}."|". $iormcg{$cg}{CG_IO_WT_LG}."|".$iormcg{$cg}{CG_IO_RQ_SM_time}."||||||||||\n";
       }


       foreach $interconnect (keys %interconnects)
       {
          print "em_result=HOST_INTERCONNECT|".$interconnects{$interconnect}{name}."|".$cellname."|".$realmname."|".$osstimestamp."|".$interconnects{$interconnect}{N_MB_SENT}."|".$interconnects{$interconnect}{N_MB_SENT_time}."|".$interconnects{$interconnect}{N_MB_DROP}."|".$interconnects{$interconnect}{N_MB_DROP_time}."|".$interconnects{$interconnect}{N_MB_RESENT}."|".$interconnects{$interconnect}{N_MB_RESENT_time}."|".$interconnects{$interconnect}{N_MB_RECEIVED}."|".$interconnects{$interconnect}{N_MB_RECEIVED_time}."|".$interconnects{$interconnect}{N_MB_RDMA_DROP}."|".$interconnects{$interconnect}{N_MB_RDMA_DROP_time}."|".$interconnects{$interconnect}{N_RDMA_RETRY_TM}."|".$interconnects{$interconnect}{N_RDMA_RETRY_TM_time}."|||||"."\n";
       }

#-----------------------------------------------------------------
# FUNCTIONS :  handle_start
#
#
# DESC : Does node based parsing of the XML output.
#
# ARGUMENTS :
#		elements : Node elements in the XML 
#  		attrs 	 : Attributes of the elements.
#
#
#-----------------------------------------------------------------

sub handle_start {
    my( $expat, $element, %attrs  ) = @_;
    $myinf="";
    if ($element eq "context")
    {
      if( %attrs )
      {
         $cellname = $attrs{cell};
         $realmname = $attrs{realm};
         $osstimestamp = $attrs{ossStartTimestamp};
      }
    }
    elsif ($element eq "cli-output")
    {
       $myinf="cli-output";
    }
    elsif ($element eq "name")
    {
       $myinf="name";
    }
    elsif ($element eq "metricType")
    {
       $myinf="metricType";
    }
    elsif ($element eq "metricValue")
    {
       $myinf="metricValue";
    }
    elsif ($element eq "collectionTime")
    {
       $myinf="collectionTime";
    }
    elsif ($element eq "metricObjectName")
    {
       $myinf="metricObjectName";
    }
    elsif ($element eq "objectType")
    {
       $myinf="objectType";
    }


}

sub handle_end {
    my( $expat, $element, %attrs  ) = @_;
    if ($element eq "metric")
    {
      if ($realmname eq "") {
        $realmname="NONE";
      }
    }
}

sub characterData {
my( $parseinst, $data ) = @_;
$space=" ";
$data =~ s/\n//g;
if (($data !~ m/^\s/) and ($data ne "\""))
{
if ($myinf eq "name" )
{
  $name=$name.$data;
}
elsif ($myinf eq "metricType" )
{
  $metricType=$metricType.$data;
}
elsif ($myinf eq "metricObjectName" )
{
  $metricObjectName=$metricObjectName.$data;
}
elsif ($myinf eq "metricValue" )
{
  $metricValue=$metricValue.$data;

}
elsif ($myinf eq "collectionTime" )
{
  #convert to secs from millsecs
  $data= $data; 
  $collectionTime=$collectionTime.$data;
}
elsif ($myinf eq "objectType" )
{
  $objectType=$objectType.$data;
  if (($metricType eq "Cumulative") || ($metricType eq "Instantaneous")
      || ($name eq "N_NIC_RCV_SEC") || ($name eq "N_NIC_TRANS_SEC"))
  {
     $collectionTime = $collectionTime/1000;
     if ($objectType eq "CELLDISK") {
       $celldisk = $celldisk+1; 
       
       $celldisks{$metricObjectName}{name} = $metricObjectName;
       $celldisks{$metricObjectName}{$name} = $metricValue;
       $celldisks{$metricObjectName}{$name."_time"} = $collectionTime;
     }
     elsif ($objectType eq "GRIDDISK") {
       $griddisk = $griddisk+1;
       $griddisks{$metricObjectName}{name} = $metricObjectName;
       $griddisks{$metricObjectName}{$name} = $metricValue;
       $griddisks{$metricObjectName}{$name."_time"} = $collectionTime;
     }
     elsif ($objectType eq "CELL") {
       $cell = $cell+1;
       $cells{$metricObjectName}{name} = $metricObjectName;
       $cells{$metricObjectName}{$name} = sprintf("%.2f",$metricValue);
       $cells{$metricObjectName}{$name."_time"} = $collectionTime;
     }
     elsif ($objectType eq "CELL_FILESYSTEM") {
       $cellfilesystem = $cellfilesystem+1;
       
       $cellfs{$metricObjectName}{name} = $metricObjectName;
       $cellfs{$metricObjectName}{util} = sprintf("%.2f",$metricValue);
       $cellfs{$metricObjectName}{collectionTime} = $collectionTime;
     }
     elsif ($objectType eq "IORM_DATABASE") {
       $iormdatabase = $iormdatabase+1;
       
       $iormdb{$metricObjectName}{name} = $metricObjectName;
       $iormdb{$metricObjectName}{$name} = $metricValue;
       $iormdb{$metricObjectName}{$name."_time"} = $collectionTime;
     }
     elsif ($objectType eq "IORM_CATEGORY") {
       $iormcategory = $iormcategory+1;
       
       $iormca{$metricObjectName}{name} = $metricObjectName;
       $iormca{$metricObjectName}{$name} = $metricValue;
       $iormca{$metricObjectName}{$name."_time"} = $collectionTime;
     }
     elsif ($objectType eq "IORM_CONSUMER_GROUP") {
       $iormcg = $iormccg+1;
       
       $iormcg{$metricObjectName}{name} = $metricObjectName;
       $iormcg{$metricObjectName}{$name} = $metricValue;
       $iormcg{$metricObjectName}{$name."_time"} = $collectionTime;
     }
     elsif ($objectType eq "HOST_INTERCONNECT") {
       $iormcg = $iormccg+1;
       
       $interconnects{$object_name}{name} = $object_name;
       $interconnects{$object_name}{$name} = $metric_value;
       $interconnects{$object_name}{$name."_time"} = $collection_time;
     }
  }
  $name="";
  $alertState="";
  $collectionTime="";
  $metricObjectName="";
  $metricType="";
  $metricValue="";
  $objectType="";

}
}
}
