http://www.perlmonks.org?node_id=585285


in reply to Re^2: trouble parsing log file...
in thread trouble parsing log file...

EDIT: Success! I got it now, thanks for your help everyone!
use warnings; $logfile="log.txt"; $error="DOWN"; $warn="PROBLEM"; $redbutton="\<img src\=\'default_files/perlredblink2\.gif'>"; $greenbutton="\<img src\=\'default_files/perlgreenblink\.gif'>"; $yellowbutton="\<img src\=\'default_files/perlyellowblink\.gif'>"; open LOG, $logfile or die "Cannot open $logfile for read :$!"; my $button = $greenbutton; while (<LOG>) { if ($_ =~ /$error/i) { $button = $redbutton; print "<!--Content-type: text/html-->\n\n"; print "$redbutton"; } if ($_ =~ /$warn/i) { $button = $yellowbutton; print "<!--Content-type: text/html-->\n\n"; print "$yellowbutton"; } } close LOG;

Replies are listed 'Best First'.
Re^4: trouble parsing log file...
by McDarren (Abbot) on Nov 21, 2006 at 16:04 UTC
    Your problem is here...
    $logfile="log.txt";
    and here...
    if ($logfile =~ /$error/i) {
    Can you see?
    You are trying to match the string "DOWN" against the string "log.txt". Of course, that will never match :)

    I think you want:

    while (my $line = <LOG>) { if ($line =~ /$error/i) { etc....

    Cheers,
    Darren :)

Re^4: trouble parsing log file...
by perl_geoff (Acolyte) on Nov 21, 2006 at 18:21 UTC
    OK, here's my latest:
    use strict; use warnings; my $logfile="log.txt"; my $error="DOWN"; my $warn="PROBLEM"; my $redbutton="\<img src\=\'default_files/perlredblink\.gif'>"; my $greenbutton="\<img src\=\'default_files/perlgreenblink\.gif'>"; my $yellowbutton="\<img src\=\'default_files/perlyellowblink\.gif'>"; open LOG, $logfile or die "Cannot open $logfile for read :$!"; my $button = $greenbutton; while ($_ = <LOG>) { if ($_ =~ /$error/i) { $button = $redbutton; print "<!--Content-type: text/html-->\n\n"; print "$button"; } elsif ($_ =~ /$warn/i) { $button = $yellowbutton; print "<!--Content-type: text/html-->\n\n"; print "$button"; } else { print "<!--Content-type: text/html-->\n\n"; print "$button"; } } close LOG;
    Now, when I test the output upon changing the log values locally, I get exactly the outputs I want; I am using Perl 5.8.8. However, when I test it on my server, which is using Perl 5.6.1 my server-side include to call this file from HTML does some really funky stuff (it actually shows two green, one yellow, two red, one yellow then one red,) but I think that may be a different issue with my server configuration. Should I upgrade the Perl version on my server to get this to execute correctly? Or, are you guys still seeing problems with my code? Thanks for any help.

      First of all, you really should specify the mode you want Perl to open your file with. So:

      open LOG, "<", $logfile or die "Cannot open $logfile for read: $!";

      Secondly, the reason you're getting multiple buttons is because as you go over each line in your log file, you're printing out either a red button, a yellow button or whatever the previous value of $button was.

      Do you want coloured buttons for every line in your file? Or do you want one just for the last line? Alternately, do you want to have one button representing the biggest problem? As in, if there was something that signalled a "red" button and a "yellow" button that you only get one red one?

      I'm going to assume that you want the latter. So that if all the lines in the file look boring, you get 1 green button. If any of them are worth warnings, you get a yellow, and if any are red, you get a red; but in all cases you only get one button. I'm also going to assume that you only need to print the header out once, and that you will always print it.

      use strict; use warnings; # Create some constants my $logfile = "log.txt"; my $error = "DOWN"; my $warn = "PROBLEM"; my ($GREEN, $YELLOW, $RED) = (0, 1, 2); my $greenbutton = "\<img src\=\'default_files/perlgreenblink\.gif'>"; my $yellowbutton = "\<img src\=\'default_files/perlyellowblink\.gif'>" +; my $redbutton = "\<img src\=\'default_files/perlredblink\.gif'>"; my @buttons = ($greenbutton, $yellowbutton, $redbutton); open LOG, "<", $logfile or die "Cannot open $logfile for read :$!"; # If there aren't any log entries, it is probably green. my $severity = $GREEN; # Read each line and record the highest severity while ( <LOG> ) { # If it's red, we might as well stop looking as it's # not going to get any better if ( $_ =~ /$error/i ) { $severity = $RED; last; } # If it's a warning, move up to yellow elsif ( $_ =~ /$warn/i ) { # next if $severity > $YELLOW; # needed if no last above $severity = $YELLOW; } # It's only green if it was already green. else { next if $severity > $GREEN; $severity = $GREEN; } } close LOG; # Print out our button print "<!--Content-type: text/html-->\n\n"; print $buttons[$severity], "\n";

      A flaw with this approach is that as time moves on, red buttons may not longer mean anything. For example, if the log file contains data from 2 days ago, then a "DOWN" back then has probably been resolved now. As such, you may find it useful to have a look at Log::Tail to allow you to tail log events on live logs, and to record when the red and yellow events happen so that you can reduce their severity over time.

      Such a program will be much more complicated than this though.

      I hope this helps.

        Thank you...I had actually already fixed the problem with multiple buttons. The main issue I had was I couldn't figure out a correct/safe way to loop through the entire log. I notice you didn't throw the log into the array. To explain what I really want with this program, essentially there are going to be multiple error/warning strings. I want the program to parse my document and on a priority basis, display one red button if it sees any 'red' errors. 2nd priority would be one yellow button if it seen any 'yellow' warnings. If it doesn't see any of either of these error/warning strings, it would display one green button. In order to fix these errors, the buttons will actually be image links to the log directories, so I will be able to click the button, go to the directory, read the log and figure out what the problem is. I would like to make the program more advanced in the future, but I would like to get something working as soon as possible, and improve upon it later (as needed.) Your code does help very much; I suppose I don't need to throw the log into an array to loop through the whole thing after all (to get the effect I want.) Thanks! :)