Frage

I need to remote tail log files such that the tailing continues working even when the file is rolled over.

My attempts to do so, started by directly using the tail command over ssh:

ssh root@some-remote-host tail -1000f /some-directory/application.log | tee /c/local-directory/applicaiton.log

That allows me to filter through /c/local-directory/applicaiton.log locally using Otroslogviewer (which was the original purpose of trying to tail the log file locally).

The above stops tailing when the remote log file is rolled over (which happens at every 10MB). I do not have the access required to change the roll over settings.

Unfortunately, none of the tail versions on the remote OS (Solaris) support a --follow (or -f) option which can handle file rollovers, so I had to write the following tailer.sh script to simulate that option:

<!-- language: lang-bash -->
#!/bin/bash

function startTail {
echo "Path: $1"
tail -199999f "$1" 2>/dev/null &                 #Try to tail the file
while [[ -f $1 ]]; do sleep 1; done              #Check every second if the file still exists
echo "***** File Not Available as of: $(date)"   #If not then log a message and,
kill "$!" 2>/dev/null                            #Kill the tail process, then


echo "Waiting for file to appear"                #Wait for the file to re-appear
while [ ! -f "$1" ]
do
  echo -ne  "."                                  #Show progress bar
  sleep 1
done

echo -ne '\n' #Advance to next line              #File has appeared again
echo "Starting Tail again"

startTail "$1"
}

startTail "$1"

I am relatively happy with the above script. However, it suffers from one issue stemming from the limitation of the sleep command on the remote OS. It can only accept whole numbers, so sleep 1 is the smallest amount of time I can wait before checking for the existence of the file again. That time period is enough to detect a file rollover sometimes, but fails enough number of times to be a problem I want to fix.

The only other way I can think of is to implement a file-rollover check by checking for the file size. So, check for the filesize every one second, if it's less than the previously recorded size then the file was rolled over. Then, re-start the tail.

I checked for other more reliable alternatives like inotifywait, inotify but they are not available on the remote server(s) and I do not have the access to install them.

Can you think of any other way to detect a file rollover with a bash script?


Edit: Based on Hema's answer below, the modified (working!) script is as follows:

#!/bin/bash


function startTail {
echo "Path: $1"
tail -199999f "$1" 2>/dev/null &            #Try to tail the file

#Check every second if the file still exists
while [[ -f $1 ]]
do
perl -MTime::HiRes -e "Time::HiRes::sleep(0.1)"
done

echo "***** File Not Available as of: $(date)"  #If not then log a message and,
kill $! 2>/dev/null             #Kill the tail process, then


echo "Waiting for file to appear"       #Wait for the file to re-appear
while [ ! -f $1 ]
do
  echo -ne  "."                 #Show progress bar
  sleep 1
done

echo -ne '\n' #Advance to next line     #File has appeared again
echo "Starting Tail again"

startTail "$1"
}

startTail "$1"
War es hilfreich?

Lösung

For sleeping in microseconds, you can use

perl -MTime::HiRes -e "Time::HiRes::usleep(1)" ; 
perl -MTime::HiRes -e "Time::HiRes::sleep(0.001)" ;

Andere Tipps

Unfortunately, none of the tail versions on the remote OS (Solaris) support the --follow option

That's a little harsh.

Just use -f (rather than --follow) on both Solaris and Linux. On Linux you can use --follow as a synonym for -f. On Solaris you can't.

But anyway, to be more precise: you want a follow option that handles rollovers. GNU tail (i.e. Linux) has that natively by the way of the -F (capital F) option. Solaris doesn't. The GNU tail -F option can handle that the file is rolled over as long as it keeps the name name. In other words on Solaris you would have to use gtail command to force the use of GNU tail.

If you are a prudent Solaris site then such GNU tool would just be there, without you having to worry about it. You shouldn't accept a Solaris install from your SysAdmin where he/she has deliberately neglected to make sure the basic GNU tools are there. On Solaris 11 (as an example) he really has to go out of his way to make that happen.

You would make your script OS independent by the well known method:

TAILCMD="tail"

# We need GNU tail, not any other implementation of 'tail'
if [ "$(uname -s)" == "SunOS" ]; then
  TAILCMD="gtail"
fi

$TAILCMD -F myfile.log
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top