Search code examples
bashtailscraper

Bash : How to tail latest file in continuous loop


I am trying to write script that monitors log file and on specific error it performs certain function. I got the main code working however stuck with one problem. Application create new log file when system date changes (log file name pattern is LOG.NODE1.DDMMYYYY), how do I get my code to automatically switch to new file that is created. Following is my script so far,

#!/bin/sh

logfile=$(ls -t $DIR"/env/log/LOG"* | head -n 1)
echo $logfile
tail -f $logfile | while read LOGLINE
do

if [[  "${LOGLINE}" == *";A database exception has occurred: FATAL DBERR:  SQL_ERROR: ORA-00001: unique constraint (IX_TEST1) violated"* ]];

then
        #Do something

fi
done

Solution

  • #!/bin/bash
    #      ^^^^ -- **NOT** /bin/sh
    
    substring=";A database exception has occurred: FATAL DBERR:  SQL_ERROR: ORA-00001: unique constraint (IX_TEST1) violated"
    newest=
    timeout=10  # number of seconds of no input after which to look for a newer file
    
    # sets a global shell variable called "newest" when run
    # to keep overhead down, this avoids invoking any external commands
    find_newest() {
      set -- "${DIR?The variable DIR is required}"/env/log/LOG*
      [[ -e $1 || -L $1 ]] || return 1
      newest=$1; shift
      while (( $# )); do
        [[ $1 -nt $newest ]] && newest=$1
        shift
      done
    }
    
    while :; do
      find_newest  # check for newer files
      # if the newest file isn't the one we're already following...
      if [[ $tailing_from_file != "$newest" ]]; then
        exec < <(tail -f -- "$newest")  # start a new copy of tail following the newer one
        tailing_from_file=$newest       # and record that file's name
      fi
      if read -t "$timeout" -r line && [[ $line = *"$substring"* ]]; then
        echo "Do something here"
      fi
    done