I'm trying to write a bash script to observe a catalina.out
logfile. Every time the string java.lang.OutOfMemoryError
appears it should restart the tomcat.
(I know it would be better to find the bug inside the webapp but the webapp needs to run until the developers find the bug. So this is only a hotfix for (hopefully) a short time.)
The problem is that “break” doesn't leave the while loop immediately when it finds the pattern. More details below.
Here the script:
#!/bin/bash
LOGFILE=/var/log/catalina.out
LOCKFILE=/tmp/pointtest.lock
while [ /bin/true ]
do
echo "Starting tail-Loop"
tail -fn0 ${LOGFILE} | \
while read line
do
echo "Inside tail-Loop"
echo "$line" | grep "java.lang.OutOfMemoryError" > /dev/null
if [ $? = 0 ]
then
echo "Error! java.lang.OutOfMemoryError"
# here should be the command to restart tomcat
break
fi
done
echo "Left tail-Loop"
done
Here a test input file (filename: noErrors
) with no errors:
Something Something Something Something Anything Something Something Do something And so on Anything Something
Here a test input file (Filename: oomErrors
) with Out of memory errors:
Something Something java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: Java heap space at java.util.concurrent.FutureTask.report(FutureTask.java:122) at java.util.concurrent.FutureTask.get(FutureTask.java:192) at org.apache.catalina.core.ContainerBase.threadStart(ContainerBase.java:1276) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessorMonitor.run(ContainerBase.java:1322) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748) java.lang.OutOfMemoryError: Java heap space Something Something Anything java.lang.OutOfMemoryError: Java heap space java.lang.OutOfMemoryError: Java heap space Something Something Do something And so on java.lang.OutOfMemoryError: Java heap space Anything Something
First:
touch /var/log/catalina.out
Then start the script.
Output:
Starting tail-Loop
Now I'm doing the following command:
cat noErrors >> /var/log/catalina.out
The output of the script:
Inside tail-Loop Inside tail-Loop Inside tail-Loop Inside tail-Loop Inside tail-Loop Inside tail-Loop Inside tail-Loop Inside tail-Loop Inside tail-Loop Inside tail-Loop Inside tail-Loop Inside tail-Loop
So until here the script works as expected.
Now I'm doing the following command:
cat oomErrors >> /var/log/catalina.out
Output of the script:
Inside tail-Loop Inside tail-Loop Inside tail-Loop Error! java.lang.OutOfMemoryError
The first 2 lines of oomErrors
are handled correct. Then the script finds the OOM-pattern but it doesn't leave the tail-while-loop.
Then I do this command:
cat noErrors >> /var/log/catalina.out
The output of the script:
Left tail-Loop Starting tail-Loop
Only here it left the tail-while-loop and restarts the tail-while-loop.
It seems that after detecting the first line with error it ignores the following lines and stops at the break command.
So my question: Why doesn't the script leave the tail-while-loop immediately after finding the first line with the error string and how can I fix this?
Thanks in advance :-)