#!/usr/bin/perl -w # # Copyright Thomas G. Hale Sr. Novell Inc. June 2011 # This script gets 3 variables from a vm. cpu, memory, and disk capacity. # It gets these all from the Virtual Machine Properties that are available there. # later added the perf.pl script created by a VMware employee to get performance metrics. # use strict; use warnings; use VMware::VIRuntime; # imported packages for all the perf metrics use VMware::VIMRuntime; use VMware::VILib; use Data::Dumper; use Switch; use Time::Local; # Parameters passing to the script now: my $host_param; my $answer; my $name; my $frequency; my $counter_type; my $entity_type; my $password; my $user_name; my $server; my $datacenter; my $perfmgr_view; my $all_counters; my $cpu_counters; my $memory_counters; my $disk_counters; my $system_counters; my $net_counters; my $st_date; my $end_date; # original option variables #my $entity_type = Opts::get_option('entity'); #my $counter_type = Opts::get_option('countertype'); #my $frequency = Opts::get_option('freq'); #my $name = Opts::get_option('name'); #$end_date = Opts::get_option('date'); #my $entity_type = Opts::get_option('entity'); #my $counter_type = Opts::get_option('countertype'); # my $frequency = Opts::get_option('freq'); #my $name = Opts::get_option('name'); name was replaced by a var where I delcare the name. #$end_date = Opts::get_option('date'); $end_date = '2011-06-13'; $host_param = 'MCDWIN2K80142'; $name = 'MCDWIN2K80142'; # frequency can be daily, monthly or weekly $frequency = 'daily'; # valid counter_types are all, cpu, mem, disk and sys. $counter_type = 'all'; $entity_type = 'VirtualMachine'; # the datacenter names should be either dal-dev for dev or x for production and uat. $datacenter = 'dal-dev'; $user_name = 'sa_psorchestrate'; $password = 'N0vell123'; $server= "172.26.116.82"; print "the entity is: $entity_type \n"; print "the counter_type is: $counter_type \n"; print "the frequency is: $frequency \n"; print "the name of the VM is: $name \n"; print "the end date is: $end_date \n"; my %opts = ( datacenter => { type => "=s", help => "Datacenter name", required => 0, }, countertype => { type => "=s", help => "Counter type [cpu | mem | net | disk | sys | all] \n If nothing is specified, the utilization report will include all the counter types.", required => 0, }, date => { type => "=s", help => "Date in yyyy-mm-dd format\n If no date is provided, the current date is assumed.", required => 0, }, entity => { type => "=s", help => "Specify ManagedEntity type [VirtualMachine | HostSystem]\n Only HostSystem and VirtualMachine entity types are currently supported.", default => 'HostSystem', required => 0, }, freq => { type => "=s", help => "Frequency [daily | weekly | monthly]\n The start date for the report will be computed from the frequency.\n If the frequency is daily, the start date will be one day less the 'date' value specified.\n For weekly frequencies, the start date will be seven days less the 'date' value specified. ", required => 0, }, name => { type => "=s", help => "Name of the host/virtual machine\n If name is not specified, the utilization report will contain all host/vm data", required => 0, }, ); $Util::script_version = "1.0"; # read/validate options and connect to the server Opts::add_options(%opts); Opts::parse(); Opts::validate(); Util::connect(); # start of statics info grab $answer = get_cpu(); $answer = get_mem(); $answer = get_device_info(); # end of the info grab. onto the more complex performance info. #depending on the frequency and end_date, get date range ($st_date,$end_date) = get_date_range($frequency, $end_date); #print "Start date : $st_date \n"; #print "End date : $end_date \n"; $end_date = $end_date."T00:00:00"; #-00:00"; $st_date = $st_date."T00:00:00"; #-00:00"; if(!defined ($counter_type)) { $counter_type='all' } #my $entity_views; my $entity_views; #Get the name of the vm if specified or get all vm entities # this is the section thats got to be bombing # course of action is to comment out pieces till it works, or stops throwing the class error for VirtualMachineVMCIDevice if(defined $name) { #print "The name before is: $name \n"; #print "The entity type before is: $entity_type \n"; #$entity_views = Vim::find_entity_views(view_type => $entity_type, filter =>{'name' => $name}); $entity_views = Vim::find_entity_views(view_type => 'VirtualMachine', filter =>{'name' => $name}); #print "The name after is: $name \n"; #print "The entity type after is: $entity_type \n"; } else { print "You need to specify a name to start with duffus. \n"; $entity_views = Vim::find_entity_views(view_type => $entity_type); print "The else's name is: $name \n"; print "The else's entity type is: $entity_type \n"; } #print "This is the Dumper for localtime and time: Dumper(localtime(time))"; print "--------------------------------\n"; print "\nEntity Type : " .$entity_type ."\n"; print "--------------------------------\n\n"; init_perf_counter_info(); foreach my $entity (sort {$a->name cmp $b->name} @$entity_views) #foreach my $entity (sort {$a->name cmp $b->name} @$entity_views) { #check if the vm is on to collect stats if($entity_type eq 'VirtualMachine' && $entity->runtime->powerState->val eq 'poweredOff') # && $entity_type eq 'VirtualMachine') { print "\n------------------------------------------------------------\n"; print "'" . $entity->name . "' is powered off. No stats available\n\n"; print "------------------------------------------------------------\n\n"; next; } my $perf_metric_ids = filter_metric_ids($counter_type,$perfmgr_view->QueryAvailablePerfMetric(entity => $entity)); print "The perf metric ids are: $perf_metric_ids \n"; #my $interval = get_perf_interval($entity); # performance data for the smallest interval in csv format my $perf_query_spec = PerfQuerySpec->new(entity => $entity, metricId => $perf_metric_ids, format => 'csv', startTime => $st_date, endTime => $end_date #intervalId => $interval ); # my $perf_query_spec = PerfQuerySpec->new(entity => $entity, # metricId => $perf_metric_ids, # format => 'csv', # startTime => $st_date, # endTime => $end_date # #intervalId => $interval # ); print "The perf_query_spec is: $perf_query_spec \n"; # get performance data my $perf_data = $perfmgr_view->QueryPerf(querySpec => $perf_query_spec); print "This is the perf data: $perf_data \n "; if(!defined ($perf_data) || !@$perf_data) { print "\n------------------------------------------------------------\n"; print "'" . $entity->name . "' has no stats available for the given date range. Try different dates\n\n" ; print "------------------------------------------------------------\n\n"; next; } foreach (@$perf_data) { print "\n------------------------------------------------------------\n"; print "'" . $entity->name . "'\n"; print "------------------------------------------------------------\n"; my $time_stamps = $_->sampleInfoCSV; #my $val; #$val = $_->value; # #print "The values are: $val \n"; #print "The time_stamps are: $time_stamps \n"; my $values = $_->value; #print "This is the Dumper that gets the performance data passing the time stampes: " . Dumper($time_stamps). "\n"; foreach (Dumper($time_stamps)) { print "This is the Dumper that gets the performance data passing the time stampes: " . $time_stamps . "\n"; } my @ts = split(/,/,$time_stamps); my $ts_size = @ts; print "This is the contents of the array: " . @ts . "\n"; print "Number of samples : " . $ts_size . "\n\n"; print""; foreach (@$values) { if($_->id->instance eq '') { print_counter_info($_->id->counterId, $_->id->instance); pretty_print($_); } } print "------------------------------------------------------------\n\n"; } } sub get_date_range { my ($freq,$end_date) = @_; my $st_date; my ($sec,$min,$hour,$day,$month,$year,$wday,$yday,$isdst); if(!defined ($freq)) { $freq = "daily"; } if (!defined($end_date)) { ($sec,$min,$hour,$day,$month,$year) = localtime(time); $year = 1900+$year; $month = $month+1; if($month<10) { $month = "0" . $month; } if($day<10) { $day = "0" . $day; } $end_date = $year . "-" . $month . "-" . $day ; } ($year,$month,$day)= split(/-/,$end_date); my $end_time = timelocal(0,0,0,$day,$month-1,$year-1900); my $st_time; switch ($freq) { case "daily" { $st_time = $end_time - 86400; } case "weekly" { $st_time = $end_time - (7*86400); } case "monthly" { $st_time = $end_time - (30*86400); } else { $st_time = $end_time - 86400; } } ($sec,$min,$hour,$day,$month,$year,$wday,$yday,$isdst)=localtime($st_time); $year = 1900+$year; $month = $month+1; if($month<10) { $month = "0" . $month; } if($day<10) { $day = "0" . $day; } $st_date = $year . "-" . $month . "-" . $day ; return ($st_date,$end_date); print "The start date is $st_date and the end date is end_date \n"; } sub print_counter_info { my ($counter_id, $instance) = @_; my $counter = $all_counters->{$counter_id}; print $counter->nameInfo->label . "\t : "; print "Rollup type : " . $counter->rollupType->val . "\n"; if (defined $instance) { print "Instance : " . $instance . "\n"; } print "Description: " . $counter->nameInfo->summary . "\n"; print $counter->unitInfo->label . "\n"; } sub pretty_print { my $perf_metric = $_; my @values = split(/,/,$perf_metric->value); my $counter = $all_counters->{$perf_metric->id->counterId}; my $rollupType = $counter->rollupType->val; my $nameInfo = $counter->nameInfo->key; my $unitInfo = $counter->unitInfo->label; my $factor = 1; if ($unitInfo =~/Percent/) { $factor = 100; } switch($rollupType) { case "maximum" { print maximum(@values)/$factor . " ".$unitInfo."\n\n"; } case "minimum" { print minimum(@values)/$factor . " ".$unitInfo."\n\n"; } case "average" { printf ("%.2f %s\n\n" ,average(@values)/$factor,$unitInfo); } else { print "Default case\n"; } } } sub minimum { my @arr = @_; print "This is the Dumper for the sub minimum of arr: Dumper(@arr)\n"; my $n= @arr; if($n==0) { die "The array has no elements \n"; } my $i=0; my $min; for ($i=0;$i<$n;$i++) { if($arr[$i]!=-1) { $min=$arr[$i]; last; } } #print "Min is : ". $arr[0] ."\n"; for(;$i<$n;$i++ ) { if(($arr[$i] < $min) && ($arr[$i]!=-1)) { $min = $arr[$i]; } } print "This is the 2nd Dumper for the sub minimum: Dumper($min)\n"; return $min; } sub maximum { my @arr = @_; print "This is the Dumper: Dumper(@arr)\n"; my $n= @arr; if($n==0) { die "The array has no elements \n"; } my $i=0; my $max; for ($i=0;$i<$n;$i++) { if($arr[$i]!=-1) { $max=$arr[$i]; last; } } for(;$i<$n;$i++ ) { if($arr[$i] > $max ) { $max = $arr[$i]; } } return $max; } sub average { my @arr = @_; my $n=0; my $avg=0; if(@arr==0) { die "The array has no elements \n"; } for( my $i=0;$i<@arr;$i++ ) { if($arr[$i]!=-1) { $avg = $avg + $arr[$i]; $n++; } } return $avg/$n; } sub get_perf_interval { my $entity = shift; my $provider_summary = $perfmgr_view->QueryPerfProviderSummary(entity => $entity); my $interval = $provider_summary->refreshRate; print "Refresh rate interval : $interval \n"; return $interval; } sub init_perf_counter_info { $perfmgr_view = Vim::get_view(mo_ref => Vim::get_service_content()->perfManager); my $perfCounterInfo = $perfmgr_view->perfCounter; foreach (@$perfCounterInfo) { #print "This is the Dumper in perfCounterInfo for: $perfCounterInfo Info AND Dumper($_)\n"; if($_->rollupType->val =~/average/ || $_->rollupType->val =~/maximum/ || $_->rollupType->val =~/minimum/){ #my $val; #$val = $_->rollupType->val; #print "The value for the rollupType is: $val \n"; my $key = $_->key; #print "The key for the metric is: $key \n"; #$all_counters->{ $key } = $_; my $group_info = $_->groupInfo; my $name_info = $_->nameInfo; #print "The name info for the metric is: $name_info \n"; # if ($group_info->key eq 'cpu') { # my $test_key; # $test_key = $group_info->key; # print "The group info key for the metric should be cpu: $test_key \n"; # } if ($group_info->key eq 'cpu' && ($name_info->key eq 'usage' || $name_info->key eq 'usagemhz')) { $cpu_counters->{ $key } = $_; $all_counters->{ $key } = $_; print "The cpu_counters hash is: $cpu_counters \n"; } elsif ($group_info->key eq 'mem' && ($name_info->key eq 'usage' || $name_info->key eq 'granted' || $name_info->key eq 'active')) { $memory_counters->{ $key } = $_; #print "The memory_counters hash is: $memory_counters \n"; $all_counters->{ $key } = $_; } elsif ($group_info->key eq 'disk' && ($name_info->key eq 'usage')) { $disk_counters->{ $key } = $_; # print "The disk_counters hash is: $disk_counters \n"; $all_counters->{ $key } = $_; } elsif ($group_info->key eq 'sys' && ($name_info->key eq 'resourceCpuUsage')) { $system_counters->{ $key } = $_; # print "The system_counters hash is: $system_counters \n"; $all_counters->{ $key } = $_; } # elsif ($group_info->key eq 'net') # { # $net_counters->{ $key } = $_; # $all_counters->{ $key } = $_; # } } } } sub filter_metric_ids { my ($type, $perf_metric_ids) = @_; if (! $all_counters) { init(); } my $counters; if ($type eq 'cpu') { $counters = $cpu_counters; } elsif ($type eq 'mem') { $counters = $memory_counters; } elsif ($type eq 'sys') { $counters = $system_counters; } elsif ($type eq 'disk') { $counters = $disk_counters; } elsif ($type eq 'net') { $counters = $net_counters; } else { $counters = $all_counters; } my @filtered_list; foreach (@$perf_metric_ids) { if (exists $counters->{$_->counterId}) { push @filtered_list, $_; } } return \@filtered_list; } # the 3 subs for the static script piece. sub get_cpu { my $single_host = Vim::find_entity_view (view_type => 'VirtualMachine' , filter => { name => $host_param }, properties => ['config.hardware']); my $num_cpu = $single_host->get_property('config.hardware.numCPU'); print "The num_cpu is: " . $num_cpu . "\n"; } # sub for the static script piece sub get_mem { my $single_host = Vim::find_entity_view (view_type => 'VirtualMachine' , filter => { name => $host_param }, properties => ['config.hardware']); my $mem_size = $single_host->get_property('config.hardware.memoryMB'); print "The mem_size is: " . $mem_size . "\n"; } # sub for the static script piece. sub get_device_info { my $vm_view = Vim::find_entity_view (view_type => 'VirtualMachine' , filter => { name => $host_param }); my $device_info = $vm_view->config->hardware->device; foreach my $disk (@$device_info){ if ( $disk->deviceInfo->label =~ /Hard disk/ ){ print "Disk: " . $disk->deviceInfo->label . "\n"; print "Disk: " . $disk->deviceInfo->summary . "\n"; } } } =pod # Get all inventory objects of the specified type my $entity_type = Opts::get_option('entity'); my $entity_views = Vim::find_entity_views(view_type => $entity_type); my $entity_name; my $entity_view; print "Entity type : $entity_type\n"; print "------------------------------------------------\n"; print "------------------------------------------------\n"; =cut Util::disconnect();