You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Femi Oshagbemi <fo...@hotmail.com> on 2005/03/27 13:47:02 UTC

Read from Apache error.log

Hello, im very new to the perl, modperl and apache combination.

I was wondering if it is somehow possible to read the apache error.log input 
just after each execution of a procedure?

I am invoking another program from within my perl module using a 
'System(...)' call. Although the call is successfull, there are times when 
the invoked program may terminate with a 'parse error:' for example, and 
theses are logged in the error.log. Is there a way the catch or read this as 
it happens and display to the browser?


Im using a perl/apache binary - Perl-5.8-win32-bin.exe downloaded form 
http://httpd.apache.org/ and windows xp.


Anyone with any help or ideas please let me know

thanks in advance



Re: Read from Apache error.log

Posted by Stas Bekman <st...@stason.org>.
Femi Oshagbemi wrote:
> Hello, im very new to the perl, modperl and apache combination.
> 
> I was wondering if it is somehow possible to read the apache error.log 
> input just after each execution of a procedure?
> 
> I am invoking another program from within my perl module using a 
> 'System(...)' call. Although the call is successfull, there are times 
> when the invoked program may terminate with a 'parse error:' for 
> example, and theses are logged in the error.log. Is there a way the 
> catch or read this as it happens and display to the browser?

Instead of ``, qx or system, you can use Apache::SubProcess, IPC::Run or 
IPC::Run3 which all give you an access to STDERR of the sub-process. (Note 
that IPC::Open* don't work under mod_perl, at least not with 1.0, didn't 
test with 2.0).

If for some reason you still want to read from error_log, here is how:

we have a similar need in the mod_perl2 test suite, so here is how we
do that:

use TestCommon::LogDiff;

my $path = '/path/to/error_log'; # adjust this
my $logdiff = TestCommon::LogDiff->new($path);
# do something
my $diff = $logdiff->diff;

and here is the module that does the work:

package TestCommon::LogDiff;

use POSIX ();

sub new {
     my $class = shift;
     my $path  = shift;

     open my $fh, "<$path" or die "Can't open $path: $!";
     seek $fh, 0, POSIX::SEEK_END();
     $pos = tell $fh;

     my %self = (
         path => $path,
         fh   => $fh,
         pos  => $pos,
     );

     return bless \%self, $class;
}

sub DESTROY {
     my $self = shift;
     close $self->{fh};
}

sub diff {
     my $self = shift;

     # XXX: is it possible that some system will be slow to flush the
     # buffers and we may need to wait a bit and retry if we see no new
     # logged data?
     my $fh = $self->{fh};
     seek $fh, $self->{pos}, POSIX::SEEK_SET(); # not really needed

     local $/; # slurp mode
     my $diff = <$fh>;
     seek $fh, 0, POSIX::SEEK_END();
     $self->{pos} = tell $fh;

     return defined $diff ? $diff : '';
}

1;

__END__

=head1 NAME

TestCommon::LogDiff - get log file diffs

=head1 Synopsis

   use TestCommon::LogDiff;
   use Apache::Test;

   plan tests => 2;

   my $path = "/tmp/mylog";
   open my $fh, ">>$path" or die "Can't open $path: $!";

   my $logdiff = TestCommon::LogDiff->new($path);

   print $fh "foo 123\n";
   my $expected = qr/^foo/;
   ok t_cmp $logdiff->diff, $expected;

   print $fh "bar\n";
   my $expected = 'bar';
   ok t_cmp $logdiff->diff, $expected;


=head1 Description

Useful for testing the warning, error and other messages going into
the log file.

=head1 API

=head2 new

open the log file and point the filehandle pointer to its end.

=head2 diff

extract any newly logged information since the last check and move the
filehandle to the end of the file.

=cut


-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

Re: Read from Apache error.log

Posted by Clinton Gormley <cl...@traveljury.com>.
> Admittedly, I should have read your original post more closely.  The program your calling with system fails, not the system call itself, so eval would not catch this.  Have you considered using the backtick operator and inspect the output for errors? This might not be feasible if the called program has a large amount of output that might mimic what error text you're looking for.

>>From perldoc -f system : (excerpt)

The return value is the exit status of the program as returned by the
"wait" call.  To get the actual exit value shift right by eight (see
below).  See also "exec".  This is not what you want to use to capture
the output from a command, for that youshould use merely backticks or
"qx//", as described in "‘STRING‘" in perlop.  Return value of −1
indicates a failure to start the program (inspect $! for the reason).

Also, look at : perldoc perlfaq8, starting with the question :
"Why can’t I get the output of a command with system()?"

________________________________________________________________________

Clinton Gormley clinton@traveljury.com

www.TravelJury.com - For travellers, By travellers




Re: Read from Apache error.log

Posted by Rodger Castle <ro...@profocusdesigns.com>.
> I had Initially tried using 'eval' however it seemed to me that no 
> exceptions were thrown by the function call within the eval {system...} but 
> within the called program itself, I may be wrong. In either case that method 
> brought me no success unfortunately.

Admittedly, I should have read your original post more closely.  The program your calling with system fails, not the system call itself, so eval would not catch this.  Have you considered using the backtick operator and inspect the output for errors? This might not be feasible if the called program has a large amount of output that might mimic what error text you're looking for.

Rodger

Re: Read from Apache error.log

Posted by Femi Oshagbemi <fo...@hotmail.com>.
thanks Rodger,

I had Initially tried using 'eval' however it seemed to me that no 
exceptions were thrown by the function call within the eval {system...} but 
within the called program itself, I may be wrong. In either case that method 
brought me no success unfortunately.


>From: Rodger Castle <ro...@profocusdesigns.com>
>To: modperl@perl.apache.org
>Subject: Re: Read from Apache error.log
>Date: Sun, 27 Mar 2005 06:59:44 -0500
>
> > Hello, im very new to the perl, modperl and apache combination.
> >
>
>So am I, but I think I have a usable solution for you.
>
> > I am invoking another program from within my perl module using a
> > 'System(...)' call. Although the call is successfull, there are times 
>when
> > the invoked program may terminate with a 'parse error:' for example, 
>and
> > theses are logged in the error.log. Is there a way the catch or read 
>this as
> > it happens and display to the browser?
>
>Here's what I do ... add the line
>
>use Carp;
>
>to your Module list (checkout the perldocs on it for full details)
>
>Wrap your call in an 'eval {};' block.  Example ...
>
>eval
>{
>	System.call (...);      # This is the call that you're expecting an error 
>from
>};  ## Don't forget the semi-colon
>if ( $@ )
>{
>	$r->print ( "Uh oh. Error found: $@" );
>	carp ( $@ );
>}
>
>The eval acts as an exception handler.  There is some discussion on the 
>mod_perl site for using eval and Carp for exception handling.
>
>Hope the helps.
>
>Rodger



Re: Read from Apache error.log

Posted by Rodger Castle <ro...@profocusdesigns.com>.
> Hello, im very new to the perl, modperl and apache combination.
> 

So am I, but I think I have a usable solution for you.

> I am invoking another program from within my perl module using a 
> 'System(...)' call. Although the call is successfull, there are times when 
> the invoked program may terminate with a 'parse error:' for example, and 
> theses are logged in the error.log. Is there a way the catch or read this as 
> it happens and display to the browser?

Here's what I do ... add the line

use Carp;

to your Module list (checkout the perldocs on it for full details)

Wrap your call in an 'eval {};' block.  Example ...

eval
{
	System.call (...);      # This is the call that you're expecting an error from
};  ## Don't forget the semi-colon
if ( $@ )
{
	$r->print ( "Uh oh. Error found: $@" );
	carp ( $@ );
}

The eval acts as an exception handler.  There is some discussion on the mod_perl site for using eval and Carp for exception handling.

Hope the helps.

Rodger