vsphere监控代码备份

来源:互联网 发布:淘宝店铺宣言怎么写 编辑:程序博客网 时间:2024/06/06 03:38
#!/usr/bin/perl -w
use lib "/opt/limserver/lib/perllib";
use strict;
use warnings;
use VMware::VIRuntime;
use DBI;
use Config::Tiny;
use Log::Minimal;
use File::Stamped;
use Net::Ping;
#use Thread;
use threads;
use threads::shared;
use Sys::CPU;
use Net::Telnet;
use POSIX ":sys_wait_h";
#$SIG{CHLD} = 'IGNORE';
#$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
my %hashCounters=();
my @cpuArr=("usage.average:*");#cpu
my @diskArr=("read.average:*","write.average:*");#disk
my @netArr=("received.average:*","transmitted.average:*","packetsRx.summation:*","packetsTx.summation:*");#net
$hashCounters{"cpu"}=\@cpuArr;
$hashCounters{"disk"}=\@diskArr;
$hashCounters{"net"}=\@netArr;


sub check_health_state{
  my ($state) = shift(@_);
  my $res = "UNKNOWN";
  if (uc($state) eq "GREEN") {
     $res = "OK";
  } elsif (uc($state) eq "YELLOW") {
    $res = "WARNING";
  } elsif (uc($state) eq "RED") {
    $res = "CRITICAL";
  }
  return $res;
}


sub simplify_number{
  my ($number, $cnt) = @_;
  $cnt = 2 if (!defined($cnt));
  return sprintf("%.${cnt}f", "$number");

sub convert_number{
  my @vals = split(/,/, shift(@_));
  return shift(@vals) if ($vals[-1] < 0);
  return pop(@vals);
 }




sub return_host_performance_values {
  my $values;
  #my $host_name = shift(@_);
  my $host_view=shift(@_);  
  #my $host_view = Vim::find_entity_views(view_type => 'HostSystem', filter => $host_name, properties => [ 'name', 'runtime.inMaintenanceMode' ]); # Added properties named argument.
  #die "Runtime error\n" if (!defined($host_view));
  #die "Host \"" . $$host_name{"name"} . "\" does not exist\n" if (!@$host_view);
  #die {msg => ("NOTICE: \"" . $$host_view[0]->name . "\" is in maintenance mode, check skipped\n"), code => OK} if (uc($$host_view[0]->get_property('runtime.inMaintenanceMode')) eq "TRUE");
  $values = generic_performance_values($host_view,@_);
  return undef if ($@);
  return ($host_view, $values);
 }


sub generic_performance_values {
  my ($views,$hostname,$fileT) = @_;
  my $counter = 0;
  my @values = ();
  my @viewArr=($views);
  #my $amount = @list;
  my $perfMgr = Vim::get_view(mo_ref => Vim::get_service_content()->perfManager, properties => [ 'perfCounter' ]);
  my $retList=get_key_metrices($perfMgr);
  my $hashCounterIdKey= pop(@$retList);
  my $metrices=pop(@$retList);
  my @perf_query_spec = ();
  push(@perf_query_spec, PerfQuerySpec->new(entity => $_, metricId => $metrices, format => 'csv', intervalId => 20, maxSample => 1))foreach (@viewArr);
  my $perf_data = $perfMgr->QueryPerf(querySpec => \@perf_query_spec);
  #$amount *= @$perf_data;
  while (@$perf_data){
    my $unsorted = shift(@$perf_data)->value;
    my @host_values = ();
    foreach my $id (@$unsorted){
      foreach my $index (0..@$metrices-1){
        if ($id->id->counterId == $$metrices[$index]->counterId){
   $counter++ if (!defined($host_values[$index]));
          $host_values[$index] = $id;
           my $instance=$id->id->instance;
           my $keyName=$$hashCounterIdKey{$id->id->counterId};
           if($instance eq "" ){
             if($keyName=~/^disk/i){
               print $fileT  $hostname." ".$keyName." ".(($id->value)*1024)."\n";
               #print "---------------********XXXXXX*********-----------------".$instance."\n";
               #print "---------------#######################-----------------".$$hashCounterIdKey{$id->id->counterId}."\n";
               #print "---------------********@@@@@@@*********-----------------".$id->value."\n";
             } 
          }
          if($instance ne "" ){
             #my $keyName=$$hashCounterIdKey{$id->id->counterId};
             if($keyName=~/^disk/i){
             #      print $fileT  $hostname." ".$keyName." ".$id->value."\n";
                   #print "---------------*****************-----------------".$keyName."\n";
                   #print "---------------xxxxxxxxxxxxxx1-----------------".$instance."\n";
             }elsif($keyName=~/^cpu/i){
                   print  $fileT $hostname." ".$keyName.$instance." ".($id->value)*0.01."\n";
             }else{
                if(($keyName=~/received/i)||($keyName=~/transmitted/i)){ 
                   print  $fileT $hostname." ".$instance."_".$keyName." ".(($id->value)*1024)."\n";
                }else{
                   print  $fileT $hostname." ".$instance."_".$keyName." ".$id->value."\n";
                }
             }
             
          }
        }
      }
    }
    push(@values, \@host_values);
  }
  #return undef if ($counter != $amount || $counter == 0);
  return \@values;
 }


sub get_key_metrices {
  my ($perfmgr_view) = @_;
  my $perfCounterInfo = $perfmgr_view->perfCounter;
  my @counters;
  my $k=0;
  my %hashKeyName=();
  my @retArrt=();
  die "Insufficient rights to access perfcounters\n" if (!defined($perfCounterInfo));
  foreach (@$perfCounterInfo) {
    # cpu cpuArr
    if ($_->groupInfo->key eq "cpu") {
      my $cur_name = $_->nameInfo->key . "." . $_->rollupType->val;
      foreach my $index (0..@cpuArr-1){
        if ($cpuArr[$index] =~ /$cur_name/){
          $cpuArr[$index] =~ /(\w+).(\w+):*(.*)/;
          $counters[$k] = PerfMetricId->new(counterId => $_->key, instance => $3);
          $hashKeyName{$_->key}="cpu";
          $k++;
        }
      }
    }
    # disk diskArr
    if ($_->groupInfo->key eq "disk") { 
      my $cur_name = $_->nameInfo->key . "." . $_->rollupType->val; 
      foreach my $index (0..@diskArr-1){ 
        if ($diskArr[$index] =~ /$cur_name/){ 
          $diskArr[$index] =~ /(\w+).(\w+):*(.*)/; 
          $counters[$k] = PerfMetricId->new(counterId => $_->key, instance => $3);
          $hashKeyName{$_->key}="disk".$_->nameInfo->key;
          $k++;
        } 
      } 
    } 
    #net netArr
    if ($_->groupInfo->key eq "net") { 
      my $cur_name = $_->nameInfo->key . "." . $_->rollupType->val; 
      foreach my $index (0..@netArr-1){ 
        if ($netArr[$index] =~ /$cur_name/){ 
          $netArr[$index] =~ /(\w+).(\w+):*(.*)/; 
          $counters[$k] = PerfMetricId->new(counterId => $_->key, instance => $3);
          $hashKeyName{$_->key}=$_->nameInfo->key;
          $k++;
        } 
      } 
    }
  }


  push(@retArrt,\@counters);
  push(@retArrt,\%hashKeyName);
  return \@retArrt;
 }
sub getValueBykey{
  my($key,$value,$mem)=@_;
  my $times=1800;
  my $val=$mem->get($key);
  if($val){
     $mem->replace($key,$value,$times);
  }else{
     $mem->add($key,$value,$times);
  }


}
 
my %opts = (
  entity => {
  type => "=s",
  variable => "VI_ENTITY",
  help => "ManagedEntity type: HostSystem, etc",
  required => 1,
  },
  testType=>{
  type=>"=s",
  required=>0
  } 
  
);


     my $Config = Config::Tiny->new;
     $Config = Config::Tiny->read('/opt/limserver/etc/limserver.conf');
     my $dbname = $Config->{_}->{DBName};
     if(!defined($dbname)){
        $dbname="";
     }
     my $location =$Config->{_}->{DBHost};
     if(!defined($location)){
        $location="127.0.0.1";
     }
     my $port=$Config->{_}->{DBPort};
     if(!defined($port)){
        $port="3306";
     }
     my $db_user=$Config->{_}->{DBUser};
     if(!defined($db_user)){
        $db_user="root";
     }
     my $db_pass = $Config->{_}->{DBPassword};
     my $serverIp=$Config->{_}->{SourceIP};
     if(!defined($serverIp)){
        $serverIp="127.0.0.1";
     }
     my $serverPort=$Config->{_}->{ListenPort};
     if(!defined($serverPort)){
        $serverPort="8211";
     }
     my $mysqlSock=$Config->{_}->{DBSocket};
     my $logPath =$Config->{_}->{LogFile};
     my $logLevel="INFO";
     my $debugLevel=$Config->{_}->{DebugLevel};
       if(defined($debugLevel)){
        if($debugLevel==0){
          $logLevel="MUTE";
        }elsif($debugLevel==1){
          $logLevel="CRITICAL";
        }elsif($debugLevel==2){
          $logLevel="ERROR";
        }elsif($debugLevel==3){
          $logLevel="WARN";
        }elsif($debugLevel==4){
          $logLevel="INFO";
        }
       }else{
          $logLevel="WARN";
       }
        
       $logLevel="INFO";
     my $ConfigT = Config::Tiny->new;
     $ConfigT = Config::Tiny->read('/opt/limserver/etc/limvsphere.conf');
     my $dirPath=$ConfigT->{_}->{dataDir};
     if(!defined($dirPath)){
        $dirPath="/vsphereValues";
     }
     my $senderPath=$ConfigT->{_}->{senderPath};
     my $fh = File::Stamped->new(pattern => $logPath);
     $ENV{LM_DEBUG}  = 1;
     #LM_DEFAULT_COLOR='debug=red:info=;cyan:critical=yellow;red'
     local $Log::Minimal::LOG_LEVEL = $logLevel;
     local $Log::Minimal::PRINT = sub {
       my ( $time, $type, $message, $trace) = @_;
       print  {$fh} " $time [$type] $message at $trace\n";
     };
#print $dbname.$location.$port.$db_user.$db_pass."\n";
my $database = "DBI:mysql:database=$dbname;host=$location;mysql_socket=$mysqlSock";
#my $database = "DBI:mysql:$dbname:$location:$port";
my %hashKeyValue=();
    share(%hashKeyValue);
   if(-e $dirPath){
     infof("------dirPath---exits-----");
     print "---------exits-----"."\n";
   }else{
     mkdir( $dirPath, 0755 );
   }
#my $semaphore;
my $num_proc=0;
my $num_collect=0;
my $collect;
my $hostSleep=0;
#$SIG{CHLD} = sub { $num_proc-- };
#while(1){
my $cpuCores=Sys::CPU::cpu_count();#system("cat /proc/cpuinfo | grep processor | wc -l");
if($cpuCores>10){
  $cpuCores=8;
}else{
  $cpuCores=2;
}
infof("------cpuCores------$cpuCores");
print "--------cpuCores----------".$cpuCores."\n";
sub REAPER { waitpid(-1 , WNOHANG);$num_proc--;};
$SIG{CHLD} = \&REAPER;
sub mainStart{
  infof("mianstart sleep ".$hostSleep." sec");
  system("sleep $hostSleep");
  $num_proc=0;
  $num_collect=0;
  my $zcount=0;
 #create a database connect
  print "----db_pass----".$db_pass."\n";
 my $dbh;
 eval{
  $dbh = DBI->connect($database,$db_user,$db_pass,{RaiseError=>1,AutoCommit=>0,PrintError=>0});
 };
 if($@){
    my $errNumber=$DBI::err;
    SWITCH:{
    if ($errNumber==1044) {
      infof("DatabaseName is $database");
      warnf("DatabaseName error!");
      print "DatabaseName error!";last SWITCH;
    }
    if ($errNumber==1045) {
      warnf("DB UserName or Password error!");
      print "DB UserName or Password error!";
      last SWITCH;
    }
    if ($errNumber==2003) {
      warnf("Can't connect to MySQL server! Please check out the value of DBhost,DBport and the physical connection that is from cli
ent to MySQL server.");
      print "Can't connect to MySQL server! Please check out the value of DBhost,DBport and the physical connection that is from client to MySQL server.";
      last SWITCH;
    }
   if ($errNumber==2013) {
      warnf("Lost connection to MySQL server!");
      print "Lost connection to MySQL server!";
      last SWITCH;
   }
  }
  #exit 0; 
 }
 my $sql="select hostid,lim_v_address,host,username,password from lim_vsphere_host inner join hosts on status=0 and hostid=zhostid";
 infof("get host list -> ".$sql);
 my $sql2="select vsphere_refresh_period from config;";
 infof("get host frequest -> ". $sql2);
 my $sthf = $dbh->prepare($sql2);
    $sthf->execute() or die "error:$dbh->errstr";
 
 my $sth = $dbh->prepare($sql);
    $sth->execute() or die "error:$dbh->errstr";
 my $numRows=$sth->rows;
 my @rowf;
 while(@rowf=$sthf->fetchrow_array){
   $hostSleep=$rowf[0];
   print "-------rowf-----------".$rowf[0]."\n";
 }
 my @row;
 infof("---------hostSize-----$numRows");
 print $numRows."----\n";
 #$semaphore = new Thread::Semaphore($numRows);
 my @hostArr=();
 while(@row=$sth->fetchrow_array){
    my @hostInfoArr=();
    $hostInfoArr[0]=$row[1];
    $hostInfoArr[1]=$row[2];
    $hostInfoArr[2]=$row[3];
    $hostInfoArr[3]=$row[4];
    push(@hostArr,\@hostInfoArr);
 }
 $dbh->disconnect();
  foreach my $host (@hostArr){
   infof("-----num_proc-------------$num_proc");
   infof("-----zcount------------$zcount");
   print "-----num_proc-------------".$num_proc."\n";
   print "-----zcount------------".$zcount."\n";
   #print $$host[0];
   #threads->new(\&subThread,$$host[0],$$host[1],$$host[2],$$host[3]);
   #&subThread($$host[0],$$host[1],$$host[2],$$host[3]);
   do {
        sleep(1);
    } until ($num_proc < $cpuCores);
   my $pid = fork();
    if (!defined($pid)) {
        warnf("Error in fork: $!");
        print "Error in fork: $!";
        exit 0;
    }
    if ($pid == 0) {
        ## == child proc ==
        &subThread($$host[0],$$host[1],$$host[2],$$host[3]);
        exit 0;
    }
    $num_proc ++;
    if (($zcount-$num_proc-$num_collect) > 0) {
        while (($collect = waitpid(-1, WNOHANG)) > 0) {
            $num_collect ++;
        }
    }
    #$numRows--;
    $zcount++;
    #do {
    #    sleep(1);
    #} until ($num_proc < $cpuCores);
  }
 &mainStart();
}
&mainStart();


sub subThread{


   my ($ip,$hostname,$username,$password)=@_;#$row_[1];
   my $addr="https://".$ip."/sdk/webService";
   infof("-----vspherehostAddr------------$addr");
   #my $pingobject = Net::Ping->new("icmp");
   #if ($pingobject->ping($ip)) {
   #   infof("vsphere host ip is ".$ip." -> could reach...");
   #   $pingobject->close();
   #}else{
   #   warnf("vsphere host ip is ".$ip." -> could not reach...");
   #   $pingobject->close();
   #   exit 0;
   #}
   my $telnet=Net::Telnet->new(Host=>$ip,Port=>'443',Timeout=>'3',Errmode=>'return');
   my $host_status=1;
   unless($telnet){
     warnf("webService is not connect");
     system("$senderPath  -z $serverIp -p $serverPort -s $hostname  -k hostStatus -o 0");
     exit 0; 
   }else{
     infof("webService  connect ok ");
     #system("$senderPath  -z $serverIp -p $serverPort -s $hostname  -k hostStatus -o 1");
   }
   eval {
    infof("$ip username: $username ; password: $password");
    Opts::set_option("url", $addr);
    Opts::set_option("username", $username);
    Opts::set_option("password", $password);
    Opts::parse();
    Opts::validate();
    Util::connect();
    #Util::connect($addr, $username, $password);
   };
   if ($@) {
      warnf("ip=$ip -> "."$@");
      exit 0;
   }
   
   print "---ggg----"."\n";
   my $entity_type ="HostSystem";# Opts::get_option('entity');
   #my $esx = {name => $host};
   my $host_view=Vim::find_entity_view(view_type=>$entity_type,properties => ['name','runtime','vm','summary','configManager.datastoreSystem','configManager.dateTimeSystem']);
   unless ($host_view){
    print "host is not found"."\n";
  }
   #my $host_view=Vim::find_entity_view(view_type=>$entity_type);
   if(!defined($host_view)){
     warnf("vsphereHost ip is $ip is wrong");
     exit 0;
   }
   my $values = $host_view->get_property('summary.quickStats');
   my $hardinfo = $host_view->get_property('summary.hardware');
   #print $hardinfo->model."\n";
   
   my $memorySize=$hardinfo->memorySize;
   #print "--------zong------------".$memorySize."\n";
   my $cpuUsageValue = simplify_number($values->overallCpuUsage / ($hardinfo->numCpuCores * $hardinfo->cpuMhz) * 100) if exists($values->{overallCpuUsage}) && defined($hardinfo);
   my $memUsageValue = simplify_number($values->overallMemoryUsage / ($hardinfo->memorySize / 1024 / 1024) * 100) if exists($values->{overallMemoryUsage}) && defined($hardinfo);
   my $memUsageSize = simplify_number($values->overallMemoryUsage*1024*1024) if exists($values->{overallMemoryUsage});
   #print "---------12121------------".$values->overallMemoryUsage."\n";
   #my $diskReadValues = return_host_performance_values($host_view);
   #my $diskRead = simplify_number(convert_number($$diskReadValues[0][0]->value), 0);
   #my $diskWriteValues = return_host_performance_values($esx, 'disk', ('write.average:*'));
   #my $diskWrite = simplify_number(convert_number($$diskWriteValues[0][0]->value), 0);
   #my $host_status=$host_view->runtime->powerState->val;
   my $cpuNum =$hardinfo->numCpuPkgs;
   my $cpuLogicNum=$hardinfo->numCpuThreads;
   my $datetime_system = Vim::get_view(mo_ref => $host_view->get_property('configManager.dateTimeSystem') , properties => ['dateTimeInfo']);
   my $localtime=$datetime_system->QueryDateTime();
   my $config= $host_view->get_property('summary.config');
   my $systemVersion=$config->product->name.",".$config->product->version.",".$config->product->build;
   my $uptime=$values->uptime;
   my $vmArr = $host_view->vm;
   my $vmCount=0;
   my $vmPowerOnCount=0;
   my $nicNum=$host_view->summary->hardware->numNics;
   foreach my $vm_sub (@$vmArr){
     my $vmObj = Vim::get_view(mo_ref => $vm_sub, properties => ['runtime']);
     if($vmObj->runtime->powerState->val eq "poweredOn"){
        $vmPowerOnCount++;
     }
     $vmCount++;
   }
   
   my $sensors= $host_view->runtime->healthSystemRuntime->hardwareStatusInfo->storageStatusInfo;
   my $driveCount=0;
   my $out_file="$dirPath"."/"."$hostname";
   open(FILE,">$out_file");
   my $datastore_system = Vim::get_view(mo_ref => $host_view->get_property('configManager.datastoreSystem'));
   my $ret=$datastore_system->get_property('datastore');
   foreach my $ref_store (@$ret){
     my $store = Vim::get_view(mo_ref => $ref_store, properties => ['summary', 'info']);
     my $value1 = simplify_number(convert_number($store->summary->freeSpace));
     my $value2 = convert_number($store->summary->capacity);
     my $value3 = simplify_number(convert_number($store->info->freeSpace) / $value2 * 100) if ($value2 > 0);
     my $storeName=$store->summary->name;
        print FILE $hostname." "."$storeName"."_freeSpace"." ".$value1."\n";
        print FILE $hostname." "."$storeName"."_capacity"." "."$value2"."\n";
        print FILE $hostname." "."$storeName"."_freeSpaceUsage"." "."$value3"."\n";
        
   }
   foreach my $sensor (@$sensors){
      my $value =$sensor->name;
      my $status=$sensor->status->key;
           if ($value=~/^controller/i){
             my $start=index ($value,"(",0);
             my $length=index($value,")",0)-$start;
             my $subStr=substr($value,$start+1,$length-1)."\n";
             $subStr=~ s/\s//g;
             print FILE $hostname." "."raidController"." "."$subStr"."\n";
           }
           if($value=~/^Battery/i){
             my $length=index ($value,"on",0);
             my $subStr=substr($value,0,$length-1);
             $subStr=~ s/\s//g;
             print FILE $hostname." "."raid_battery"." "."$status"."\n";
           }
           if($value=~/^Drive/i){
             $driveCount++;
             my $length=index ($value,"on",0);
             my $subStr=substr($value,0,$length-1);
             $subStr=~ s/\s//g;
             print FILE $hostname." "."$subStr"." ".$status."\n"; 
          }
          if($value=~/^Port/i){
             my $length=index ($value,"on",0);
             my $subStr=substr($value,0,$length-1);
             $subStr=~ s/\s//g;
             print FILE $hostname." "."$subStr"." ".check_health_state($status)."\n";
          }
         if($value=~/^Raid/i){
             my $length=index ($value,"on",0);
             my $subStr=substr($value,0,$length-1);
             $subStr=~ s/\s//g;
             print FILE $hostname." "."$subStr"." ".$status."\n";
          }
     }


    my $memoryIdleSize=$memorySize-$memUsageSize;
     return_host_performance_values($host_view,$hostname,\*FILE);
     print FILE $hostname." "."memorySize"." ".$memorySize."\n";
     print FILE $hostname." "."memUsage"." ".$memUsageValue."\n";
     print FILE $hostname." "."memUsageSize"." ".$memUsageSize."\n";
     print FILE $hostname." "."memoryIdleSize"." ".$memoryIdleSize."\n";
     print FILE $hostname." "."hostStatus"." ".$host_status."\n";
     print FILE $hostname." "."cpuUsage"." ".$cpuUsageValue."\n";
     print FILE $hostname." "."cpuLogicNum"." ".$cpuLogicNum."\n";
     print FILE $hostname." "."cpuNum"." ".$cpuNum."\n";
     print FILE $hostname." "."localtime"." ".$localtime."\n";
     print FILE $hostname." "."systemVersion"." ".$systemVersion."\n";
     print FILE $hostname." "."uptime"." ".$uptime."\n";
     print FILE $hostname." "."vmCount"." ".$vmCount."\n";
     print FILE $hostname." "."vmPowerOnCount"." ".$vmPowerOnCount."\n";
     print FILE $hostname." "."driveCount"." ".$driveCount."\n";
     print FILE $hostname." "."nicNum"." ".$nicNum."\n";
   close(FILE);
   system("$senderPath  -z $serverIp -p $serverPort -s $hostname  -i $out_file");
   #$memd->disconnect_all();
   #$semaphore->up();
   #}
   exit 0;
   Util::disconnect();
}
#$dbh->disconnect();# destory a database connect
#Util::disconnect();
原创粉丝点击