Advertisement
Guest User

rock64_diagnostics.sh

a guest
May 26th, 2018
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.37 KB | None | 0 0
  1. #!/bin/bash
  2. # This script is designed to be a general purpose diagnostic log and testing
  3. # script for the pine64 and related SBC boards. It heavily borrows from code
  4. # used in the Armbian project's armbianmonitor.
  5. #
  6. # Written 2017 Peter Feerick and contributors, released under GPLv3
  7. #
  8.  
  9. #if user doesn't have permission for /var/log, write to /tmp
  10. if [ -w /var/log ]; then
  11. Log="/var/log/${0##*/}.log"
  12. else
  13. Log="/tmp/${0##*/}.log"
  14. fi
  15.  
  16. VerifyRepairExcludes="/etc/|/boot/|cache|getty|/var/lib/smartmontools/"
  17.  
  18. Main() {
  19. # check if stdout is a terminal...
  20. if test -t 1; then
  21. # see if it supports colors...
  22. ncolors=$(tput colors)
  23. if test -n "$ncolors" && test $ncolors -ge 8; then
  24. BOLD="$(tput bold)"
  25. NC='\033[0m' # No Color
  26. LGREEN='\033[1;32m'
  27. LRED='\e[0;91m'
  28. fi
  29. fi
  30.  
  31. [ $# -eq 0 ] && (DisplayUsage ; exit 0)
  32.  
  33. ParseOptions "$@"
  34.  
  35. exit 0
  36. } # Main
  37.  
  38. #thanks to tkaiser for the initial command for this function
  39. VerifyFiles() {
  40. echo -e "\n### file verification:\n"
  41.  
  42. OUTPUT=$(dpkg --verify | egrep -v -i "${VerifyRepairExcludes}" | awk -F" /" '{print "/"$2}')
  43.  
  44. if [[ -z $OUTPUT ]]; then
  45. echo -e "${LGREEN}${BOLD}It would appear you don't have any corrupt files or packages!${NC}"
  46. echo -e "If you still have concerns, use this scripts media test mode"
  47. echo -e "to do a stress test of your drive/storage device.\n"
  48. else
  49. echo -e "${LRED}${BOLD}It appears you *may* have corrupt packages.${NC} If you believe this to be the"
  50. echo -e "case (and not a customisation that you or a script has applied), re-run this"
  51. echo -e "script in fix mode to try and fix these packages.\n"
  52.  
  53. echo -e "### The following changed from packaged state files were detected:\n"
  54. echo -e "${OUTPUT}\n"
  55. fi
  56.  
  57. } # VerifyFiles
  58.  
  59. #thanks to tkaiser for the initial command for this function
  60. VerifyAndFixFiles() {
  61. echo -e "\n### file verification and file/package repair:\n"
  62.  
  63. STAGE1=$(dpkg --verify | egrep -v -i "${VerifyRepairExcludes}" | awk -F" /" '{print "/"$2}')
  64.  
  65. if [[ -z $STAGE1 ]]; then
  66. echo -e "${LGREEN}${BOLD}It would appear you don't have any corrupt files or packages!${NC}"
  67. echo -e "\nIf you are experiencing issues, it is probably best to back"
  68. echo -e "up your data, and reinstall the OS from a new image.\n"
  69. else
  70. echo -e "### The following changed from packaged state files were detected:\n"
  71. echo -e "${STAGE1}"
  72.  
  73. echo -e "\n### Identifying which packages the changed files belong to... "
  74. STAGE2=$(echo "${STAGE1}" | while read ; do dpkg -S "${REPLY}" | cut -f1 -d: ; done | sort | uniq)
  75.  
  76. if [[ -z ${STAGE2} ]]; then
  77. echo -e "\n\n${LRED}${BOLD}An internal error has occured... Exiting!${NC}"
  78. exit 1
  79. else
  80. echo -e "\nThe following packages will be reinstalled:"
  81. echo -e "${STAGE2}"
  82.  
  83. # test internet connection by poking google
  84. nc -zw1 google.com 443 >/dev/null 2>&1
  85.  
  86. if [[ $? -eq 0 ]]; then
  87. echo -e "\n### Updating software repositories before package reinstall..."
  88. apt-get update -qq >/dev/null 2>&1
  89.  
  90. echo "${STAGE2}" | while read;
  91. do
  92. echo -e "Reinstalling package: ${REPLY}"
  93. apt-get -q --reinstall -y install ${REPLY} >/dev/null 2>&1
  94. done
  95.  
  96. echo -e "\n${LGREEN}${BOLD}Process complete.${NC} Reboot your device now and see if the issues that"
  97. echo -e "were identified have been successfully resolved."
  98. else
  99. echo -e "\n${LRED}${BOLD}It appears you don't have an active internet connection!!${NC}\n"
  100. echo -e "Repair cannot proceed without an internet connection as new/fresh versions of the"
  101. echo -e "package files are downloaded as part of the repair process. Please resolve the"
  102. echo -e "network/network issue and then try again. Exiting!\n"
  103.  
  104. exit 1
  105. fi
  106. fi
  107. fi
  108. } # VerifyAndFixFiles
  109.  
  110. # Most of the below has been shameless copied from the Armbian project's armbianmonitor,
  111. # because they did an amazing job at making a create diagnostic report! Specifically:
  112.  
  113. # https://github.com/armbian/build/blob/master/packages/bsp/armbianmonitor/armbianmonitor-daemon
  114. # https://github.com/armbian/build/blob/master/packages/bsp/armbianmonitor/armbianmonitor
  115. # https://github.com/armbian/build/blob/master/packages/bsp/armhwinfo
  116. GenerateLog() {
  117. echo -e "\n### dmesg:\n"
  118. dmesg
  119.  
  120. echo -e "\n### meminfo:\n"
  121. cat /proc/meminfo
  122.  
  123. echo -e "\n### ifconfig:\n"
  124. ifconfig
  125.  
  126. echo -e "### lsusb:\n"
  127. lsusb 2>/dev/null ; echo "" ; lsusb -t 2>/dev/null
  128.  
  129. lspci >/dev/null 2>&1 && (echo -e "\n### lspci:" ; lspci 2>/dev/null)
  130.  
  131. echo -e "\n### partitions:\n"
  132. cat /proc/partitions
  133.  
  134. echo -e "\n### df:\n"
  135. df -h
  136.  
  137. echo -e "\n### Installed packages:\n\n$(dpkg -l | egrep "linux-|openmediavault")"
  138.  
  139. echo -e "\n### Loaded modules:\n\n$(lsmod)"
  140.  
  141. if [[ $(dpkg-query -W -f='${Status}' linux-pine64-package 2>/dev/null | grep -c "ok installed") == "1" ]]; then
  142. echo -e "\n### linux-pine64-package version:\n"
  143. apt-cache policy linux-pine64-package
  144. fi
  145.  
  146. if [[ $(dpkg-query -W -f='${Status}' linux-rock64-package 2>/dev/null | grep -c "ok installed") == "1" ]]; then
  147. echo -e "\n### linux-rock64-package version:\n"
  148. apt-cache policy linux-rock64-package
  149. fi
  150.  
  151. echo -e "\n### Kernel version:\n"
  152. uname -a
  153.  
  154. get_flash_information
  155. which iostat >/dev/null 2>&1 && \
  156. echo -e "\n### Current sysinfo:\n"
  157. which iostat >/dev/null 2>&1 && echo -e "$(iostat -p ALL | grep -v '^loop')\n\n"
  158. echo -e "$(vmstat -w)\n\n$(free -h)"
  159. } # GenerateLog
  160.  
  161. CheckCard() {
  162. if [ "$(id -u)" = "0" ]; then
  163. echo "Checking disks is not permitted as root or through sudo. Exiting" >&2
  164. exit 1
  165. fi
  166.  
  167. if [ ! -d "$1" ]; then
  168. echo "\"$1\" does not exist or is no directory. Exiting" >&2
  169. exit 1
  170. fi
  171. TargetDir="$1"
  172.  
  173. # check requirements
  174. which f3write >/dev/null 2>&1 || MissingTools=" f3"
  175. which iozone >/dev/null 2>&1 || MissingTools="${MissingTools} iozone3"
  176. if [ "X${MissingTools}" != "X" ]; then
  177. echo "Some tools are missing, please do a \"sudo apt-get -f -y install${MissingTools}\" to install them, and try again" >&2
  178. exit 1
  179. fi
  180.  
  181. # check provided path
  182. Device="$(GetDevice "$1")"
  183. set ${Device}
  184. DeviceName=$1
  185. FileSystem=$2
  186. echo "${DeviceName}" | grep -q "mmcblk0" || echo -e "\n${BOLD}NOTE:${NC} It seems you're actually testing ${DeviceName} (${FileSystem})\n"
  187.  
  188. TestDir="$(mktemp -d "${TargetDir}/cardtest.XXXXXX" || exit 1)"
  189. date "+%s" >"${TestDir}/.starttime" || exit 1
  190. trap "rm -rf \"${TestDir}\" ; exit 0" 0 1 2 3 15
  191. LogFile="$(mktemp /tmp/armbianmonitor_checks_${DeviceName##*/}_${FileSystem}.XXXXXX)"
  192.  
  193. # start actual test, create a small file for some space reserve
  194. fallocate -l 32M "${TestDir}/empty.32m" 2>/dev/null || dd if=/dev/zero of="${TestDir}/empty.32m" bs=1M count=32 status=noxfer >/dev/null 2>&1
  195. ShowWarning=false
  196.  
  197. # Start writing
  198. echo -e "Starting to fill ${DeviceName} with test patterns, please be patient this might take a very long time"
  199. f3write "${TestDir}" | tee "${LogFile}"
  200. touch "${TestDir}/.starttime" || ShowDeviceWarning
  201. rm "${TestDir}/empty.32m"
  202.  
  203. # Start verify
  204. echo -e "\nNow verifying the written data:"
  205. echo "" >>"${LogFile}"
  206. f3read "${TestDir}" | tee -a "${LogFile}"
  207. touch "${TestDir}/.starttime" || ShowDeviceWarning
  208. rm "${TestDir}/"*.h2w
  209. echo -e "\nStarting iozone tests. Be patient, this can take a very long time to complete:"
  210. echo "" >>"${LogFile}"
  211. cd "${TestDir}"
  212. iozone -e -I -a -s 100M -r 4k -r 512k -r 16M -i 0 -i 1 -i 2 | tee -a "${LogFile}"
  213. touch "${TestDir}/.starttime" || ShowDeviceWarning
  214. echo -e "\n${BOLD}The results from testing ${DeviceName} (${FileSystem}):${NC}"
  215. egrep "Average|Data" "${LogFile}" | sort -r
  216. echo " random random"
  217. echo -e "reclen write rewrite read reread read write\c"
  218. awk -F"102400 " '/102400/ {print $2}' <"${LogFile}"
  219.  
  220. # check health
  221. echo -e "\n${BOLD}Health summary: \c"
  222. egrep -q "Read-only|Input/output error" "${LogFile}" && (echo -e "${LRED}${BOLD}${DeviceName} failed${NC}" ; exit 0)
  223. grep -q "Data LOST: 0.00 Byte" "${LogFile}" && echo -e "${LGREEN}OK" || \
  224. (echo -e "${LRED}${BOLD}${DeviceName} failed. Replace it as soon as possible!" ; \
  225. grep -A3 "^Data LOST" "${LogFile}")
  226.  
  227. # check performance
  228. RandomSpeed=$(awk -F" " '/102400 4/ {print $7"\t"$8}' <"${LogFile}")
  229. if [ "X${RandomSpeed}" != "X" ]; then
  230. # Only continue when we're able to read out iozone results
  231. set ${RandomSpeed}
  232. RandomReadSpead=$1
  233. RandomWriteSpead=$2
  234. ReadSpeed=$(awk -F" " '/Average reading speed/ {print $4"\t"$5}' <"${LogFile}")
  235. set ${ReadSpeed}
  236. if [ "X$2" = "XMB/s" ]; then
  237. RawReadSpead=$(echo "$1 * 1000" | bc -s | cut -f1 -d.)
  238. else
  239. RawReadSpead$(echo "$1" | cut -f1 -d.)
  240. fi
  241. echo -e "\n${NC}${BOLD}Performance summary:${NC}\nSequential reading speed:$(printf "%6s" $1) $2 \c"
  242. [ ${RawReadSpead} -le 2500 ] && Exclamation="${LRED}${BOLD}way " || Exclamation=""
  243. [ ${RawReadSpead} -le 5000 ] && Exclamation="${Exclamation}${BOLD}too "
  244. [ ${RawReadSpead} -le 7500 ] && echo -e "(${Exclamation}low${NC})\c"
  245. echo "${Exclamation}" | grep -q "too" && ShowWarning=true
  246. echo -e "\n 4K random reading speed:$(printf "%6s" ${RandomReadSpead}) KB/s \c"
  247. [ ${RandomReadSpead} -le 700 ] && Exclamation="${LRED}${BOLD}way " || Exclamation=""
  248. [ ${RandomReadSpead} -le 1400 ] && Exclamation="${Exclamation}${BOLD}too "
  249. [ ${RandomReadSpead} -le 2500 ] && echo -e "(${Exclamation}low${NC})\c"
  250. echo "${Exclamation}" | grep -q "too" && ShowWarning=true
  251. WriteSpeed=$(awk -F" " '/Average writing speed/ {print $4"\t"$5}' <"${LogFile}")
  252. set ${WriteSpeed}
  253. if [ "X$2" = "XMB/s" ]; then
  254. RawWriteSpeed=$(echo "$1 * 1000" | bc -s | cut -f1 -d.)
  255. else
  256. RawWriteSpeed=$(echo "$1" | cut -f1 -d.)
  257. fi
  258. echo -e "\nSequential writing speed:$(printf "%6s" $1) $2 \c"
  259. [ ${RawWriteSpeed} -le 2500 ] && Exclamation="${LRED}${BOLD}way " || Exclamation=""
  260. [ ${RawWriteSpeed} -le 4000 ] && Exclamation="${Exclamation}${BOLD}too "
  261. [ ${RawWriteSpeed} -le 6000 ] && echo -e "(${Exclamation}low${NC})\c"
  262. echo "${Exclamation}" | grep -q "too" && ShowWarning=true
  263. echo -e "\n 4K random writing speed:$(printf "%6s" ${RandomWriteSpead}) KB/s \c"
  264. [ ${RandomWriteSpead} -le 400 ] && Exclamation="${LRED}${BOLD}way " || Exclamation=""
  265. [ ${RandomWriteSpead} -le 750 ] && Exclamation="${Exclamation}${BOLD}too "
  266. [ ${RandomWriteSpead} -lt 1000 ] && echo -e "(${Exclamation}low${NC})\c"
  267. echo "${Exclamation}" | grep -q "too" && ShowWarning=true
  268. if [ "X${ShowWarning}" = "Xtrue" ]; then
  269. echo -e "\n\n${BOLD}The device you tested seems to perform too slow to be used with pine64."
  270. echo -e "This applies especially to desktop images where slow storage is responsible"
  271. echo -e "for sluggish behaviour. If you want to have fun with your device do NOT use"
  272. echo -e "this media to put the OS image or the user homedirs on.${NC}\c"
  273. fi
  274. echo -e "\n\nTo interpret the results above correctly or search for better storage
  275. alternatives please refer to http://oss.digirati.com.br/f3/ and also
  276. http://www.jeffgeerling.com/blogs/jeff-geerling/raspberry-pi-microsd-card
  277. and http://thewirecutter.com/reviews/best-microsd-card/"
  278. fi
  279. } # CheckCard
  280.  
  281. GetDevice() {
  282. TestPath=$(findmnt "$1" | awk -F" " '/\/dev\// {print $2"\t"$3}')
  283. if [[ -z ${TestPath} && -n "${1%/*}" ]]; then
  284. GetDevice "${1%/*}"
  285. elif [[ -z ${TestPath} && -z "${1%/*}" ]]; then
  286. findmnt / | awk -F" " '/\/dev\// {print $2"\t"$3}'
  287. else
  288. echo "${TestPath}"
  289. fi
  290. } # GetDevice
  291.  
  292. get_flash_information() {
  293. # http://www.bunniestudios.com/blog/?page_id=1022
  294. find /sys -name oemid | while read Device ; do
  295. DeviceNode="${Device%/*}"
  296. DeviceName="${DeviceNode##*/}"
  297. echo -e "\n### ${DeviceName} info:\n"
  298. find "${DeviceNode}" -maxdepth 1 -type f | while read ; do
  299. NodeName="${REPLY##*/}"
  300. echo -e "$(printf "%20s" ${NodeName}): $(cat "${DeviceNode}/${NodeName}" | tr '\n' " ")"
  301. done
  302. done
  303. } # get_flash_information
  304.  
  305. UploadSupportLogs() {
  306. #prevent colour escape sequences in log
  307. BOLD=''
  308. NC=''
  309. LGREEN=''
  310. LRED=''
  311.  
  312. #check requirements
  313. which fping >/dev/null 2>&1 || MissingTools=" fping"
  314. which curl >/dev/null 2>&1 || MissingTools="${MissingTools} curl"
  315. which iostat >/dev/null 2>&1 || MissingTools="${MissingTools} sysstat"
  316.  
  317. if [ "X${MissingTools}" != "X" ]; then
  318. echo -e "Some tools are missing, installing: ${MissingTools}" >&2
  319. apt-get -f -qq -y install ${MissingTools} >/dev/null 2>&1
  320. fi
  321.  
  322. echo -e "Generating diagnostic logs... "
  323. GenerateLog > ${Log}
  324. [[ -n ${VERIFY} ]] && (echo -e "Running file integrity checks... " ; VerifyFiles >> ${Log})
  325.  
  326. #check network connection
  327. fping ix.io | grep -q alive || \
  328. (echo "Network/firewall problem detected. Please fix this or upload ${Log} manually." >&2 ; exit 1)
  329.  
  330. echo -ne "\nIP obfuscated log uploaded to \c"
  331. # obfuscate IPv4 addresses somehow but not too much
  332. cat ${Log} | \
  333. sed -E 's/([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3})/XXX.XXX.\3\4/g' \
  334. | curl -F 'f:1=<-' http://ix.io
  335.  
  336. echo -e "Please post the above URL on the forum where you've been asked for it."
  337. } # UploadSupportLogs
  338.  
  339. RequireRoot() {
  340. if [ "$(id -u)" != "0" ]; then
  341. echo "This function requires root privleges - run as root or through sudo. Exiting" >&2
  342. exit 1
  343. fi
  344. } # RequireRoot
  345.  
  346. DisplayUsage() {
  347. echo -e "\nUsage: ${BOLD}${0##*/} [-h] [-c \$path] [-f] [-l] [-L] [-m] [-u] [-v]${NC}\n"
  348. echo -e "############################################################################"
  349. echo -e "\n Use ${BOLD}${0##*/}${NC} for the following tasks:\n"
  350. echo -e " ${0##*/} ${BOLD}-c /path/to/test${NC} performs disk health/performance tests"
  351. echo -e " ${0##*/} ${BOLD}-f${NC} tries to fix detected corrupt packages"
  352. echo -e " ${0##*/} ${BOLD}-l${NC} outputs diagnostic logs to the screen via less"
  353. echo -e " ${0##*/} ${BOLD}-L${NC} outputs diagnostic logs to the screen as is"
  354. echo -e " ${0##*/} ${BOLD}-m${NC} provides simple CLI monitoring"
  355. echo -e " ${0##*/} ${BOLD}-n${NC} provides simple CLI network monitoring"
  356. echo -e " ${0##*/} ${BOLD}-u${NC} tries to upload diagnostic logs for support purposes"
  357. echo -e " ${0##*/} ${BOLD}-v${NC} tries to diagnose corrupt packages and files"
  358. echo -e "\n############################################################################\n"
  359. } # DisplayUsage
  360.  
  361. ParseOptions() {
  362. while getopts 'hHlLvVfFmMnNuUc:C:' c ; do
  363. case ${c} in
  364. h|H)
  365. # display usage info
  366. DisplayUsage
  367. exit 0
  368. ;;
  369.  
  370. l)
  371. # generate logs and pipe to screen via less
  372. GenerateLog | less
  373. exit 0
  374. ;;
  375.  
  376. L)
  377. # generate logs and output to display
  378. GenerateLog
  379. exit 0
  380. ;;
  381.  
  382. v|V)
  383. # file verification mode
  384. RequireRoot
  385. VerifyFiles
  386. exit 0
  387. ;;
  388.  
  389. f|F)
  390. # file verification and repair mode
  391. RequireRoot
  392. VerifyAndFixFiles
  393. exit 0
  394. ;;
  395.  
  396. m|M)
  397. # monitoring mode
  398. echo -e "Stop monitoring using [ctrl]-[c]"
  399. MonitorMode
  400. exit 0
  401. ;;
  402.  
  403. n|N)
  404. # monitoring mode
  405. echo -e "Stop monitoring using [ctrl]-[c]"
  406. NetworkMonitorMode
  407. exit 0
  408. ;;
  409.  
  410. u)
  411. # upload generated logs for support
  412. RequireRoot
  413. UploadSupportLogs
  414. exit 0
  415. ;;
  416.  
  417. U)
  418. # verify files and upload generated logs for support
  419. RequireRoot
  420. export VERIFY=TRUE
  421. UploadSupportLogs
  422. exit 0
  423. ;;
  424.  
  425. c|C)
  426. # check card mode
  427. CheckCard "${OPTARG}"
  428. exit 0
  429. ;;
  430.  
  431. esac
  432. done
  433. } # ParseOptions
  434.  
  435. MonitorMode() {
  436. # This functions prints out endlessly:
  437. # - time/date
  438. # - average 1m load
  439. # - detailed CPU statistics
  440. # - Soc temperature if available
  441.  
  442. # Allow script to return back to another calling utility when stopped by [ctrl]-[c]
  443. trap "echo ; exit 0" 0 1 2 3 15
  444.  
  445. # Try to renice to 19 to not interfere with OS behaviour
  446. renice 19 $BASHPID >/dev/null 2>&1
  447.  
  448. LastUserStat=0
  449. LastNiceStat=0
  450. LastSystemStat=0
  451. LastIdleStat=0
  452. LastIOWaitStat=0
  453. LastIrqStat=0
  454. LastSoftIrqStat=0
  455. LastCpuStatCheck=0
  456. LastTotal=0
  457.  
  458. SleepInterval=5
  459.  
  460. if [ -f /sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq ]; then
  461. DisplayHeader="Time big.LITTLE load %cpu %sys %usr %nice %io %irq"
  462. CPUs=biglittle
  463. elif [ -f /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq ]; then
  464. DisplayHeader="Time CPU load %cpu %sys %usr %nice %io %irq"
  465. CPUs=normal
  466. else
  467. DisplayHeader="Time CPU n/a load %cpu %sys %usr %nice %io %irq"
  468. CPUs=notavailable
  469. fi
  470.  
  471. [ -f /sys/devices/virtual/thermal/thermal_zone0/temp ] && DisplayHeader="${DisplayHeader} CPU" || SocTemp='n/a'
  472. [ -f /sys/devices/virtual/thermal/cooling_device0/cur_state ] \
  473. && DisplayHeader="${DisplayHeader} C.St." || CoolingState='n/a'
  474. echo -e "Stop monitoring using [ctrl]-[c]"
  475. echo -e "${DisplayHeader}"
  476. Counter=0
  477. while true ; do
  478. if [ "$c" == "m" ]; then
  479. let Counter++
  480. if [ ${Counter} -eq 15 ]; then
  481. echo -e "\n${DisplayHeader}\c"
  482. Counter=0
  483. fi
  484. elif [ "$c" == "s" ]; then
  485. # internal mode for debug log upload
  486. let Counter++
  487. if [ ${Counter} -eq 6 ]; then
  488. exit 0
  489. fi
  490. else
  491. printf "\x1b[1A"
  492. fi
  493. LoadAvg=$(cut -f1 -d" " </proc/loadavg)
  494. case ${CPUs} in
  495. biglittle)
  496. BigFreq=$(awk '{printf ("%0.0f",$1/1000); }' </sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq) 2>/dev/null
  497. LittleFreq=$(awk '{printf ("%0.0f",$1/1000); }' </sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq) 2>/dev/null
  498. ProcessStats
  499. echo -e "\n$(date "+%H:%M:%S"): $(printf "%4s" ${BigFreq})/$(printf "%4s" ${LittleFreq})MHz $(printf "%5s" ${LoadAvg}) ${procStats}\c"
  500. ;;
  501. normal)
  502. CpuFreq=$(awk '{printf ("%0.0f",$1/1000); }' </sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq) 2>/dev/null
  503. ProcessStats
  504. echo -e "\n$(date "+%H:%M:%S"): $(printf "%4s" ${CpuFreq})MHz $(printf "%5s" ${LoadAvg}) ${procStats}\c"
  505. ;;
  506. notavailable)
  507. ProcessStats
  508. echo -e "\n$(date "+%H:%M:%S"): --- $(printf "%5s" ${LoadAvg}) ${procStats}\c"
  509. ;;
  510. esac
  511. if [ "X${SocTemp}" != "Xn/a" ]; then
  512. SocTemp=$(awk '{printf ("%0.1f",$1/1000); }' </sys/devices/virtual/thermal/thermal_zone0/temp)
  513. echo -e " $(printf "%4s" ${SocTemp})°C\c"
  514. fi
  515. [ "X${CoolingState}" != "Xn/a" ] && printf " %d/%d" $(cat /sys/devices/virtual/thermal/cooling_device0/cur_state) $(cat /sys/devices/virtual/thermal/cooling_device0/max_state)
  516. [ "$c" == "s" ] && sleep 0.3 || sleep ${SleepInterval}
  517. done
  518. } # MonitorMode
  519.  
  520. ProcessStats() {
  521. procStatLine=(`sed -n 's/^cpu\s//p' /proc/stat`)
  522. UserStat=${procStatLine[0]}
  523. NiceStat=${procStatLine[1]}
  524. SystemStat=${procStatLine[2]}
  525. IdleStat=${procStatLine[3]}
  526. IOWaitStat=${procStatLine[4]}
  527. IrqStat=${procStatLine[5]}
  528. SoftIrqStat=${procStatLine[6]}
  529.  
  530. Total=0
  531. for eachstat in ${procStatLine[@]}; do
  532. Total=$(( ${Total} + ${eachstat} ))
  533. done
  534.  
  535. UserDiff=$(( ${UserStat} - ${LastUserStat} ))
  536. NiceDiff=$(( ${NiceStat} - ${LastNiceStat} ))
  537. SystemDiff=$(( ${SystemStat} - ${LastSystemStat} ))
  538. IOWaitDiff=$(( ${IOWaitStat} - ${LastIOWaitStat} ))
  539. IrqDiff=$(( ${IrqStat} - ${LastIrqStat} ))
  540. SoftIrqDiff=$(( ${SoftIrqStat} - ${LastSoftIrqStat} ))
  541.  
  542. diffIdle=$(( ${IdleStat} - ${LastIdleStat} ))
  543. diffTotal=$(( ${Total} - ${LastTotal} ))
  544. diffX=$(( ${diffTotal} - ${diffIdle} ))
  545. CPULoad=$(( ${diffX}* 100 / ${diffTotal} ))
  546. UserLoad=$(( ${UserDiff}* 100 / ${diffTotal} ))
  547. SystemLoad=$(( ${SystemDiff}* 100 / ${diffTotal} ))
  548. NiceLoad=$(( ${NiceDiff}* 100 / ${diffTotal} ))
  549. IOWaitLoad=$(( ${IOWaitDiff}* 100 / ${diffTotal} ))
  550. IrqCombined=$(( ${IrqDiff} + ${SoftIrqDiff} ))
  551. IrqCombinedLoad=$(( ${IrqCombined}* 100 / ${diffTotal} ))
  552.  
  553. LastUserStat=${UserStat}
  554. LastNiceStat=${NiceStat}
  555. LastSystemStat=${SystemStat}
  556. LastIdleStat=${IdleStat}
  557. LastIOWaitStat=${IOWaitStat}
  558. LastIrqStat=${IrqStat}
  559. LastSoftIrqStat=${SoftIrqStat}
  560. LastTotal=${Total}
  561. procStats=$(echo -e "$(printf "%3s" ${CPULoad})%$(printf "%4s" ${SystemLoad})%$(printf "%4s" ${UserLoad})%$(printf "%4s" ${NiceLoad})%$(printf "%4s" ${IOWaitLoad})%$(printf "%4s" ${IrqCombinedLoad})%")
  562. } # ProcessStats
  563.  
  564. NetworkMonitorMode() {
  565. # Allow script to return back to another calling utility when stopped by [ctrl]-[c]
  566. trap "echo ; exit 0" 0 1 2 3 15
  567.  
  568. # Try to renice to 19 to not interfere with OS behaviour
  569. renice 19 $BASHPID >/dev/null 2>&1
  570.  
  571. # Install bc if not present
  572. which bc >/dev/null 2>&1 || apt-get -f -qq -y install bc >/dev/null 2>&1
  573.  
  574. timerStart
  575. kickAllStatsDown
  576. iface=$(route -n | egrep UG | egrep -o "[a-zA-Z0-9]*$")
  577.  
  578. printf "\nruntime network statistics: $(uname -n)\n"
  579. printf "[tap 'd' to display column headings]\n"
  580. printf "[tap 'z' to reset counters]\n"
  581. printf "[use <ctrl-c> to exit]\n"
  582. printf "[bps: bits/s, Mbps: megabits/s, pps: packets/s, MB: megabytes]\n\n"
  583. printf "%-11s %-66s %-66s\n" $(echo -en "$iface rx.stats____________________________________________________________ tx.stats____________________________________________________________")
  584. printf "%-11s %-11s %-11s \u01B0.%-11s %-11s \u01B0.%-11s \u01A9.%-11s %-11s %-11s \u01B0.%-11s %-11s \u01B0.%-11s \u01A9.%-11s\n\n" $(echo -en "count bps Mbps Mbps pps pps MB bps Mbps Mbps pps pps MB")
  585.  
  586. while true; do
  587. nss=(`sed -n 's/'$iface':\s//p' /proc/net/dev`)
  588. rxB=${nss[0]}
  589. rxP=${nss[1]}
  590. txB=${nss[8]}
  591. txP=${nss[9]}
  592. drxB=$(( ${rxB} - ${prxB} ))
  593. drxb=$(( ${drxB}* 8 ))
  594. drxmb=$(echo "scale=2;$drxb/1000000"|bc)
  595. drxP=$(( ${rxP} - ${prxP} ))
  596. dtxB=$(( ${txB} - ${ptxB} ))
  597. dtxb=$(( ${dtxB}* 8 ))
  598. dtxmb=$(echo "scale=2;$dtxb/1000000"|bc)
  599. dtxP=$(( ${txP} - ${ptxP} ))
  600. if [ "$cnt" != "0" ]; then
  601. if [ "$c" == "N" ]; then
  602. printf "\x1b[1A"
  603. fi
  604. srxb=$(( ${srxb} + ${drxb} ))
  605. stxb=$(( ${stxb} + ${dtxb} ))
  606. srxB=$(( ${srxB} + ${drxB} ))
  607. stxB=$(( ${stxB} + ${dtxB} ))
  608. srxP=$(( ${srxP} + ${drxP} ))
  609. stxP=$(( ${stxP} + ${dtxP} ))
  610. srxMB=$(echo "scale=2;$srxB/1024^2"|bc)
  611. stxMB=$(echo "scale=2;$stxB/1024^2"|bc)
  612. arxb=$(echo "scale=2;$srxb/$cnt"|bc)
  613. atxb=$(echo "scale=2;$stxb/$cnt"|bc)
  614. arxmb=$(echo "scale=2;$arxb/1000000"|bc)
  615. atxmb=$(echo "scale=2;$atxb/1000000"|bc)
  616. arxP=$(echo "scale=0;$srxP/$cnt"|bc)
  617. atxP=$(echo "scale=0;$stxP/$cnt"|bc)
  618. printf "%-11s %-11s %-11s %-11s %-11s %-11s %-11s %-11s %-11s %-11s %-11s %-11s %-11s\n" $(echo -en "$cnt $drxb $drxmb $arxmb $drxP $arxP $srxMB $dtxb $dtxmb $atxmb $dtxP $atxP $stxMB")
  619. fi
  620. prxB="$rxB"
  621. prxP="$rxP"
  622. ptxB="$txB"
  623. ptxP="$txP"
  624. let cnt++
  625. timerShut
  626. read -n1 -s -t$procSecs zeroAll
  627. timerStart
  628. if [ "$zeroAll" == 'z' ]; then
  629. kickAllStatsDown
  630. fi
  631. if [ "$zeroAll" == 'd' ]; then
  632. scrollingHeader
  633. fi
  634. done
  635. }
  636.  
  637. scrollingHeader() {
  638. printf "%-11s %-66s %-66s\n" $(echo -en "$iface rx.stats____________________________________________________________ tx.stats____________________________________________________________")
  639. printf "%-11s %-11s %-11s \u01B0.%-11s %-11s \u01B0.%-11s \u01A9.%-11s %-11s %-11s \u01B0.%-11s %-11s \u01B0.%-11s \u01A9.%-11s\n\n" $(echo -en "count bps Mbps Mbps pps pps MB bps Mbps Mbps pps pps MB")
  640. }
  641.  
  642. timerStart() {
  643. read st0 st1 < <(date +'%s %N')
  644. }
  645.  
  646. timerShut() {
  647. read sh0 sh1 < <(date +'%s %N')
  648. jusquaQuand=$(echo "scale=2;($sh0-$st0)*1000000000+($sh1-$st1)"|bc)
  649. procSecs=$(echo "scale=2;(1000000000-$jusquaQuand)/1000000000"|bc)
  650. if [ "$rf1" == "debug" ]; then
  651. printf "time controller adjustment: $procSecs\n"
  652. if [ "$c" == "N" ]; then
  653. printf "\x1b[1A"
  654. fi
  655. fi
  656. }
  657.  
  658. kickAllStatsDown() {
  659. prxB=0
  660. prxP=0
  661. ptxB=0
  662. ptxP=0
  663. srxb=0
  664. stxb=0
  665. srxB=0
  666. stxB=0
  667. srxMB=0
  668. stxMB=0
  669. srxP=0
  670. stxP=0
  671. cnt=0
  672. }
  673.  
  674. Main "$@"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement