Advertisement
Guest User

Server Status Script - Bash

a guest
Jun 23rd, 2014
1,537
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 9.83 KB | None | 0 0
  1. #!/bin/bash
  2. #
  3. # Server status script for Linux.
  4. # This script is designed to be run as a cronjob by 'root'.
  5. # Created by sleddog.
  6. # Last revised: 03 Mar 2014.
  7. # Free for everyone.
  8. #
  9. # Capture start time for runtime calculation.
  10. START=`date +%s`
  11. #
  12. # SETTINGS --------------------------------------------------------------------
  13. #
  14. # MEMTYPE=1 for OpenVZ using 'guaranteed/burst' memory (user_beancounters).
  15. # MEMTYPE=2 for everything else (including OpenVZ with vswap).
  16. MEMTYPE=2
  17. #
  18. # Ethernet interface for traffic.
  19. IFACE="eth0"
  20. #
  21. # Path and filename for the HTML report.
  22. REPORT="/path/to/web/status.html"
  23. #
  24. # Page title for the HTML report.
  25. PGTITLE="Server Status"
  26. #
  27. # Format of the report date/time line. Read 'man date' for details...
  28. REPDATE=`date +'%l:%M %p - %a, %d %b %Y [GMT %:z]'`
  29. #
  30. # Run interval as set in the cronjob. This is used for display purposes
  31. # on the report page.
  32. INTERVAL=5
  33. #
  34. # A place to write temporary files generated by this script.
  35. DATADIR="/tmp"
  36. #
  37. # Disk devices for disk usage report.
  38. # DISKMNT  : the mount point shown in 'df' (column at right, not left!).
  39. # DISKNAME : the name to be displayed in the report; maximum 10 characters.
  40. DISKMNT[0]='/'
  41. DISKNAME[0]='/'
  42. # Add a second disk device:
  43. #DISKMNT[1]='/dev/shm'
  44. #DISKNAME[1]='/dev/shm'
  45. #
  46. # END SETTINGS ----------------------------------------------------------------
  47. #
  48. if [ "$MEMTYPE" -eq "1" ]; then
  49.     BEAN=`cat /proc/user_beancounters`
  50. else
  51.     MEMINFO=`cat /proc/meminfo`
  52. fi
  53. STAT=`cat /proc/stat`
  54. LOADAVG=`cat /proc/loadavg`
  55. UPTIME=`cat /proc/uptime`
  56. DISKUSE=`df -h`
  57. #
  58. function calc_wait {
  59.         IO=`echo $STAT | awk '{ print $6 }'`
  60.         TTL=`echo $STAT | awk '{ print($2 + $3 + $4 + $5 + $6) }'`
  61. }
  62. function format_wait {
  63.         IO=$2
  64.     IOPdisp=`echo $1 $2 | awk '{ printf("%.2f", $2 * 100 / $1) }'`
  65. }
  66. function sec2dhm {
  67.         DAYS=$((SEC/86400))
  68.         HOURS=$(((SEC/3600) - ($DAYS*24)))
  69.         MINS=$(((SEC - (($DAYS*86400) + ($HOURS*3600)))/60))
  70.         if [ "$DAYS" -eq "1" ]; then
  71.                 UP="1 day "
  72.         elif [ "$DAYS" -gt "1" ]; then
  73.                 UP="$DAYS days "
  74.         fi
  75.         if [ "$HOURS" -eq "1" ]; then
  76.                 UP="${UP}1 hour "
  77.         elif [ "$HOURS" -gt "1" ]; then
  78.                 UP="${UP}${HOURS} hours "
  79.         fi
  80.         if [ "$MINS" -eq "1" ]; then
  81.                 UP="${UP}1 minute"
  82.         elif [ "$MINS" -gt "1" ]; then
  83.                 UP="${UP}$MINS minutes"
  84.         fi
  85. }
  86. #
  87. # Uptime & load
  88. #
  89. SEC=`echo "$UPTIME" | awk '{ print $1 }' | awk 'BEGIN { FS="." } { print $1 }'`
  90. sec2dhm
  91. LOAD=`echo "$LOADAVG" | awk '{ print $1" "$2" "$3 }'`
  92. #
  93. # Memory
  94. #
  95. if [ "$MEMTYPE" -eq "1" ]; then
  96.     PRIVBAR=$((`echo "$BEAN" | grep privvm | awk '{ print $4 }'`/ 256))
  97.     PRIVCUR=`echo "$BEAN" | grep privvm | awk '{ printf("%.0f", $2 / 256) }'`
  98.     PRIVFAI=`echo "$BEAN" | grep privvm | awk '{ print $6 }'`
  99.     PRIVCURPER=`echo $PRIVBAR $PRIVCUR | awk '{ printf("%.0f", $2 * 100 / $1) }'`
  100.     APPBAR=$((`echo "$BEAN" | grep vmguar | awk '{ print $4 }'`/ 256))
  101.     APPCUR=`echo "$BEAN" | grep oomguar | awk '{ printf("%.0f", $2 / 256) }'`
  102.     APPFAI=`echo "$BEAN" | grep oomguar | awk '{ print $6 }'`
  103.     APPCURPER=`echo $APPBAR $APPCUR | awk '{ printf("%.0f", $2 * 100 / $1) }'`
  104.     if [ "$PRIVFAI" -gt "0" ]; then
  105.         PRIVFAI="[${PRIVFAI}]"
  106.     else
  107.         PRIVFAI=''
  108.     fi
  109.     if [ "$APPFAI" -gt "0" ]; then
  110.         APPFAI="[${APPFAI}]"
  111.     else
  112.         APPFAI=''
  113.     fi
  114.     SWAPPED=`echo "$BEAN" | awk '$1 ~ /^physpages$/ { phys=$2 } $1 ~ /^oomguarpages$/ { oomguar=$2 } END { printf "%.0f", (oomguar - phys) / 256 }'`
  115.     PLEN=%$((${#PRIVCUR}))s
  116.     PRIVCUR=`printf "$PLEN" $PRIVCUR`
  117.     APPCUR=`printf "$PLEN" $APPCUR`
  118.     SWAPPED=`printf "$PLEN" $SWAPPED`
  119.     MEMORY=`echo -e "Privvmpages  : $PRIVCUR / $PRIVBAR M (${PRIVCURPER}%) $PRIVFAI \nOomguarpages : $APPCUR / $APPBAR M (${APPCURPER}%) $APPFAI\nSwapped      : $SWAPPED M"`
  120. else
  121.     MEMITEMS=('MemTotal' 'MemFree' 'Buffers' 'Cached' 'SwapTotal' 'SwapFree')
  122.     for ITEM in ${MEMITEMS[@]}; do
  123.         VAL=`echo "$MEMINFO" | grep "^${ITEM}:" | awk '{ print $2 }'`
  124.         if [ -n "$VAL" ]; then
  125.             let $ITEM=$VAL
  126.         else
  127.             let $ITEM=0
  128.         fi
  129.     done
  130.     let APPS=$((MemTotal - $MemFree - $Buffers - $Cached))
  131.     APPS_PER=$((APPS * 100 / $MemTotal))
  132.     APPS=`printf '%4s' $((APPS / 1024))`
  133.     let BC=$((Buffers + $Cached))
  134.     BC_PER=$((BC * 100 / $MemTotal))
  135.     BC=`printf '%4s' $((BC / 1024))`
  136.     let FREE1=$((MemFree))
  137.     FREE1_PER=$((FREE1 * 100 / $MemTotal))
  138.     FREE1=`printf '%4s' $((FREE1 / 1024))`
  139.     let FREE2=$((MemFree + $Buffers + $Cached))
  140.     FREE2_PER=$((FREE2 * 100 / $MemTotal))
  141.     FREE2=`printf '%4s' $((FREE2 / 1024))`
  142.     if [ "$SwapTotal" -gt "0" ]; then
  143.         let SWAP=$((SwapTotal - $SwapFree))
  144.         SWAP_PER=$((SWAP * 100 / $SwapTotal))
  145.     else
  146.         SWAP=0
  147.         SWAP_PER=0
  148.     fi
  149.     SWAP=`printf '%4s' $((SWAP / 1024))`
  150.     MEMORY=`echo -e "Applications : $APPS MB (${APPS_PER}%)\nB/C          : $BC MB (${BC_PER}%)\nFree         : $FREE1 MB (${FREE1_PER}%)\nFree (-B/C)  : $FREE2 MB (${FREE2_PER}%)\nSwapped      : $SWAP MB (${SWAP_PER}%)"`
  151. fi
  152. #
  153. # Disk
  154. #
  155. i=0
  156. for DEV in ${DISKMNT[@]}; do
  157.     DISKARR=(`echo "$DISKUSE" | grep -m1 " ${DEV}$" | awk '{ print $2" "$3" "$4" "$5 }'`)
  158.     # if the df output is line-wrapped (because of a long filesystem name)
  159.     # then the items are off by one. Check for a % symbol at the end...
  160.     if [[ ! ${DISKARR[3]} == *% ]]; then
  161.         DISKARR=(`echo "$DISKUSE" | grep -m1 " ${DEV}$" | awk '{ print $1" "$2" "$3" "$4 }'`)
  162.     fi
  163.     for ITEM in ${DISKARR[@]}; do
  164.         DISK="${DISK}`printf "%-7s" $ITEM`"
  165.     done
  166.     DISKLBL=`printf "%-10s" ${DISKNAME[$i]}`
  167.     if [ -n "$DISKS" ]; then
  168.         DISKS="${DISKS}\n$DISKLBL ${DISK}"
  169.     else
  170.         DISKS="$DISKLBL $DISK"
  171.     fi
  172.     unset DISK
  173.     i=$((i+1))
  174. done
  175. DISKS=`echo -e "FS         Size   Used   Avail  Use%\n$DISKS"`
  176. #
  177. # IO Wait
  178. #
  179. if [ -f "${DATADIR}/cpu" ]; then
  180.         /bin/cp -af ${DATADIR}/cpu ${DATADIR}/cpu.prev
  181. fi
  182. echo $STAT > $DATADIR/cpu
  183. calc_wait
  184. format_wait $TTL $IO
  185. IOP_BOOT=`printf "%5s" $IOPdisp`"%"
  186. if [ -f "${DATADIR}/cpu.prev" ]; then
  187.     TTL_1=$TTL
  188.     IO_1=$IO
  189.     STAT=`cat ${DATADIR}/cpu.prev`
  190.     calc_wait
  191.     TTL_DUR=`awk -v e1="$TTL_1" -v e2="$TTL" 'BEGIN {print e1-e2}'`
  192.     IO_DUR=$(($IO_1-$IO))
  193.     if [ "$TTL_DUR" -gt "0" ]; then
  194.         format_wait $TTL_DUR $IO_DUR
  195.     else
  196.         IOPdisp="0.00"
  197.     fi
  198.     IOP_INT=`printf "%5s" $IOPdisp`"%"
  199. else
  200.     IOP_INT="-"
  201. fi
  202. IOLBL="Last $INTERVAL mins :"
  203. if [ "$INTERVAL" -lt "10" ]; then
  204.     IOLBL="Last $INTERVAL mins  :"
  205. fi
  206. IOWAIT=`echo -e "Since boot   : ${IOP_BOOT}\n$IOLBL ${IOP_INT} "`
  207. #
  208. # Transfer
  209. #
  210. if [ -e "$REPORT" ]; then
  211.         LASTRUN=`stat -c %Y $REPORT`
  212.         ELAPSED=$((START-$LASTRUN))
  213. fi
  214. DATARAW=(`cat /proc/net/dev | grep $IFACE | sed "s/${IFACE}://" | awk '{ print $1" "$9 }'`)
  215. RECVD=${DATARAW[0]}
  216. TRANS=${DATARAW[1]}
  217. RECVD_DIFF=0
  218. TRANS_DIFF=0
  219. if [ -e "${DATADIR}/txlast" ]; then
  220.     TRANS_LAST=`cat ${DATADIR}/txlast`
  221. fi
  222. if [ -e "${DATADIR}/rxlast" ]; then
  223.     RECVD_LAST=`cat ${DATADIR}/rxlast`
  224. fi
  225. if [[ -n "$TRANS_LAST" && -n "$ELAPSED" ]]; then
  226.     TRANS_DIFF=$(((TRANS-$TRANS_LAST) / 1024))
  227.     if [ "$TRANS_DIFF" -lt "0" ]; then
  228.         TRANS_DIFF=$(((4294967296+TRANS-$TRANS_LAST) / 1024))
  229.     fi
  230.     TX_UNITS=KB
  231.     if [ "$TRANS_DIFF" -gt "9999" ]; then
  232.         TX=$((TRANS_DIFF / 1024))
  233.         TX_UNITS=MB
  234.     else
  235.         TX=$TRANS_DIFF
  236.     fi
  237. fi
  238. if [[ -n "$RECVD_LAST" && -n "$ELAPSED" ]]; then
  239.     RECVD_DIFF=$(((RECVD-$RECVD_LAST) / 1024))
  240.     if [ "$RECVD_DIFF" -lt "0" ]; then
  241.         RECVD_DIFF=$(((4294967296+RECVD-$RCVD_LAST) / 1024))
  242.     fi
  243.     RX_UNITS=KB
  244.     if [ "$RECVD_DIFF" -gt "9999" ]; then
  245.         RX=$((RECVD_DIFF / 1024))
  246.         RX_UNITS=MB
  247.     else
  248.         RX=$RECVD_DIFF
  249.     fi
  250. fi
  251. PLEN=%$((${#TRANS_DIFF}))s
  252. if [ "$RECVD_DIFF" -gt "$TRANS_DIFF" ]; then
  253.     PLEN=%$((${#RECVD_DIFF}))s
  254. fi
  255. TX=`printf "$PLEN" $TX`
  256. RX=`printf "$PLEN" $RX`
  257. echo $RECVD > ${DATADIR}/rxlast
  258. echo $TRANS > ${DATADIR}/txlast
  259. #
  260. #
  261. FINISH=`date +%s`
  262. ELSEC=$((FINISH-$START))
  263. if [ "$ELSEC" -lt "1" ]; then
  264.         RUNTIME="Runtime: <1 sec."
  265. elif [ "$ELSEC" -eq "1" ]; then
  266.         RUNTIME="Runtime: 1 sec."
  267. else
  268.         RUNTIME="Runtime: $ELSEC secs."
  269. fi
  270. cat > $REPORT <<END
  271. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  272. <html>
  273. <head>
  274. <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
  275. <meta name="viewport" content="width=device-width; initial-scale=1.0;">
  276. <title>$PGTITLE</title>
  277. <style type='text/css'>
  278. body { margin: 0; padding: 0; text-align: center; font-family: sans-serif; background-color: #1E4561; color: #CCC }
  279. .box { width: 400px; margin: 50px auto 0 auto; padding: 18px 10px 15px 25px; text-align: left; box-shadow: 0px 16px 20px -16px #000; border-radius: 5px; background-color: #F6F6F6; color: #202020 }
  280. h1, h2 { margin: 0; padding: 0 }
  281. h1 { font-size: 19px }
  282. h2, .repdate { font-size: 14px }
  283. .repdate { margin: 5px 0 15px 0 }
  284. pre { font-family: monospace; font-size: 13px; margin: 5px 0 7px 35px; padding: 0; line-height: 17px }
  285. .footer { text-align: center; font-size: 11px; margin-top: 15px; line-height: 15px }
  286. @media only screen and (max-width: 480px) {
  287. body { background-color: #F6F6F6; color: #202020 }
  288. .box { width: auto; margin: 0; padding: 0; border: none; border-radius: 0; box-shadow: none; overflow: hidden; background-color: inherit; color: inherit }
  289. h1 { font-size: 17px; margin-top: 15px }
  290. .repdate { font-size: 13px }
  291. h1, .repdate, h2 { margin-left: 10px }
  292. pre { font-size: 12px; margin-left: 20px }
  293. .footer { text-align: left; border-top: 1px solid #999; margin: 10px; padding: 10px }
  294. }
  295. </style>
  296. </head>
  297. <body>
  298. <div class='box'>
  299. <h1>$PGTITLE</h1>
  300. <div class='repdate'>$REPDATE</div>
  301. <h2>Uptime</h2>
  302. <pre>$UP</pre>
  303. <h2>Load</h2>
  304. <pre>$LOAD</pre>
  305. <h2>Memory</h2>
  306. <pre>$MEMORY</pre>
  307. <h2>Disk</h2>
  308. <pre>$DISKS</pre>
  309. <h2>IO Wait</h2>
  310. <pre>$IOWAIT</pre>
  311. <h2>Transfer (last $INTERVAL mins)</h2>
  312. <pre>Transmit     :  $TX $TX_UNITS
  313. Receive      :  $RX $RX_UNITS</pre>
  314. </div>
  315. <div class='footer'>$RUNTIME<br>Regenerated every $INTERVAL minutes.</div>
  316. </body>
  317. </html>
  318. END
  319. exit 0
  320. # end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement