package Service::ParseLog; use strict; use Carp; use Symbol qw/gensym/; # Takes the log filename and opens for parsing sub new { my $class = shift; my $file = shift or croak("No filename passed"); my $obj = {}; $obj->{file} = $file; my $fh = &gensym(); open ($fh, "<$file") or confess("Cannot read $file: $!"); $obj->{fh} = $fh; $obj->{line_no} = 0; return bless $obj, $class; } # Reads the next service section. In array context it # the lines in the service. In scalar it returns whether # there is more in the file. The service is in the # last_service field. The is_parsing field indicates # whether it found the end of the last service it started. sub read_service { my $self = shift; my $fh = $self->{fh}; my $line_no = $self->{line_no}; # Find the *'s for the service if (<$fh>) { ++$line_no; if (/^\*{5}/) { $self->{is_parsing} = 1; } else { confess("No next service at $line_no in $self->{file}"); } } else { # EOF undef($self->{last_service}); return 0; } # Grab a service section and return it my @service; $self->{is_parsing} = 1; while (<$fh>) { ++$line_no; if (/^\*{5}/) { # End of service $self->{is_parsing} = 0; last; } else { push @service, $_; } } $self->{line_no} = $line_no; $self->{last_section} = \@service; return wantarray ? @service : !$self->{is_parsing}; } #### my $log = new Service::ParseLog("servlog.txt"); while ($log->read_service()) { my @lines = @{$log->{last_service}}; # do stuff } if ($log->{is_parsing}) { # Incomplete last service }