#!/bin/bash

# shsysinfo V1.1 - mail @ patrick - nagel . net  (2006-09-08)

## Configuration
## -------------

NETWORK_INTERFACE="eth0"		 # Network interface name

HDD_DEVICE="/dev/hda"			 # Harddisk device name                                # I'll improve this soon...
HDD_PARTITION1="1"			 # Harddisk partition 1's number (/dev/hda1 --> 1)
HDD_PARTITION1_LABEL="System partition"	 # Harddisk partition 1's label
HDD_PARTITION2="3"			 # Harddisk partition 2's number 
HDD_PARTITION2_LABEL="Storage partition" # Harddisk partition 2's label

# Put this into your /etc/crontab to provide S.M.A.R.T. information (currently only one drive supported):
#    # update smart statistics (for shsysinfo)
#    */10  * * * *	root	/usr/sbin/smartctl -a /dev/hda >/tmp/smartstats
SMART_STATISTICS="/tmp/smartstats"       # If this variable is empty, S.M.A.R.T. information won't be shown.



## Variables

declare -a FREE

## Functions

function gather_info() {
	# CPU usage (user + nice + system) and network load measuring (they take a lot of time, so I combined them...)
	LOADTX1="$(/sbin/ifconfig ${NETWORK_INTERFACE} | grep "TX bytes" | sed -e 's/.*TX bytes://' -e 's/[ ].*//')"
	LOADRX1="$(/sbin/ifconfig ${NETWORK_INTERFACE} | grep "RX bytes" | sed -e 's/.*RX bytes://' -e 's/[ ].*//')"
	USAGE="$(cat /proc/stat | awk '/cpu  /{print ($2+$3+$4)}')"          # Sum of user, nice, system
	TOTAL="$(cat /proc/stat | awk '/cpu  /{print ($2+$3+$4+$5+$6+$7)}')" # Sum of all counters
	sleep 1  # Sleep 1 second, then check our values again and calculate the difference
	USAGE2="$(cat /proc/stat | awk '/cpu  /{print ($2+$3+$4)}')"
	TOTAL2="$(cat /proc/stat | awk '/cpu  /{print ($2+$3+$4+$5+$6+$7)}')"
	USAGEPERCENT="$(echo -n "$USAGE $TOTAL $USAGE2 $TOTAL2" | awk '{printf ("%i", int(100*($3-$1))/($4-$2))}')"
	if (($USAGEPERCENT >= 100)); then USAGEPERCENT=100; fi   # it just looks weird when the CPU load is shown as above 100%...
	LOADTX2="$(/sbin/ifconfig ${NETWORK_INTERFACE} | grep "TX bytes" | sed -e 's/.*TX bytes://' -e 's/[ ].*//')"
	LOADRX2="$(/sbin/ifconfig ${NETWORK_INTERFACE} | grep "RX bytes" | sed -e 's/.*RX bytes://' -e 's/[ ].*//')"
	LOADTX="$(( (${LOADTX2} - ${LOADTX1}) / 1000 ))"  # Divide by 1000 (so we have KB/s)
	LOADRX="$(( (${LOADRX2} - ${LOADRX1}) / 1000 ))"  # Divide by 1000 (so we have KB/s)	

	# Uptime
	UPTIME="$(uptime | sed -e 's/.*up //' -e 's/,[ ]*[0-9*] user.*//')"

	# Memory
	FREE=( $(free -m | tail -n 2 | awk '{printf("%i ",$3)}') )
	TOTAL_MEM="$(free -m | grep "Mem:" | awk '{printf("%i", $2)}')"
	TOTAL_SWAP="$(free -m | grep "Swap:" | awk '{printf("%i", $2)}')"
	MEM="${FREE[0]}"
	SWAP="${FREE[1]}"
	MEM_PERCENT="$(echo -n "${MEM} ${TOTAL_MEM}" | awk '{printf("%i", ($1/$2)*100);}')"
	SWAP_PERCENT="$(echo -n "${SWAP} ${TOTAL_SWAP}" | awk '{printf("%i", ($1/$2)*100);}')"

	# Processes
 	TOP5CPU="$(ps chax -o cmd,user --sort=-%cpu | head -n 5 | sed -e 's/[a-zA-Z]*$/(User: &)/' -e 's/^/<li>/' -e 's/$/<\/li>/')"
	TOP5MEM="$(ps chax -o cmd,user --sort=-rss | head -n 5 | sed -e 's/[a-zA-Z]*$/(User: &)/' -e 's/^/<li>/' -e 's/$/<\/li>/')"
	PROCESSES="$(ps --no-heading -e | head -n -4 | wc -l)"          # -4 to remove measuring processes

	# HDD
	PARTITION1="$(df -m | grep "${HDD_DEVICE}${HDD_PARTITION1}" | awk '{printf("%i MB (%s)\n", $3, $5);}')"
	PARTITION2="$(df -m | grep "${HDD_DEVICE}${HDD_PARTITION2}" | awk '{printf("%i MB (%s)\n", $3, $5);}')"
	SMART_POWER_ON_HOURS="$(grep "Power_On_Hours" ${SMART_STATISTICS} | awk '{printf("%i (%.2f years)\n", $10, $10/(24*365) )}')"
	SMART_TEMPERATURE="$(grep "Temperature_Celsius" ${SMART_STATISTICS} | awk '{printf("%i °C\n", $10 )}')"
	SMART_LAST_TEST_HOUR="$(grep "# 1" ${SMART_STATISTICS} | cut -b 63-68)"
	SMART_LAST_TEST_AGO="$(echo "${SMART_LAST_TEST_HOUR} $(grep "Power_On_Hours" ${SMART_STATISTICS} | awk '{printf("%i", $10 )}')" | awk '{printf("%ih\n", $2-$1) }')"
	SMART_LAST_TEST_RESULT="$(grep "# 1" ${SMART_STATISTICS} | cut -b 26-55 | sed -r 's/.*/\L&/')"
	SMART_LAST_TEST_TYPE="$(grep "# 1" ${SMART_STATISTICS} | cut -b 6-25 | sed -r 's/.*/\L&/;s/^./\U&/')"

	# Connections
	CONNECTIONS="$(netstat -nt | tail -n +3 | wc -l)"
}

