How to check whether tomcat server is started up - bash

I want to check if tomcat server is really started up. When you start tomcat, you get an entry like "Server startup" in catalina.out. Once I got this, the script should go ahead.
That's my code
echo "Waiting for Tomcat"
if [ $(tail -f /home/0511/myapp/logs/catalina.out | grep "Server startup" | wc -l) -eq 1 ]; then
echo "Tomcat started"
fi
#further code...
Output:
Waiting for Tomcat
|
So, I am sure, after 30-60 seconds, the "tail .. | wc -l" gets 1. However, I cannot match it with my code above. Nothing happens, I have to interrupt per CTRL C.
What is wrong or is there any better solution for my intention?

Try this:
while true;do
if tail -n 100 /home/0511/myapp/logs/catalina.out | grep -q "Server
startup";then
echo "Tomcat started"
exit 0
fi
done
So you constantly check the last 100 lines from the log, and if match, exit with a message.
Another (more elegant) solution without a loop:
if tail -f /home/0511/myapp/logs/catalina.out | grep -q "Server
startup";then
echo "Tomcat started"
fi

You said "I want to check if tomcat server is really started up". If you check the log with tail and grep, in worst case scenario, you could detect an old start which ended with a crash.
Tomcat server when is started it is listening to a certain port(e.g. 8080). So you should check if tomcat server is listening on that port.
If you are using a different port replace 8080 in following lines with your custom port.
In order to display tomcat status you should use netstat. Example of a line returned by netstat:
TCP 0.0.0.0:8080 0.0.0.0:0 LISTENING
In order to display only if Tomcat is started or not, you could use:
netstat -an|grep -e ":8080[^0-9].*[0-9].*LISTENING" && echo "Tomcat started" || echo "Tomcat not started"
The grep expression matches ":" followed by port 8080, followed by non-digit, followed by any characters, followed by digit, followed by any characters, followed by "LISTENING".
In order to wait for Tomcat you could use:
echo Waiting for Tomcat port to be ...
until netstat -an | grep -e ":8080[^0-9].*[0-9].*LISTENING" > /dev/null ; do
sleep 1 ;
done
echo Tomcat started

grep doesn't exit as soon as it found a match; it keeps reading for further matches.
To make grep not produce any output, but instead exit with 0 status as soon as a match is found, use the -q option:
if tail -f /home/0511/myapp/logs/catalina.out | grep -q "Server startup"; then
That said, a log message isn't the most reliable way to check if a server is actually up and serving. Instead, you could try, for example, repeatedly polling it with curl instead.

Related

Bash Script to check for host

I have a complicated script request that I am trying to figure out. Basically, I need a script that will check for certain conditions and depending on the outcome will run certain commands.
So, I need it to check if $hostip is up and running. If it is running, I need it to check and see if $domain has same IP address as $domainip. If they match, script then ends. If they don't match, I need to run command "shutdown $hostip". Now, if it fails to find $domain, ie internet is down, then I need it to sleep for 6 hours and then try again. I want it to try 3 times and if still can't find domain after 18 hours, then run "shutdown $hostip".
The goal above is to shutdown a server if the domain does not match the set IP or the internet is disconnected for 18 hours.
I also need script to check the other side of things as well. So, if $hostip is not online, but $domain and $domainip do match, then power on server.
These are my variables I have so far.
domain=google.com
domainip=216.58.194.46
hostip=192.168.1.1
gatewayip=$(ping -q -c 1 -t 1 $domain | grep PING | sed -e "s/).*//" | sed -e "s/.*(//")
So there are two parts to this.
First, you need to check if the hosts is up. You can do this with ping as you have done:
ping -q -c 1 "$domain" >/dev/null 2>&1
which will set its exit code to true or false as expected if the host is up or down. Note I've removed the -t option as it was causing the ping to fail.
Second, you need to check that $domain resolves to $domainip. You can do this with several tools - host is straightforward:
host -t a $domain | grep -q "$domain has address $domainip"
Putting that together you get something like:
domain=google.com
domainip=216.58.194.46
hostip=192.168.1.1
for i in {1..3}; do
sleep 6h
if ping -q -c 1 "$domain" 2>/dev/null; then
exit 0
fi
if host -t a $domain | grep -q "$domain has address $domainip"; then
exit 0
fi
done
shutdown $hostip

Socket problem on Debian 9 - How to use bash script to check

I have a service on Debian 9. I also have a bash restarter so if the service shuts down unexpectedly, the restarter will make it run again.
The restarter basically does:
if (this service is not running); then
run service
fi
The problem I have is that sometimes, after the service shuts down unexpectedly, the restarter makes it run again but I get the error:
failed to bind socket acceptor
The service is running but not really working.
What can I add on my restarter so it checks the socket is available first and then, run the service? I am trying a lot of things posted here but nothing works so far.
Your problem is probably caused by a connection in TIME_WAIT state (see e.g. here).
You can avoid this problem by using SO_REUSEADDR in the application.
If you can not alter the application you would have to check for this condition in the restarter and delay service start until the TIME_WAIT connection vanishes.
This check can be done by analyzing the output of netstat, e.g.:
while netstat -n | egrep ':5678.*:.*TIME_WAIT' >/dev/null ; do sleep 0.1 ; done
Where 5678 is your service port number.
Good luck!
EDIT> Restarter snippet with a check:
pidof service >/dev/null
PID1=$?
if [ $PID1 -eq 1 ] ; then
while netstat -n | egrep ':5678.*:.*TIME_WAIT' >/dev/null ; do sleep 1 ; done
screen -A -dmS service1 gdb --batch -x /home/server/crashreport.gdb /home/server/bin/service
fi
Note that a shorter form is possible:
if ! pidof service >/dev/null ; then
while netstat -n | egrep ':5678.*:.*TIME_WAIT' >/dev/null ; do sleep 1 ; done
screen -A -dmS service1 gdb --batch -x /home/server/crashreport.gdb /home/server/bin/service
fi
If your restarter runs this check in a loop you should give screen and gdb its time to start the service (otherwise the service could be run two times which might cause a similar error message as the one in your question...)

If condition based on tail and grep commands in Shell Script

I want to write an if condition in Shell script something like this:
if[ tail -10f logFile | grep -q "RUNNING" ]
So the idea is I have restarted my server and want to perform some action only after the server is started up(RUNNING). So I want to continuously tail the log and check if the server is in RUNNING mode again.
The issue with the above approach is it does not exits even after the server is RUNNING and goes into infinite loop. No code in if or else is printed.
What about?
while [ $(tail -10 logFile | grep -c RUNNING) -eq 0 ]; do sleep 1; done

looping curl and grep to query an API and process result all in one action

Initially I was having trouble piping a curl and grep command because I was getting the same exit code if the server was down as I was for if the pattern was not found and that wasn't good. Here are some examples of solutions I was given for that:
#!/bin/bash
if curl http://192.168.1.2/api/query | grep -q mypattern; then
echo "Found pattern"
elif [ "${PIPESTATUS[0]}" -eq 0 ]; then
echo "Server up"
else
echo "Server down"
fi
Here is the other one:
if while ! curl http://192.168.1.2:8080/api/query; do sleep 1; done |
grep -q mypattern; then
echo "success"
fi
Now I am stuck again and trying to adapt them. Right now it will retrieve the contents of the queue. If it can't reach the server, it keeps trying until is does reach it. It will then process the queue to find the pattern. But I need to confirm the server is reachable AND process the queue all in one action. If EITHER the server is unreachable or the pattern is found, keep trying until the server responds AND the pattern is not found in the queue. After that, then I will do whatever. I am having trouble trying to come up with an efficient solution.
You can pipe the standard output of the entire while loop (which includes the output of the curl command) to another loop that runs until it finds your pattern in its input:
while ! curl http://...; do
# Write to standard error so that it isn't sent to grep
echo "Server down, waiting one second" >&2
sleep 1
done |
until grep -q mypattern; do
echo "Waiting for pattern to match"
done

Is there any way except using counter to enable time based alerts

Suppose that ps -ef | grep apache | wc -l gives output 2 which means 2 process are running.
In my server connection fluctuates, so I want to send an alert when the output of ps -ef| grep apache |wc -l is zero more than 5 Minutes.
I want to send an alert when the output of ps -ef| grep apache |wc -l is zero more than 5 Minutes.
First,ps -ef| grep apache can be unreliable because it may count grep apache as an apache process. To avoid that, use ps -ef | grep '[a]pache'. Better, try: pgrep apache. Also, if we are looking for zero or not zero processes, we don't need wc -l.
If your needs are simple, then here is a simple bash script that checks every minute to see if an apache process is running. If five successive tests show no such process, it sends an email to user#admin:
#!/bin/bash
count=0
while sleep 1m
do
if pgrep apache >/dev/null
then
count=0
else
((count++))
fi
if [ "$count" -ge 5 ]
then
echo "Houston, we have a problem: $count" | mail admin#host
count=0
fi
done
Since this only checks every minute, it could miss some process that starts and stops in less than a minute. You may need to adjust the timing. As Jonathan Leffler commented, doing this well is hard work. This script is only intended as a quick-and-simple solution.

Resources