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

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

i am a complete novice with perl, i am trying so hard to learn this language but i am struggling with perl (a lot really).

i developed a bash script that would continuously read a log file, search for a particular string, and if it found the string, email a notification to the admins and restart a service.

how exactly could i do this in perl?

specifically, i want to tail /var/log/ldap.log and grep for connection_input: conn=11
if connection_input: conn=11 is found, then send an email and restart ldap.
if it's not found, then no action needed.

Replies are listed 'Best First'.
Re: guidance with a realtime log reader
by toolic (Bishop) on Aug 29, 2013 at 17:27 UTC
Re: guidance with a realtime log reader
by thewebsi (Scribe) on Aug 29, 2013 at 19:32 UTC

    Since Perl integrates well with the shell, you can also transition stepwise into a full Perl implementation.

    For example, start with a command-line script:

    >tail -f /var/log/ldap.log | perl -ne 'if ( /connection_input: conn=11/ ) { system ( "send an email" ); system ( "restart ldap" ); }'

    Then move the code into a Perl script file:

    >tail -f /var/log/ldap.log | process.pl

    Then take over the function of tail in Perl:

    >process.pl

    And finally maybe replace some of the system calls with Perl equivalents (eg, Mail::Sendmail)...

Re: guidance with a realtime log reader
by rodion (Chaplain) on Aug 29, 2013 at 21:42 UTC
    Don't forget that you will need to provide for stopping and restarting your script at the the time when the log file turns over to a new copy. (On the log file side, the change is often done using "rotate".) Without that, your tail command might be listening to a log that has been renamed from "logfile" to "logfile.0". You'll be listening it logfile.0, the inode that you opened, which is no longer being written to, and nothing is listening to the new day's copy of "logfile".

    Just a caution.

      Thank you so much for responding ... I'll try to work on it this weekend to convert from bash to perl. And good call with the log rotating. :) If anyone is interested, here is my bash script:
      #!/bin/bash string="connection_input: conn=11" tail -n 0 -F /var/log/ldap.log | \ while read LINE do echo "$LINE" | grep -q $string if [ $? = 0 ] then echo -e "$string found on $HOSTNAME" | mail -s "LDAP authentication on + $(hostname)" teamsupport@yourdomain.com fi done
      But I have to start it with a no hangup script
      #!/bin/bash nohup ./ldap_log_reader.sh 0<&- &>/dev/null &
Re: guidance with a realtime log reader
by pemungkah (Priest) on Aug 30, 2013 at 21:04 UTC
    The select() function can be called so as to wait until input is available on a filehandle. This is probably the key to getting the tail-like behavior you want. Take a look at perldoc -f select. The only difficult bit is setting up the bit mask.

    If this is running in root's crontab, then it can just do the appropriate kill -1 equivalent (Perl has a kill() function too) to restart LDAP.