info_distro.sh 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. #!/bin/bash
  2. # LinuxGSM info_distro.sh module
  3. # Author: Daniel Gibbs
  4. # Contributors: http://linuxgsm.com/contrib
  5. # Website: https://linuxgsm.com
  6. # Description: Variables providing useful info on the Operating System such as disk and performace info.
  7. # Used for command_details.sh, command_debug.sh and alert.sh.
  8. # !Note: When adding variables to this script, ensure that they are also added to the command_dev_parse_distro_details.sh script.
  9. moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
  10. ### Game Server pid
  11. if [ "${status}" == "1" ]; then
  12. gameserverpid="$(tmux -L "${socketname}" list-sessions -F "#{session_name} #{pane_pid}" | grep "^${sessionname} " | awk '{print $NF}')"
  13. if [ "${engine}" == "source" ]; then
  14. srcdslinuxpid="$(ps -ef | grep -v grep | grep "${gameserverpid}" | grep srcds_linux | awk '{print $2}')"
  15. elif [ "${engine}" == "goldsrc" ]; then
  16. hldslinuxpid="$(ps -ef | grep -v grep | grep "${gameserverpid}" | grep hlds_linux | awk '{print $2}')"
  17. fi
  18. fi
  19. ### Distro information
  20. ## Distro
  21. # Returns architecture, kernel and distro/os.
  22. arch="$(uname -m)" # Architecture e.g. x86_64
  23. kernel="$(uname -r)" # Kernel e.g. 2.6.32-042stab120.16
  24. # Gathers distro info from various sources filling in missing gaps.
  25. distro_info_array=(os-release lsb_release hostnamectl debian_version redhat-release)
  26. for distro_info in "${distro_info_array[@]}"; do
  27. if [ -f "/etc/os-release" ] && [ "${distro_info}" == "os-release" ]; then
  28. distroname="$(grep "PRETTY_NAME" /etc/os-release | awk -F= '{gsub(/"/,"",$2);print $2}')" # e.g. Ubuntu 22.04.3 LTS
  29. distroversion="$(grep "VERSION_ID" /etc/os-release | awk -F= '{gsub(/"/,"",$2);print $2}')" # e.g. 22.04
  30. distroid="$(grep "ID=" /etc/os-release | grep -v _ID | awk -F= '{gsub(/"/,"",$2);print $2}')" # e.g. ubuntu
  31. distroidlike="$(grep "ID_LIKE=" /etc/os-release | grep -v _ID | awk -F= '{gsub(/"/,"",$2);print $2}')" # e.g. debian
  32. distrocodename="$(grep "VERSION_CODENAME" /etc/os-release | awk -F= '{gsub(/"/,"",$2);print $2}')" # e.g. jammy
  33. # Special var for rhel like distros to remove point in number e.g 8.4 to just 8.
  34. if [[ "${distroidlike}" == *"rhel"* ]] || [ "${distroid}" == "rhel" ]; then
  35. distroversionrh="$(sed -nr 's/^VERSION_ID="([0-9]*).+?"/\1/p' /etc/os-release)" # e.g. 8
  36. fi
  37. elif [ "$(command -v lsb_release 2> /dev/null)" ] && [ "${distro_info}" == "lsb_release" ]; then
  38. if [ -z "${distroname}" ]; then
  39. distroname="$(lsb_release -sd)" # e.g. Ubuntu 22.04.3 LTS
  40. elif [ -z "${distroversion}" ]; then
  41. distroversion="$(lsb_release -sr)" # e.g. 22.04
  42. elif [ -z "${distroid}" ]; then
  43. distroid="$(lsb_release -si)" # e.g. Ubuntu
  44. elif [ -z "${distrocodename}" ]; then
  45. distrocodename="$(lsb_release -sc)" # e.g. jammy
  46. fi
  47. elif [ "$(command -v hostnamectl 2> /dev/null)" ] && [ "${distro_info}" == "hostnamectl" ]; then
  48. if [ -z "${distroname}" ]; then
  49. distroname="$(hostnamectl | grep "Operating System" | sed 's/Operating System: //g')" # e.g. Ubuntu 22.04.3 LTS
  50. fi
  51. elif [ -f "/etc/debian_version" ] && [ "${distro_info}" == "debian_version" ]; then
  52. if [ -z "${distroname}" ]; then
  53. distroname="Debian $(cat /etc/debian_version)" # e.g. Debian bookworm/sid
  54. elif [ -z "${distroversion}" ]; then
  55. distroversion="$(cat /etc/debian_version)" # e.g. bookworm/sid
  56. elif [ -z "${distroid}" ]; then
  57. distroid="debian"
  58. fi
  59. elif [ -f "/etc/redhat-release" ] && [ "${distro_info}" == "redhat-release" ]; then
  60. if [ -z "${distroname}" ]; then
  61. distroname="$(cat /etc/redhat-release)" # e.g. Rocky Linux release 9.2 (Blue Onyx)
  62. elif [ -z "${distroversion}" ]; then
  63. distroversion="$(rpm -qa \*-release | grep -Ei "oracle|redhat|centos|fedora|rocky|alma" | cut -d"-" -f3)" # e.g. 9.2
  64. elif [ -z "${distroid}" ]; then
  65. distroid="$(awk '{print $1}' /etc/redhat-release)" # e.g. Rocky
  66. fi
  67. fi
  68. done
  69. # Get virtual environment type.
  70. if [ "$(command -v systemd-detect-virt 2> /dev/null)" ]; then
  71. virtualenvironment="$(systemd-detect-virt)" # e.g. kvm
  72. fi
  73. # distroversioncsv is used for selecting the correct distro csv in data directory
  74. if [ -n "${distroversionrh}" ]; then
  75. distroversioncsv="${distroversionrh}" # e.g. 8
  76. else
  77. distroversioncsv="${distroversion}" # e.g. 22.04
  78. fi
  79. # Check if distro supported by distro vendor.
  80. # distro-info available in debian based distros.
  81. if [ "$(command -v distro-info 2> /dev/null)" ]; then
  82. distrosunsupported="$(distro-info --unsupported)"
  83. distrosunsupported_array=("${distrosunsupported}")
  84. for distrounsupported in "${distrosunsupported_array[@]}"; do
  85. if [ "${distrounsupported}" == "${distrocodename}" ]; then
  86. distrosupport="unsupported"
  87. break
  88. else
  89. distrosupport="supported"
  90. fi
  91. done
  92. elif [[ "${distroidlike}" == *"rhel"* ]] || [ "${distroid}" == "rhel" ]; then
  93. # RHEL/CentOS 7 EOL 2024-06-30. Will be unsupported after this date.
  94. if [ "${distroversionrh}" -lt "8" ] && [ "$(date +%s)" -lt "1719705600" ]; then
  95. distrosupport="unsupported"
  96. else
  97. distrosupport="supported"
  98. fi
  99. fi
  100. ## Glibc version
  101. glibcversion="$(ldd --version | sed -n '1s/.* //p')" # e.g: 2.17
  102. ## tmux version
  103. if [ "$(command -V tmux 2> /dev/null)" ]; then
  104. tmuxversion="$(tmux -V | awk '{print $2}')" # e.g: tmux 3.3
  105. fi
  106. if [ "$(command -V java 2> /dev/null)" ]; then
  107. javaversion="$(java -version 2>&1 | grep "version")" # e.g: openjdk version "17.0.8.1" 2023-08-24
  108. fi
  109. if [ "$(command -v mono 2> /dev/null)" ]; then
  110. monoversion="$(mono --version 2>&1 | grep -Po '(?<=version )\d')" # e.g: 6
  111. fi
  112. if [ "$(command -v dotnet 2> /dev/null)" ]; then
  113. dotnetversion="$(dotnet --list-runtimes | grep -E 'Microsoft\.NETCore\.App' | awk '{print $2}')" # e.g: 6.0.0
  114. fi
  115. ## Uptime
  116. uptime="$(< /proc/uptime)"
  117. uptime=${uptime/[. ]*/}
  118. minutes="$((uptime / 60 % 60))"
  119. hours="$((uptime / 60 / 60 % 24))"
  120. days="$((uptime / 60 / 60 / 24))"
  121. ### Performance information
  122. ## Average server load
  123. load="$(uptime | awk -F 'load average: ' '{ print $2 }')" # e.g 0.01, 0.05, 0.11
  124. ## CPU information
  125. cpumodel="$(awk -F: '/model name/ {name=$2} END {print name}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//')" # e.g Intel(R) Xeon(R) CPU E5-2676 v3 @ 2.40GHz
  126. cpucores="$(awk -F: '/model name/ {core++} END {print core}' /proc/cpuinfo)"
  127. cpufreqency="$(awk -F: '/cpu MHz/ {freq=$2} END {print freq}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//')" # e.g 2394.503
  128. # CPU usage of the game server pid
  129. if [ -n "${gameserverpid}" ]; then
  130. cpuused="$(ps --forest -o pcpu -g "${gameserverpid}" | awk '{s+=$1} END {print s}')" # integer
  131. cpuusedmhz="$(echo "${cpufreqency} * ${cpuused} / 100" | bc)" # integer
  132. fi
  133. ## Memory information
  134. # Available RAM and swap.
  135. # Newer distros can use numfmt to give more accurate results.
  136. if [ "$(command -v numfmt 2> /dev/null)" ]; then
  137. # Issue #2005 - Kernel 3.14+ contains MemAvailable which should be used. All others will be calculated.
  138. # get the raw KB values of these fields.
  139. physmemtotalkb="$(grep MemTotal /proc/meminfo | awk '{print $2}')" # integer
  140. physmemfreekb="$(grep ^MemFree /proc/meminfo | awk '{print $2}')" # integer
  141. physmembufferskb="$(grep ^Buffers /proc/meminfo | awk '{print $2}')" # integer
  142. physmemcachedkb="$(grep ^Cached /proc/meminfo | awk '{print $2}')" # integer
  143. physmemreclaimablekb="$(grep ^SReclaimable /proc/meminfo | awk '{print $2}')" # integer
  144. # check if MemAvailable Exists.
  145. if grep -q ^MemAvailable /proc/meminfo; then
  146. physmemactualfreekb="$(grep ^MemAvailable /proc/meminfo | awk '{print $2}')" # integer
  147. else
  148. physmemactualfreekb="$((physmemfreekb + physmembufferskb + physmemcachedkb))" # integer
  149. fi
  150. # Available RAM and swap.
  151. physmemtotalmb="$(((physmemtotalkb + 512) / 1024))" # integer # integer
  152. physmemtotalgb="$(((physmemtotalmb + 512) / 1024))" # integer # integer
  153. physmemtotal="$(numfmt --to=iec --from=iec --suffix=B "${physmemtotalkb}K")" # string
  154. physmemfree="$(numfmt --to=iec --from=iec --suffix=B "${physmemactualfreekb}K")" # string
  155. physmemused="$(numfmt --to=iec --from=iec --suffix=B "$((physmemtotalkb - physmemfreekb - physmembufferskb - physmemcachedkb - physmemreclaimablekb))K")" # string
  156. physmemavailable="$(numfmt --to=iec --from=iec --suffix=B "${physmemactualfreekb}K")" # string
  157. physmemcached="$(numfmt --to=iec --from=iec --suffix=B "$((physmemcachedkb + physmemreclaimablekb))K")" # string
  158. swaptotal="$(numfmt --to=iec --from=iec --suffix=B "$(grep ^SwapTotal /proc/meminfo | awk '{print $2}')K")" # string
  159. swapfree="$(numfmt --to=iec --from=iec --suffix=B "$(grep ^SwapFree /proc/meminfo | awk '{print $2}')K")" # string
  160. swapused="$(numfmt --to=iec --from=iec --suffix=B "$(($(grep ^SwapTotal /proc/meminfo | awk '{print $2}') - $(grep ^SwapFree /proc/meminfo | awk '{print $2}')))K")" # string
  161. # RAM usage of the game server pid
  162. if [ "${gameserverpid}" ]; then
  163. memusedmb="$(ps --forest -o rss -g "${gameserverpid}" | awk '{s+=$1} END {print s}' | awk '{$1/=1024;printf "%.0f",$1}{print $2}')" # integer
  164. memusedpct="$(ps --forest -o %mem -g "${gameserverpid}" | awk '{s+=$1} END {print s}')" # integer
  165. fi
  166. else
  167. # Older distros will need to use free.
  168. # Older versions of free do not support -h option.
  169. if [ "$(
  170. free -h > /dev/null 2>&1
  171. echo $?
  172. )" -ne "0" ]; then
  173. humanreadable="-m"
  174. else
  175. humanreadable="-h"
  176. fi
  177. physmemtotalmb="$(free -m | awk '/Mem:/ {print $2}')" # integer
  178. physmemtotalgb="$(free -m | awk '/Mem:/ {print $2}')" # integer
  179. physmemtotal="$(free ${humanreadable} | awk '/Mem:/ {print $2}')" # string
  180. physmemfree="$(free ${humanreadable} | awk '/Mem:/ {print $4}')" # string
  181. physmemused="$(free ${humanreadable} | awk '/Mem:/ {print $3}')" # string
  182. oldfree="$(free ${humanreadable} | awk '/cache:/')"
  183. if [ "${oldfree}" ]; then
  184. physmemavailable="n/a" # string
  185. physmemcached="n/a" # string
  186. else
  187. physmemavailable="$(free ${humanreadable} | awk '/Mem:/ {print $7}')" # string
  188. physmemcached="$(free ${humanreadable} | awk '/Mem:/ {print $6}')" # string
  189. fi
  190. swaptotal="$(free ${humanreadable} | awk '/Swap:/ {print $2}')" # string
  191. swapused="$(free ${humanreadable} | awk '/Swap:/ {print $3}')" # string
  192. swapfree="$(free ${humanreadable} | awk '/Swap:/ {print $4}')" # string
  193. fi
  194. ### Disk information
  195. ## Available disk space on the partition.
  196. filesystem="$(LC_ALL=C df -hP "${rootdir}" | tail -n 1 | awk '{print $1}')" # string e.g /dev/sda
  197. totalspace="$(LC_ALL=C df -hP "${rootdir}" | tail -n 1 | awk '{print $2}')" # string e.g 20G
  198. usedspace="$(LC_ALL=C df -hP "${rootdir}" | tail -n 1 | awk '{print $3}')" # string e.g 15G
  199. availspace="$(LC_ALL=C df -hP "${rootdir}" | tail -n 1 | awk '{print $4}')" # string e.g 5G
  200. ## LinuxGSM used space total.
  201. rootdirdu="$(du -sh "${rootdir}" 2> /dev/null | awk '{print $1}')"
  202. if [ -z "${rootdirdu}" ]; then
  203. rootdirdu="0M"
  204. fi
  205. ## LinuxGSM used space in serverfiles dir.
  206. serverfilesdu="$(du -sh "${serverfiles}" 2> /dev/null | awk '{print $1}')"
  207. if [ -z "${serverfilesdu}" ]; then
  208. serverfilesdu="0M"
  209. fi
  210. ## LinuxGSM used space total minus backup dir.
  211. rootdirduexbackup="$(du -sh --exclude="${backupdir}" "${serverfiles}" 2> /dev/null | awk '{print $1}')"
  212. if [ -z "${rootdirduexbackup}" ]; then
  213. rootdirduexbackup="0M"
  214. fi
  215. ## Backup info
  216. if [ -d "${backupdir}" ]; then
  217. # Used space in backups dir.
  218. backupdirdu="$(du -sh "${backupdir}" | awk '{print $1}')"
  219. # If no backup dir, size is 0M.
  220. if [ -z "${backupdirdu}" ]; then
  221. backupdirdu="0M"
  222. fi
  223. # number of backups set to 0 by default.
  224. backupcount=0
  225. # If there are backups in backup dir.
  226. if [ "$(find "${backupdir}" -name "*.tar.gz" | wc -l)" -ne "0" ]; then
  227. # number of backups.
  228. backupcount="$(find "${backupdir}"/*.tar.gz | wc -l)" # integer
  229. # most recent backup.
  230. lastbackup="$(ls -1t "${backupdir}"/*.tar.gz | head -1)" # string
  231. # date of most recent backup.
  232. lastbackupdate="$(date -r "${lastbackup}")" # string
  233. # no of days since last backup.
  234. lastbackupdaysago="$((($(date +'%s') - $(date -r "${lastbackup}" +'%s')) / 60 / 60 / 24))" # integer
  235. # size of most recent backup.
  236. lastbackupsize="$(du -h "${lastbackup}" | awk '{print $1}')" # string
  237. fi
  238. fi
  239. # Network Interface name
  240. netint=$(${ipcommand} -o addr | grep "${ip}" | awk '{print $2}') # e.g eth0
  241. netlink=$(${ethtoolcommand} "${netint}" 2> /dev/null | grep Speed | awk '{print $2}') # e.g 1000Mb/s
  242. # Sets the SteamCMD glibc requirement if the game server requirement is less or not required.
  243. if [ "${appid}" ]; then
  244. if [ "${glibc}" = "null" ] || [ -z "${glibc}" ] || [ "$(printf '%s\n'${glibc}'\n' "2.14" | sort -V | head -n 1)" != "2.14" ]; then
  245. glibc="2.14"
  246. fi
  247. fi
  248. # Gather Port Info using ss.
  249. ssinfo="$(ss -tuplwn)"