Changeset 28652


Ignore:
Timestamp:
11/20/13 12:57:27 (7 years ago)
Author:
jmt12
Message:

Changes to support running the reports over logs produced from multicore machines (Karearea) whereas I'd previously only supported clusters (Medusa). The biggest issue is that all workers claim to be 'W0' - so you need to differentiate by core rather than node

File:
1 edited

Legend:

Unmodified
Added
Removed
  • gs2-extensions/parallel-building/trunk/src/bin/script/hadoop_report.pl

    r28356 r28652  
    2727}
    2828
     29use Cwd;
    2930use Devel::Peek;
    3031use Sort::Key::Natural qw(natsort);
     
    3738
    3839# Configuration
    39 if (!defined $ARGV[0] || !-d $ARGV[0])
     40my $offset = 0;
     41my $dir_count = 0;
     42while (defined $ARGV[$offset])
     43{
     44  my $argument = $ARGV[$offset];
     45  if ($argument =~ /^\-(.*)/)
     46  {
     47  }
     48  else
     49  {
     50    my $path = getcwd() . '/' . $argument;
     51    if (-d $path)
     52    {
     53      &searchForHadoopLog($path);
     54      $dir_count++;
     55    }
     56    $offset++;
     57  }
     58}
     59if ($dir_count == 0)
    4060{
    4161  die("usage: hadoop_report.pl <path to results>\n");
    4262}
    43 my $results_path = $ARGV[0];
    44 
    45 # Read in hadoop.log and parse top level record
    46 print ' * Reading and parsing "hadoop.log"... ';
    47 my $job_record = {'host'=>'', 'job'=>'', 'start'=>0, 'end'=>0, 'cpu_time'=>0};
    48 my $hadoop_log_path = $results_path . '/hadoop.log';
    49 if (open(HLIN, '<:utf8', $hadoop_log_path))
    50 {
    51   while (my $line = <HLIN>)
    52   {
    53     if ($line =~ /host:(.+)/)
    54     {
    55       $job_record->{'host'} = $1;
    56     }
    57     elsif ($line =~ /Running job: job_(\d+_\d+)/)
    58     {
    59       $job_record->{'job'} = $1;
    60     }
    61     elsif ($line =~ /CPU time spent \(ms\)=(\d+)/)
    62     {
    63       $job_record->{'cpu_time'} = $1;
    64     }
    65     elsif ($job_record->{'start'} == 0 && $line =~ /(\d\d)\/(\d\d)\/(\d\d) (\d\d):(\d\d):(\d\d)/)
    66     {
    67       $job_record->{'start'} = timelocal($6, $5, $4, $3, ($2 - 1), $1);
    68     }
    69     elsif ($line =~ /(\d\d)\/(\d\d)\/(\d\d) (\d\d):(\d\d):(\d\d)/)
    70     {
    71       my $end = timelocal($6, $5, $4, $3, ($2 - 1), $1);
    72       if ($end > $job_record->{'end'})
    73       {
    74         $job_record->{'end'} = $end;
    75       }
    76     }
    77   }
    78   close(HLIN);
    79   if ($job_record->{'start'} == 0 || $job_record->{'end'} == 0)
    80   {
    81     die('Error! Failed to parse timing information from log: ' . $hadoop_log_path);
    82   }
    83 }
    84 else
    85 {
    86   die('Error! Failed to open file for reading: ' . $hadoop_log_path);
    87 }
    88 print "Done!\n";
    89 
    90 # Read in data_locality.csv (will be matched to task logs)
    91 my $data_was_local = {};
    92 my $data_locality_csv_path = $results_path . '/data_locality.csv';
    93 if (-f $data_locality_csv_path)
    94 {
    95   print ' * Reading and parsing "data_locality.csv"... ';
    96   if (open(DLIN, '<:utf8', $data_locality_csv_path))
    97   {
    98     while (my $line = <DLIN>)
    99     {
    100       # note that the line may begin with a taskid or just a taskno (legacy)
    101       if ($line =~ /(\d+),\d,(\d)/)
    102       {
    103         $data_was_local->{$1} = $2;
    104       }
    105     }
    106     close(DLIN);
    107   }
    108   else
    109   {
    110     die('Error! Failed to open file for reading: ' . $data_locality_csv_path);
     63print "\n\n================================== Complete ====================================\n\n";
     64exit;
     65
     66sub searchForHadoopLog
     67{
     68  my ($dir) = @_;
     69  if (-d $dir)
     70  {
     71    print ' * Searching for hadoop.log: ' . $dir . "\n";
     72    my $hadoop_log_path = $dir . '/hadoop.log';
     73    if (-f $hadoop_log_path)
     74    {
     75      &generateReport($dir);
     76    }
     77    # search recursively
     78    if (opendir(DH, $dir))
     79    {
     80      my @files = readdir(DH);
     81      closedir(DH);
     82      foreach my $file (@files)
     83      {
     84        my $path = $dir . '/' . $file;
     85        # ignore files starting with .
     86        if ($file =~ /^\./)
     87        {
     88        }
     89        elsif (-d $path)
     90        {
     91          &searchForHadoopLog($path);
     92        }
     93      }
     94    }
     95    else
     96    {
     97      die('Error! Failed to open directory for reading: ' . $dir);
     98    }
     99  }
     100}
     101
     102sub generateReport
     103{
     104  my ($results_path) = @_;
     105
     106  # Read in hadoop.log and parse top level record
     107  print ' * Reading and parsing "hadoop.log"... ';
     108  my $job_record = {'host'=>'', 'job'=>'', 'start'=>0, 'end'=>0, 'cpu_time'=>0};
     109  my $hadoop_log_path = $results_path . '/hadoop.log';
     110  if (open(HLIN, '<:utf8', $hadoop_log_path))
     111  {
     112    while (my $line = <HLIN>)
     113    {
     114      if ($line =~ /host:(.+)/)
     115      {
     116        $job_record->{'host'} = $1;
     117      }
     118      elsif ($line =~ /Running job: job_(\d+_\d+)/)
     119      {
     120        $job_record->{'job'} = $1;
     121      }
     122      elsif ($line =~ /CPU time spent \(ms\)=(\d+)/)
     123      {
     124        $job_record->{'cpu_time'} = $1;
     125      }
     126      elsif ($job_record->{'start'} == 0 && $line =~ /(\d\d)\/(\d\d)\/(\d\d) (\d\d):(\d\d):(\d\d)/)
     127      {
     128        $job_record->{'start'} = timelocal($6, $5, $4, $3, ($2 - 1), $1);
     129      }
     130      elsif ($line =~ /(\d\d)\/(\d\d)\/(\d\d) (\d\d):(\d\d):(\d\d)/)
     131      {
     132        my $end = timelocal($6, $5, $4, $3, ($2 - 1), $1);
     133        if ($end > $job_record->{'end'})
     134        {
     135          $job_record->{'end'} = $end;
     136        }
     137      }
     138    }
     139    close(HLIN);
     140    if ($job_record->{'start'} == 0 || $job_record->{'end'} == 0)
     141    {
     142      die('Error! Failed to parse timing information from log: ' . $hadoop_log_path);
     143    }
     144  }
     145  else
     146  {
     147    die('Error! Failed to open file for reading: ' . $hadoop_log_path);
    111148  }
    112149  print "Done!\n";
    113 }
    114 else
    115 {
    116   print " * Data locality not available or not applicable\n";
    117 }
    118 
    119 # Read in all task logs and parse task records
    120 my $task_records;
    121 print " * Locating task logs...\n";
    122 if (opendir(DH, $results_path))
    123 {
    124   my @files = readdir(DH);
    125   foreach my $file (sort @files)
    126   {
    127     if ($file =~ /import-hadoop-(\d+_\d+)_m_(\d+)_\d+\.log/)
    128     {
    129       my $job_no = $1;
    130       my $task_no = $2;
    131       my $is_data_local = 0;
    132       if (defined ($data_was_local->{$task_no}))
    133       {
    134         $is_data_local = $data_was_local->{$task_no};
    135       }
    136       my $task_record = {'host'=>'', 'cpu'=>0, 'job' => $job_no, 'task' => $task_no, 'start'=>0, 'end'=>0, 'cpu_time'=>0, 'data_locality'=>$is_data_local, 'file'=>'', 'percom'=>'NA'};
    137       print ' - Reading and parsing "' . $file . '"... ';
    138       my $task_log_path = $results_path . '/' . $file;
    139       my $io_time = 0;
    140       if (open(TIN, '<:utf8', $task_log_path))
    141       {
    142         my $io_start_time = 0;
    143         while (my $line = <TIN>)
    144         {
    145           if ($line =~ /\[Started:(\d+(?:\.\d+)?)\]/)
     150
     151  # Read in data_locality.csv (will be matched to task logs)
     152  my $data_was_local = {};
     153  my $data_locality_csv_path = $results_path . '/data_locality.csv';
     154  if (-f $data_locality_csv_path)
     155  {
     156    print ' * Reading and parsing "data_locality.csv"... ';
     157    if (open(DLIN, '<:utf8', $data_locality_csv_path))
     158    {
     159      while (my $line = <DLIN>)
     160      {
     161        # note that the line may begin with a taskid or just a taskno (legacy)
     162        if ($line =~ /(\d+),\d,(\d)/)
     163        {
     164          $data_was_local->{$1} = $2;
     165        }
     166      }
     167      close(DLIN);
     168    }
     169    else
     170    {
     171      die('Error! Failed to open file for reading: ' . $data_locality_csv_path);
     172    }
     173    print "Done!\n";
     174  }
     175  else
     176  {
     177    print " * Data locality not available or not applicable\n";
     178  }
     179
     180  # Read in all task logs and parse task records
     181  my $task_records;
     182  print " * Locating task logs...\n";
     183  if (opendir(DH, $results_path))
     184  {
     185    my @files = readdir(DH);
     186    foreach my $file (sort @files)
     187    {
     188      if ($file =~ /import-hadoop-(\d+_\d+)_m_(\d+)_\d+\.log/)
     189      {
     190        my $job_no = $1;
     191        my $task_no = $2;
     192        my $is_data_local = 0;
     193        if (defined ($data_was_local->{$task_no}))
     194        {
     195          $is_data_local = $data_was_local->{$task_no};
     196        }
     197        my $task_record = {'host'=>'', 'cpu'=>0, 'job' => $job_no, 'task' => $task_no, 'start'=>0, 'end'=>0, 'cpu_time'=>0, 'data_locality'=>$is_data_local, 'file'=>'', 'percom'=>'NA'};
     198        print ' - Reading and parsing "' . $file . '"... ';
     199        my $task_log_path = $results_path . '/' . $file;
     200        my $io_time = 0;
     201        if (open(TIN, '<:utf8', $task_log_path))
     202        {
     203          my $io_start_time = 0;
     204          while (my $line = <TIN>)
    146205          {
    147             $task_record->{'start'} = $1;
     206            if ($line =~ /\[Started:(\d+(?:\.\d+)?)\]/)
     207            {
     208              $task_record->{'start'} = $1;
     209            }
     210            elsif ($line =~ /\[Host:([^\]]+)\]/)
     211            {
     212              $task_record->{'host'} = $1;
     213            }
     214            elsif ($line =~ /\[CPU:(\d+)\]/)
     215            {
     216              $task_record->{'cpu'} = $1;
     217            }
     218            elsif ($line =~ /\[Map:([^\>]+)=>/)
     219            {
     220              $task_record->{'file'} = $1;
     221            }
     222            elsif ($line =~ /\[IOS:(\d+)\]/)
     223            {
     224              $io_start_time = $1;
     225            }
     226            elsif ($io_start_time > 0 && $line =~ /\[IOE:(\d+)\]/)
     227            {
     228              $io_time += ($1 - $io_start_time);
     229              $io_start_time = 0;
     230            }
     231            elsif ($line =~ /\[Completed:(\d+(?:\.\d+)?)\]/)
     232            {
     233              my $end_time = $1;
     234              $task_record->{'end'} = $end_time;
     235              if ($io_start_time > 0)
     236              {
     237                $io_time += ($end_time - $io_start_time);
     238              }
     239            }
    148240          }
    149           elsif ($line =~ /\[Host:([^\]]+)\]/)
     241          close(TIN);
     242          # Calculate CPU time (total time - IO time)
     243          $task_record->{'cpu_time'} = $task_record->{'end'} - $task_record->{'start'} - $io_time;
     244
     245          # We should now have the filename - use this and try and locate a
     246          # convert log for this item (assuming it is multimedia, which it may
     247          # not be)
     248          if (defined $task_record->{'file'} && $task_record->{'file'} =~ /\/([^\/]+)\.ts/)
    150249          {
    151             $task_record->{'host'} = $1;
    152           }
    153           elsif ($line =~ /\[CPU:(\d+)\]/)
    154           {
    155             $task_record->{'cpu'} = $1;
    156           }
    157           elsif ($line =~ /\[Map:([^\>]+)=>/)
    158           {
    159             $task_record->{'file'} = $1;
    160           }
    161           elsif ($line =~ /\[IOS:(\d+)\]/)
    162           {
    163             $io_start_time = $1;
    164           }
    165           elsif ($io_start_time > 0 && $line =~ /\[IOE:(\d+)\]/)
    166           {
    167             $io_time += ($1 - $io_start_time);
    168             $io_start_time = 0;
    169           }
    170           elsif ($line =~ /\[Completed:(\d+(?:\.\d+)?)\]/)
    171           {
    172             my $end_time = $1;
    173             $task_record->{'end'} = $end_time;
    174             if ($io_start_time > 0)
    175             {
    176               $io_time += ($end_time - $io_start_time);
    177             }
    178           }
    179         }
    180         close(TIN);
    181         # Calculate CPU time (total time - IO time)
    182         $task_record->{'cpu_time'} = $task_record->{'end'} - $task_record->{'start'} - $io_time;
    183 
    184         # We should now have the filename - use this and try and locate a
    185         # convert log for this item (assuming it is multimedia, which it may
    186         # not be)
    187         if (defined $task_record->{'file'} && $task_record->{'file'} =~ /\/([^\/]+)\.ts/)
    188         {
    189           my $filename_sans_extension = $1;
    190           my $convert_log = $results_path . '/convert-' . $filename_sans_extension . '.log';
    191           if (-f $convert_log)
    192           {
    193             print '[Reading and parsing convert log]... ';
    194             if (open(CLIN, '<:utf8', $convert_log))
    195             {
    196               my $max_percent = 0.00;
    197               while (my $line = <CLIN>)
     250            my $filename_sans_extension = $1;
     251            my $convert_log = $results_path . '/convert-' . $filename_sans_extension . '.log';
     252            if (-f $convert_log)
     253            {
     254              print '[Reading and parsing convert log]... ';
     255              if (open(CLIN, '<:utf8', $convert_log))
    198256              {
    199                 if ($line =~ /.*Encoding: task 1 of 1, (\d+\.\d\d) \%/)
     257                my $max_percent = 0.00;
     258                while (my $line = <CLIN>)
    200259                {
    201                   my $percent = $1;
    202                   if ($percent > $max_percent)
     260                  if ($line =~ /.*Encoding: task 1 of 1, (\d+\.\d\d) \%/)
    203261                  {
    204                     $max_percent = $percent;
     262                    my $percent = $1;
     263                    if ($percent > $max_percent)
     264                    {
     265                      $max_percent = $percent;
     266                    }
    205267                  }
    206268                }
     269                close(CLIN);
     270                $task_record->{'percom'} = $max_percent;
    207271              }
    208               close(CLIN);
    209               $task_record->{'percom'} = $max_percent;
    210             }
    211             else
    212             {
    213               print STDERR "Warning! Failed to open log file for reading: " . $convert_log . "\n";
     272              else
     273              {
     274                print STDERR "Warning! Failed to open log file for reading: " . $convert_log . "\n";
     275              }
    214276            }
    215277          }
    216         }
    217 
    218         # Store this record
    219         $task_records->{$task_no} = $task_record;
    220       }
    221       else
    222       {
    223         die('Error! Failed to open file for reading: ' . $task_log_path);
    224       }
    225       print "Done!\n";
    226     }
    227   }
    228   close(DH);
    229 }
    230 else
    231 {
    232   die('Error! Failed to open directory for reading: ' . $results_path);
    233 }
    234 print ' - Processed ' . scalar(keys(%{$task_records})) . " records\n";
    235 
    236 # Generate compute-node records
    237 print ' * Generating compute node records... ';
    238 my $node_records;
    239 foreach my $taskno (sort keys %{$task_records})
    240 {
    241   my $task_record = $task_records->{$taskno};
    242   my $node_record = {'host'=>'', 'cpu'=>0, 'job' => '', 'start'=>0, 'end'=>0, 'cpu_time'=>0};
    243   # - retrieve any existing record
    244   my $worker_id = $task_record->{'host'} . '#' . $task_record->{'cpu'};
    245   if (defined $node_records->{$worker_id})
    246   {
    247     $node_record = $node_records->{$worker_id};
    248   }
    249   if ($node_record->{'host'} eq '')
    250   {
    251     $node_record->{'host'} = $task_record->{'host'};
    252   }
    253   if ($node_record->{'cpu'} == 0)
    254   {
    255     $node_record->{'cpu'} = $task_record->{'cpu'};
    256   }
    257   if ($node_record->{'job'} eq '')
    258   {
    259     $node_record->{'job'} = $task_record->{'job'};
    260   }
    261   if ($node_record->{'start'} == 0 || $task_record->{'start'} < $node_record->{'start'})
    262   {
    263     $node_record->{'start'} = $task_record->{'start'};
    264   }
    265   if ($node_record->{'end'} == 0 || $task_record->{'end'} > $node_record->{'end'})
    266   {
    267     $node_record->{'end'} = $task_record->{'end'};
    268   }
    269   $node_record->{'cpu_time'} += $task_record->{'cpu_time'};
    270   # - store it
    271   $node_records->{$worker_id} = $node_record;
    272 }
    273 print "Done!\n";
    274 
    275 # Write out CSV of all information
    276 my $report_csv_path = $results_path . '/timing.csv';
    277 if (open(CSVOUT, '>:utf8', $report_csv_path))
    278 {
    279   my $row_counter = 1;
    280   # Header
    281   print CSVOUT "id,name,hostname,start,end,cputime,dl,pid,filename,percom\n";
    282   # Master Record
    283   print CSVOUT $row_counter . ',M0,' . $job_record->{'host'} . ',' . $job_record->{'start'} . ',' . $job_record->{'end'} . ',' . ($job_record->{'cpu_time'} / 1000) . ",0,0,NA,NA\n";
    284   $row_counter++;
    285   # For each compute node record
    286   my $known_workers = {};
    287   foreach my $worker_id (natsort(keys(%{$node_records})))
    288   {
    289     my $node_record = $node_records->{$worker_id};
    290     my $node_id = $row_counter;
     278
     279          # Store this record
     280          $task_records->{$task_no} = $task_record;
     281        }
     282        else
     283        {
     284          die('Error! Failed to open file for reading: ' . $task_log_path);
     285        }
     286        print "Done!\n";
     287      }
     288    }
     289    close(DH);
     290  }
     291  else
     292  {
     293    die('Error! Failed to open directory for reading: ' . $results_path);
     294  }
     295  print ' - Processed ' . scalar(keys(%{$task_records})) . " records\n";
     296
     297  # Generate compute-node records
     298  print ' * Generating compute node records... ';
     299  my $node_records;
     300  foreach my $taskno (sort keys %{$task_records})
     301  {
     302    my $task_record = $task_records->{$taskno};
     303    my $node_record = {'host'=>'', 'cpu'=>0, 'job' => '', 'start'=>0, 'end'=>0, 'cpu_time'=>0};
     304    # - retrieve any existing record
     305    my $worker_id = $task_record->{'host'} . '#' . $task_record->{'cpu'};
     306    if (defined $node_records->{$worker_id})
     307    {
     308      $node_record = $node_records->{$worker_id};
     309    }
     310    if ($node_record->{'host'} eq '')
     311    {
     312      $node_record->{'host'} = $task_record->{'host'};
     313    }
     314    if ($node_record->{'cpu'} == 0)
     315    {
     316      $node_record->{'cpu'} = $task_record->{'cpu'};
     317    }
     318    if ($node_record->{'job'} eq '')
     319    {
     320      $node_record->{'job'} = $task_record->{'job'};
     321    }
     322    if ($node_record->{'start'} == 0 || $task_record->{'start'} < $node_record->{'start'})
     323    {
     324      $node_record->{'start'} = $task_record->{'start'};
     325    }
     326    if ($node_record->{'end'} == 0 || $task_record->{'end'} > $node_record->{'end'})
     327    {
     328      $node_record->{'end'} = $task_record->{'end'};
     329    }
     330    $node_record->{'cpu_time'} += $task_record->{'cpu_time'};
     331    # - store it
     332    $node_records->{$worker_id} = $node_record;
     333  }
     334  print "Done!\n";
     335
     336  # Write out CSV of all information
     337  my $report_csv_path = $results_path . '/timing.csv';
     338  if (open(CSVOUT, '>:utf8', $report_csv_path))
     339  {
     340    my $row_counter = 1;
     341    # Header
     342    print CSVOUT "id,name,hostname,start,end,cputime,dl,pid,filename,percom\n";
     343    # Master Record
     344    print CSVOUT $row_counter . ',M0,' . $job_record->{'host'} . ',' . $job_record->{'start'} . ',' . $job_record->{'end'} . ',' . ($job_record->{'cpu_time'} / 1000) . ",0,0,NA,NA\n";
    291345    $row_counter++;
    292     my $csv_worker_id = 'W' . $node_record->{'cpu'};
    293     # Ensure we haven't used this id before - this should never trigger for
    294     # multicore CPUs, but will for clusters (as nearly all nodes will report
    295     # themselves as 'W0')
    296     if (defined $known_workers->{$csv_worker_id})
    297     {
    298       # Find a different worker id as this one is already in use
    299       my $counter = 0;
    300       $csv_worker_id = 'W' . $counter;
    301       while (defined $known_workers->{$csv_worker_id})
    302       {
    303         $counter++;
     346    # For each compute node record
     347    my $known_workers = {};
     348    foreach my $worker_id (natsort(keys(%{$node_records})))
     349    {
     350      my $node_record = $node_records->{$worker_id};
     351      my $node_id = $row_counter;
     352      $row_counter++;
     353      my $csv_worker_id = 'W' . $node_record->{'cpu'};
     354      # Ensure we haven't used this id before - this should never trigger for
     355      # multicore CPUs, but will for clusters (as nearly all nodes will report
     356      # themselves as 'W0')
     357      if (defined $known_workers->{$csv_worker_id})
     358      {
     359        # Find a different worker id as this one is already in use
     360        my $counter = 0;
    304361        $csv_worker_id = 'W' . $counter;
    305       }
    306     }
    307     $known_workers->{$csv_worker_id} = 1;
    308     print CSVOUT $node_id . ',' . $csv_worker_id . ',' . $node_record->{'host'} . ',' . $node_record->{'start'} . ',' . $node_record->{'end'} . ',' . $node_record->{'cpu_time'} . ",0,1,NA,NA\n";
    309     # List the child task records
    310     foreach my $taskno (sort keys %{$task_records})
    311     {
    312       my $task_record = $task_records->{$taskno};
    313       if ($task_record->{'host'} . '#' . $task_record->{'cpu'} eq $worker_id)
    314       {
    315         print CSVOUT $row_counter . ',T' . ($task_record->{'task'} + 0) . ',' . $task_record->{'host'} . ',' . $task_record->{'start'} . ',' . $task_record->{'end'} . ',' . $task_record->{'cpu_time'} . ',' . $task_record->{'data_locality'} . ',' . $node_id . ',' . $task_record->{'file'} . ',' . $task_record->{'percom'} . "\n";
    316         $row_counter++;
    317       }
    318     }
    319   }
    320   close(CSVOUT);
    321 }
    322 else
    323 {
    324   die('Error! Failed to open file for writing: ' . $report_csv_path);
    325 }
    326 
    327 print "Complete!\n\n";
    328 exit;
    329 
     362        while (defined $known_workers->{$csv_worker_id})
     363        {
     364          $counter++;
     365          $csv_worker_id = 'W' . $counter;
     366        }
     367      }
     368      $known_workers->{$csv_worker_id} = 1;
     369      print CSVOUT $node_id . ',' . $csv_worker_id . ',' . $node_record->{'host'} . ',' . $node_record->{'start'} . ',' . $node_record->{'end'} . ',' . $node_record->{'cpu_time'} . ",0,1,NA,NA\n";
     370      # List the child task records
     371      foreach my $taskno (sort keys %{$task_records})
     372      {
     373        my $task_record = $task_records->{$taskno};
     374        if ($task_record->{'host'} . '#' . $task_record->{'cpu'} eq $worker_id)
     375        {
     376          print CSVOUT $row_counter . ',T' . ($task_record->{'task'} + 0) . ',' . $task_record->{'host'} . ',' . $task_record->{'start'} . ',' . $task_record->{'end'} . ',' . $task_record->{'cpu_time'} . ',' . $task_record->{'data_locality'} . ',' . $node_id . ',' . $task_record->{'file'} . ',' . $task_record->{'percom'} . "\n";
     377          $row_counter++;
     378        }
     379      }
     380    }
     381    close(CSVOUT);
     382  }
     383  else
     384  {
     385    die('Error! Failed to open file for writing: ' . $report_csv_path);
     386  }
     387}
     388
     3891;
Note: See TracChangeset for help on using the changeset viewer.