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

Hello, I have written a library to tail the log file in a router and look for a string.

If the string is found it returns the time stamp at which the string was found.

If the string is not found it returns 0 .

the script compiles without any errors. However it returns 0 (flase) everytime even if the string is found.

It would be really helpful if someone can help me out with this. I tried various things since morning but im unable to figure it out

use strict; use warnings; sub new { my ( $this, @_ARGS ) = @_; my $class = ref($this) || $this; my $self = { _permitted => \%CLI::FIELDS, %CLI::FIELDS, @_ARGS }; bless $self, $class; # _validateFields is inherited from AKU::Object and checks to ensu +re # that what is passed as arguments to new is in the %FIELDS hash $self->_validateFields(@_ARGS); return $self->_init(); } # function to tail the logs and watch for a string. sub log_watch { my ($self, $log, $string) = @_; my $timestamp = 0; my $cmd = "type-tail $log follow"; # command to tail the file my $prompt = "::$string"; # without a terminal length of 0 some lines get split so set it ex +plicitly $self->execute( 'terminal length 0' ); # execute the command $self->execute( $cmd . $prompt ); $self->{'stdout'} = $self->get_stdout(); if ( $self->get_error() ) { # try to disconnect $self->execute("\cC"); return 0; } # try to disconnect $self->execute("\cC"); foreach my $line ( @{ $self->{'stdout'} } ) { if ( $line =~ m/^(\d+\/\d+\/\d+\s\d+\:\d+\:\d+\.\d+)/msx ) { $timestamp = $1; } DEBUG("Line: $line"); } return $timestamp; }

Im using the above lib in a sample script as below

Function call :
sub testMain { my $log_obj = LogUtils->new( ip => 'ip addr ' ); my $retrieval_time = $log_obj->log_watch( 'logfile.txt', # file name 'm-ns - - 200 GET http://www.google.com' # string to be searched ); INFO("Found retrieval of the specified string at $retrieval_time");

below is the output

output : 20140806T003044 INFO Found retrieval of the specified string at 0

Replies are listed 'Best First'.
Re: tailing the file and look for string
by hippo (Archbishop) on Aug 06, 2014 at 08:20 UTC

    Extracting the pertinent parts of your code we see this:

    sub log_watch { ... my $timestamp = 0; ... if ( $line =~ m/^(\d+\/\d+\/\d+\s\d+\:\d+\:\d+\.\d+)/msx ) { $timestamp = $1; } ... return $timestamp; }

    From which we can conclude that as $timestamp is still zero at the return point, your regex does not ever match $line. So, either your regex is wrong or $line is not what you think it is, or your log_watch method returns before $line is even tested or you have no entries in $self->{'stdout'}.

Re: tailing the file and look for string
by NetWallah (Canon) on Aug 06, 2014 at 02:27 UTC
    The absence of the " DEBUG("Line: $line");" output, and the returning 0 makes it seem like you are getting the condition:
    $self->get_error()
    You are doing mo error checking or logging/reporting .. makes it very hard to diagnose, especially in this case, where it appears you are connecting via a flaky (apparently telent like) method to a remote machine.

            Profanity is the one language all programmers know best.

Re: tailing the file and look for string
by Anonymous Monk on Aug 06, 2014 at 01:38 UTC
    DEBUG("Line: $line")

    Where is the output of DEBUG?

Re: tailing the file and look for string
by locked_user sundialsvc4 (Abbot) on Aug 06, 2014 at 02:10 UTC

    My blunt ... but, by no means intended to be “blunt” ... take on this is that:

    You seem to have forgotten that Perl is a full-featured programming language ... not an over-glorified [Bash ...] script.   “Instead, Plan Accordingly.™”

    For example:   “tailing a file” simply means:   seek( filehandle, distance, SEEK_END).   Nothing more, nothing less, no matter how “big” the file in-between might be.   We’ve been doing this sort of thing for random-access disk files since, uhh, the 1950’s.   Thus, the Perl programming language is quite able to solve this problem without resorting to any sort of “bash-script hack” metaphors ... and, so, you should do the same.

    (No, I am not trying to make fun of you in a public place!!!   Please, let us herewith “put any egos aside,” and speak frankly as though we were not in-public.   I have no way of speaking that is not public.   “But, I digress™ ...”)

    To solve your problem, you simply need to read “some n bytes” from the SEEK_END of the file in question, then use ordinary regular-expression logic against the buffer thusly obtained, in a loop, choosing the last match that you may find in such a loop, and taking a calculated risk that you didn’t happen to choose exactly the wrong starting-point.

      It would have been really helpful for me if you had suggested me something that would have helped me in resolving this issue. Anyways thanks!!

        It is not at all uncommon here for people to answer the question you should have asked (in their opinion) instead of the question you did ask. I'd estimate this is helpful at least 50% of the time for the OP. It is much more likely to help the next guy who finds the thread via a search.

        1 Peter 4:10
      A reply falls below the community's threshold of quality. You may see it by logging in.