http://www.perlmonks.org?node_id=1035037

lewnewby has asked for the wisdom of the Perl Monks concerning the following question:

Let me get this over up front, I am a relatively new perl user (Starting over after 15 years).

I have been working on extracting data from a management server via an API supplied by the vendor. So far that is all working great, I am able to get the data. My problem arises in that when I receive the data it will have some odd offset in the time stamps.

I make a call requesting data at the default sample rate of 60 seconds over a period of 1 day. The API returns the data in a sequence of Key:Value pairings for each counter I am retrieving. The first counter may have X secs:Value and proceed through at 60 second increments. Ok great so far, the second and forth counters may return to the top with the first and X is the time stamp but the third counter returns to the top and may be X+6 secs instead of X.

The data ends up looking like this:

2013-05-21 18:46:44,221.667,9.041,92.133,4.008,84.450,6.220,8.983,2.57 +0,5.917,6.710,87.067,6.133 2013-05-21 18:46:45,7.519,5.069 2013-05-21 18:47:44,33.617,2.817,70.900,2.931,161.000,9.811,8.233,2.28 +0,5.617,6.010,86.117,8.108,6.067,5.304 2013-05-21 18:48:44,26.417,1.758,38.933,2.550,42.900,3.526,5.750,1.515 +,4.867,6.132,86.433,6.067 2013-05-21 18:48:45,7.562,5.068 2013-05-21 18:49:44,42.683,2.308,33.633,2.208,42.983,3.807,6.033,1.751 +,4.900,6.042,87.300,8.118,5.983,5.207 2013-05-21 18:50:44,86.983,8.791,103.417,7.851,62.900,8.295,15.500,4.4 +21,8.300,9.368,87.800,7.697,6.050,5.202 2013-05-21 18:51:44,50.033,2.840,63.350,3.071,36.817,3.134,6.217,1.480 +,4.783,5.444,88.433,6.150 2013-05-21 18:51:45,7.725,5.275 2013-05-21 18:52:44,50.017,3.071,61.033,2.538,45.317,4.027,6.233,1.769 +,4.767,5.653,88.383,8.086,5.550,4.966 2013-05-21 18:53:44,38.850,2.265,43.100,2.051,42.683,3.795,5.883,1.403 +,4.850,5.667,89.700,6.000 2013-05-21 18:53:45,7.164,5.061 2013-05-21 18:54:44,22.000,1.741,42.817,2.352,41.700,3.430,5.700,1.543 +,5.567,5.756,87.517,7.939,6.300,5.188 2013-05-21 18:55:44,62.700,6.359,78.267,6.949,58.883,6.804,12.350,3.60 +1,8.200,9.379,87.550,7.349,6.017,5.114

I would like it to look like this:

2013-05-21 18:47:00,30.400,2.157,9.900,1.315,39.917,4.201,6.383,1.798, +5.167,7.250,129.950,7.965,5.667,4.892 2013-05-21 18:48:00,33.917,2.276,7.017,1.052,40.150,3.489,5.233,1.440, +4.900,6.393,129.850,8.257,6.033,5.191 2013-05-21 18:49:00,31.867,2.567,10.367,1.337,45.467,4.138,6.417,1.796 +,5.267,7.148,124.867,8.340,5.983,4.897 2013-05-21 18:50:00,57.533,2.943,8.800,1.063,41.867,3.701,5.083,1.445, +4.900,6.176,129.517,7.715,5.867,4.925 2013-05-21 18:51:00,72.900,10.128,103.833,6.560,66.317,6.734,14.933,4. +398,11.267,11.092,119.767,7.753,6.100,5.121 2013-05-21 18:52:00,23.950,1.803,7.217,1.460,50.667,3.845,5.183,1.492, +4.583,5.481,124.500,9.369,6.017,5.030 2013-05-21 18:53:00,25.500,1.910,9.767,1.754,49.467,4.112,6.133,1.772, +23.117,17.196,127.583,8.158,6.067,5.076 2013-05-21 18:54:00,47.350,2.344,8.833,1.419,47.283,3.875,5.400,1.409, +4.867,6.035,148.567,8.428,5.883,4.940 2013-05-21 18:55:00,29.067,2.338,10.400,1.789,45.067,3.250,6.233,1.795 +,5.100,5.866,126.517,7.990,6.133,5.219

Here is the code I am using to do this:

my ($list, $obj, $server_ctx) = @_; my @objList = @{ $list }; my (@counter_arr,$objName,@perf_cnt_data,%perfhash); my $gen_time_arr = 1; my $gen_hash_hdr = 1; my $obj_i = 0; my ($rec,$tmpHDR,$tmpVAL); if ($obj eq "system") { $obj = "host"; } $perfhash{"Time"} = ""; foreach my $perf_out ( @objList ){ my $instance = $perf_out->child_get("perf-instances"); my @instances = $instance->children_get("perf-instance-counter +-data"); foreach $rec (@instances){ my $obj_id = $rec->child_get_string("object-id"); my $IterStart = NaElement->new("$obj" . "-list-info-iter-s +tart"); $IterStart->child_add_string("object-name-or-id","$obj_id" +); my $output = $server_ctx->invoke_elem($IterStart); if ( $output -> results_status()=~/failed/ ) { print "\n\n\tFailed to get list of $obj: Error: ".$out +put->results_reason(). "\n\n"; } else { my $records = $output->child_get_int("records"); my $tag = $output->child_get_string("tag"); $output = $server_ctx->invoke("$obj" . "-list-info-ite +r-next", "maximum", $records, "tag", $tag); if ( $output -> results_status()=~/failed/ ) { print "\n\n\tFailed to iterate list of $obj : Erro +r: ".$output->results_reason(). "\n\n"; } } my $aggregates = $output->child_get("$obj" . "s"); my @aggregateArr = $aggregates->children_get(); foreach my $aggr (@aggregateArr) { $objName = $aggr->child_get_string("$obj" . "-name"); $objName =~ s/\///g; } my $counters = $rec->child_get("counters"); @perf_cnt_data = $counters->children_get("perf-counter-dat +a"); my $rec1; # TODO If the counter is aggregate:pa_max_disk_busy and returns nothin +g get the max of disk:disk_busy for the aggregate foreach $rec1 (@perf_cnt_data) { my $counter_name = $rec1->child_get_string("counter-na +me"); my $counter_str = $rec1->child_get_string("counter-dat +a"); my @counter_arr = split (',', $counter_str); my $colName = $objName . ":" . $counter_name; chomp($colName); $tmpHDR = $perfhash{"Time"}; $perfhash{"Time"} = join( ',' , $tmpHDR , $colName); for (@counter_arr) { my ($time,$value) = split(':',$_); my @timestamp = ( localtime($time) )[0..5]; $time = POSIX::strftime( '%F %H:%M:%S', @timestamp +); if ($gen_time_arr == 1) { $perfhash{$time} = join('' , "," , $value); $gen_time_arr = 0; }else { if ($perfhash{$time}) { $tmpVAL = $perfhash{$time}; } else { $tmpVAL = ""; } $perfhash{$time} = join( ',' , $tmpVAL , $valu +e); } } } } } return(\%perfhash); }

Thanks in advance

Lew