## Output

# Header
echo -e "Content-type: text/html\n"
echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\">
<head>
  <meta content=\"text/html;charset=UTF-8\" http-equiv=\"Content-Type\" />
  <title>System information - ${HOSTNAME}</title>
  <meta content=\"shsysinfo by Patrick Nagel\" name=\"author\" />
  <meta content=\"Automatically generated system information\" name=\"description\" />
  <style type=\"text/css\" media=\"all\">@import \"../dark.css\";</style>
</head>"

echo -n "<body>
  <h1>System information - ${HOSTNAME}</h1>"

# Now that the header is being shown in the client's browser, we take our time to gather some information
gather_info

# Finally, print the results
echo "  <div class=\"left\">
  <h2>System clock</h2>
  <p>$(date "+%F %T (UTC %:::z)")</p>

  <h2>Uptime</h2>
  <p>${UPTIME}</p>

  <h2>CPU usage</h2>
  <p>${USAGEPERCENT}% (user + nice + system)</p>

  <h2>Memory usage</h2>
  <p>Memory: ${MEM} MB (${MEM_PERCENT}%)<br />Swap: ${SWAP} MB (${SWAP_PERCENT}%)</p>

  <h2>Harddisk</h2>
  <h3>Usage</h3>
  <p>${HDD_PARTITION1_LABEL}: ${PARTITION1}<br />${HDD_PARTITION2_LABEL}: ${PARTITION2}</p>
  <h3>S.M.A.R.T. information</h3>
  <p>Power on hours: ${SMART_POWER_ON_HOURS}<br />Temperature: ${SMART_TEMPERATURE}<br />
     ${SMART_LAST_TEST_TYPE} test (${SMART_LAST_TEST_AGO} ago): ${SMART_LAST_TEST_RESULT}</p>

  </div>

  <div class =\"right\">

  <h2>Network load</h2>
  <p>${CONNECTIONS} connections<br />TX: ${LOADTX} KB/s<br />RX: ${LOADRX} KB/s</p>

  <h2>Process information</h2>
  <h3>Number of processes</h3>
  <p>${PROCESSES}</p>
  <h3>Current top 5 CPU consuming processes</h3>
  <ol>${TOP5CPU}</ol>
  <h3>Current top 5 memory consuming processes</h3>
  <ol>${TOP5MEM}</ol>

  </div>"

# Footer
echo "
</body>
</html>
"
