The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Log::Progress::Parser - Parse progress data from a file

VERSION

version 0.000_001

SYNOPSIS

  open my $fh, "<", $logfile or die;
  my $parser= Log::Progress::Parser->new(input => $fh);
  
  # Display a 40-character progress bar at 1-second intervals
  $|= 1;
  while (1) {
    $parser->parse;
    printf "\r%3d%%  [%-40s] ", $parser->status->{progress}*100, "#" x int($parser->status->{progress}*40);
    last if $parser->status->{progress} >= 1;
    sleep 1;
  }
  print "\n";

DESCRIPTION

This module parses progress messages from a file handle or string. Repeated calls to the "parse" method will continue parsing the file where it left off, making it relatively efficient to repeatedly call "parse" on a live log file.

ATTRIBUTES

input

This is a seekable file handle or scalar of log text from which the progress data will be parsed. Make sure to set the utf-8 layer on the file handle if you want to read progress messages that are more than just ascii.

input_pos

Each call to parse makes a note of the start of the final un-finished line, so that the next call can pick up where it left off, assuming the file is growing.

status

This is a hashref of data describing the progress found in the input.

  {
    progress => $number_between_0_and_1,
    message  => $current_progress_messsage,  # empty string if no message
    pos      => $numerator,   # only present if progress was a fraction
    max      => $denominator, #
    step     => \%sub_steps_by_id,
    data     => \%data,       # most recent JSON data payload, decoded
  }

Substeps may additionally have the keys:

    idx          => $order_of_declaration,   # useful for sorting
    title        => $name_of_this_step,
    contribution => $percent_of_parent_task, # can be undef

on_data

Optional coderef to handle JSON data discovered on input. The return value of this coderef will be stored in the "data" field of the current step.

For example, you might want to combine all the data instead of overwriting it:

  my $parser= Log::Progress::Parser->new(
    on_data => sub {
      my ($parser, $step_id, $data)= @_;
      return Hash::Merge::merge( $parser->step_status($step_id), $data );
    }
  );

METHODS

parse

Read (any additional) "input", and return the "state" field, or die trying.

  my $state= $parser->parse;

Sets "input_pos" just beyond the end of the final complete line of text, so that the next call to "parse" can follow a growing log file.

step_status

  my $status= $parser->step_status($step_id, $create_if_missing);
  my $status= $parser->step_status($step_id, $create_if_missing, \@path_out);

Convenience method to traverse "status" to get the data for a step. If the second paramter is false, this returns undef if the step is not yet defined. Else it creates a new empty status node (which should get its title set, at a minimum)

AUTHOR

Michael Conrad <mike@nrdvana.net>

COPYRIGHT AND LICENSE

This software is copyright (c) 2016 by Michael Conrad.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.