Originally published January 7, 2018 @ 2:46 pm
A Java application on one of my servers has been causing problems by opening up too many network connections and not closing them quickly enough. I needed to be notified when the number of connections opened by a particular process exceeded a certain limit. I also needed a record of open connections over time. Below is a quick script I wrote for that.
There’re a couple of things I should point out. First, the options used with the netstat command:
netstat -tunap
The “p” is for “- -process”, which takes PID as argument. Also, I did not want to be notified more than once per day, so with every email alert the script touches a lock file and then compares the mtime on the file to the current time. If mtime is more than 24 x 60 x 60 seconds in the past (24 hours), the another email will be sent and timestamp on the lock file will be updated.
if [ $(echo $(( (`date +%s` - `stat -L --format %Y ${lockfile}`) < (24*60*60) ))) -eq 0 ]
This syntax will return 1 as long as the lock file is less than 86400 seconds old. The output will be 0 when the lock file is older than 24 hours, at which point another email alert may be sent. Also, note how the first letter of the “[p]rocess_string” is enclosed in square brackets. This is avoid matching “grep” in “ps -ef | grep” output. Finally, I use “grep -m1” to make sure I have only one PID. If you need to match multiple PIDs, you would need to use a “for” loop.
And here’s the script (also on GitHub):
#!/bin/bash lim=1000 email="email@domain.com" this_script=$(basename "$(test -L "$0" && readlink "$0" || echo "$0")") time_db=$(date +'%Y-%m-%d %H:%M:%S') lockfile="/tmp/${this_script}.lock" logfile="/var/tmp/${this_script}.log" this_host=$(echo ${HOSTNAME} | awk -F'.' '{print $1}') pid=$(ps -ef | grep -m1 "[p]rocess_string" | awk '{print $2}') c=$(netstat -tunap | grep -c ${pid}) echo -e "${time_db}\t${this_host}\t${pid}\t${c}" >> "${logfile}" notify() { echo "process_string PID ${pid} has opened ${c} TCP connections on ${HOSTNAME}" | \ mailx -s "process_string network alert from ${HOSTNAME}" "${email}" touch "${lockfile}" } if [ ${c} -gt ${lim} ] then if [ -f "${lockfile}" ] then if [ $(echo $(( (`date +%s` - `stat -L --format %Y ${lockfile}`) < (24*60*60) ))) -eq 0 ] then notify fi else notify fi fi
Experienced Unix/Linux System Administrator with 20-year background in Systems Analysis, Problem Resolution and Engineering Application Support in a large distributed Unix and Windows server environment. Strong problem determination skills. Good knowledge of networking, remote diagnostic techniques, firewalls and network security. Extensive experience with engineering application and database servers, high-availability systems, high-performance computing clusters, and process automation.