├── LICENSE ├── README.md ├── img ├── 1.png └── 2.png ├── install.sh └── loadavg_watcher /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # loadavg-telegram-watcher 2 | monitors the load average server and in case of problems sends problem messages to Telegram, sends paste to pastebin.com with info of user processes sorted by cpu usage and current processlist mysql. Pastebin link is included in the telegram message. 3 | 4 | easy install with customization: 5 | 6 | \# sudo /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/avtobys/loadavg-telegram-watcher/main/install.sh)" 7 | 8 | the script will ask for missing variables: 9 | 10 | \# sudo /bin/bash -c " \ 11 | AVG_MAX='3'; \ 12 | BOT_ID='your_telegram_bot_token'; \ 13 | CHAT_ID='your_chat_id'; \ 14 | PASTE_KEY='your_paste_key'; \ 15 | $(curl -fsSL https://raw.githubusercontent.com/avtobys/loadavg-telegram-watcher/main/install.sh)" 16 | 17 | AVG_MAX='0' # 0 - for set the recommended value equal to nproc + 30% 18 | 19 | automatic places script to /usr/local/bin/loadavg_watcher 20 | automatic places the cron task to /etc/cron.d/loadavg_watcher 21 | 22 | ![plot](img/1.png) 23 | 24 | complete! 25 | 26 | * Tested on Debian Linux 27 | 28 | load 1 processor by 100% 29 | \# yes > /dev/null 30 | 31 | 32 | ![plot](img/2.png) 33 | -------------------------------------------------------------------------------- /img/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avtobys/loadavg-telegram-watcher/e99559a46f59e7abdf1b62b734117f68c69d57d9/img/1.png -------------------------------------------------------------------------------- /img/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avtobys/loadavg-telegram-watcher/e99559a46f59e7abdf1b62b734117f68c69d57d9/img/2.png -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ ! -d "/usr/local/bin" ]; then 4 | printf "\033[0;31mNo such directory /usr/local/bin\033[0m\n" 5 | exit 1 6 | fi 7 | 8 | if [ ! -d "/etc/cron.d" ]; then 9 | printf "\033[0;31mNo such directory /etc/cron.d\033[0m\n" 10 | exit 1 11 | fi 12 | 13 | 14 | [ -z "${IP:=$(curl -s -m1 checkip.amazonaws.com)}" ] && [ -z "${IP:=$(curl -s -m1 ident.me)}" ] && [ -z "${IP:=$(curl -s -m1 ipinfo.io/ip)}" ] 15 | 16 | RECOMM=$(awk 'function ceil(x){return int(x)+(x>int(x))} {print ceil($0*1.3)}' <<< $(nproc)) 17 | 18 | printf "Welcome to install programm loadavg telegram watcher! \n\nNumber processors of this computer[$IP]: $(nproc) \nRecommended max load average value: $RECOMM\n\n" 19 | 20 | if [ -z "$AVG_MAX" ]; then 21 | echo -n 'Enter setting value for the maximum load average for 1 minute(0 = recommended): ' 22 | read AVG_MAX 23 | fi 24 | 25 | if [ "$AVG_MAX" = "0" -o -z "$AVG_MAX" ]; then 26 | AVG_MAX=$RECOMM 27 | fi 28 | 29 | if [[ ! "$AVG_MAX" =~ ^[0-9]+$ ]]; then 30 | AVG_MAX=$RECOMM 31 | fi 32 | 33 | echo ${SET_AVG_MAX:="Max load average set: $AVG_MAX"} 34 | 35 | install_telegram() { 36 | if [ -z "$BOT_ID" ]; then 37 | echo -n 'Enter your telegram bot token: ' 38 | read BOT_ID 39 | fi 40 | echo ${SET_BOT_ID:="Telegram bot token set: $BOT_ID"} 41 | if [ -z "$CHAT_ID" ]; then 42 | echo -n 'Enter your telegram chat id: ' 43 | read CHAT_ID 44 | fi 45 | echo ${SET_CHAT_ID:="Telegram chat id set: $CHAT_ID"} 46 | TG_URL="https://api.telegram.org/bot$BOT_ID/sendMessage" 47 | N=$'\n' 48 | TG_RES=$(curl -s -X POST \ 49 | --data "chat_id=$CHAT_ID&parse_mode=html&text=$IP $N Settings are almost ready $N $SET_AVG_MAX $N $SET_BOT_ID $N $SET_CHAT_ID" $TG_URL | 50 | sed -r 's/.*"ok"[[:space:]]*:[[:space:]]*(true)[[:space:]]*,[[:space:]]*"result".*/\1/') 51 | if [ "$TG_RES" != "true" ]; then 52 | BOT_ID= 53 | CHAT_ID= 54 | SET_BOT_ID= 55 | SET_CHAT_ID= 56 | printf "\033[0;31mTelegram bot token or chat id is wrong...\033[0m\n" 57 | return 1 58 | else 59 | return 0 60 | fi 61 | } 62 | 63 | 64 | while ! install_telegram; do 65 | true 66 | done 67 | 68 | if [ -z "$PASTE_KEY" ]; then 69 | echo -n 'Enter your pastebin.com api developer key(optional): ' 70 | read PASTE_KEY 71 | fi 72 | 73 | echo "Pastebin developer token set: $PASTE_KEY" 74 | 75 | if [ $(command -v ps) ]; then 76 | echo "ps: ok" 77 | else 78 | printf "\033[0;31mCommand ps not found\033[0m\n" 79 | exit 1 80 | fi 81 | 82 | echo -n "mysqladmin: " 83 | if [ $(command -v mysqladmin) ]; then 84 | echo "ok" 85 | else 86 | echo "fail" 87 | fi 88 | 89 | echo -n "iotop: " 90 | if [ $(command -v iotop) ]; then 91 | echo "ok" 92 | else 93 | echo "fail" 94 | fi 95 | 96 | IFS="" 97 | 98 | SCRIPT=$(curl -fsSL https://raw.githubusercontent.com/avtobys/loadavg-telegram-watcher/main/loadavg_watcher | 99 | sed -r "s/AVG_MAX=([0-9]+)/AVG_MAX=$AVG_MAX/" | 100 | sed -r "s/BOT_ID=\"[^\"]+\"/BOT_ID=\"$BOT_ID\"/" | 101 | sed -r "s/CHAT_ID=\"[^\"]+\"/CHAT_ID=\"$CHAT_ID\"/" | 102 | sed -r "s/PASTE_KEY=\"[^\"]+\"/PASTE_KEY=\"$PASTE_KEY\"/") 103 | 104 | if [ "$(echo $SCRIPT | sed -n 's/.*\(successful installation marker\).*/\1/ip;T;q')" != "successful installation marker" ]; then 105 | printf "\033[0;31mCan't load script https://raw.githubusercontent.com/avtobys/loadavg-telegram-watcher/main/loadavg_watcher\033[0m\n" 106 | exit 1 107 | fi 108 | 109 | echo $SCRIPT >/usr/local/bin/loadavg_watcher 110 | chmod +x /usr/local/bin/loadavg_watcher 111 | echo -e "PATH=/bin:/sbin:/usr/bin:/usr/sbin\n* * * * * root /usr/local/bin/loadavg_watcher > /dev/null 2>&1" >/etc/cron.d/loadavg_watcher 112 | echo "Installation completed successfully!" 113 | exit 0 114 | -------------------------------------------------------------------------------- /loadavg_watcher: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | PATH=/bin:/sbin:/usr/bin:/usr/sbin 3 | export PATH 4 | 5 | AVG_MAX=3 # maximum load avg 6 | BOT_ID="your_telegram_bot_token" # t.me bot token 7 | CHAT_ID="your_chat_id" # t.me chat id 8 | PASTE_KEY="your_paste_key" # pastebin.com api developer key 9 | 10 | TG_URL="https://api.telegram.org/bot$BOT_ID/sendMessage" 11 | 12 | AVG=$(awk -v avg_max=${AVG_MAX} '$1>avg_max{print $1}' /proc/loadavg) 13 | N=$'\n' 14 | if [ -n "$AVG" ]; then 15 | UPTIME=$(uptime) 16 | if [ -n "$PASTE_KEY" ]; then 17 | PASTE="$UPTIME $N $N $(ps -eo pid,ppid,user,cmd,%mem,%cpu --sort=-%cpu | head) $N $N $(ps -eo pid,ppid,user,cmd,%mem,%cpu --sort=-%mem | head)" 18 | 19 | if [ $(command -v mysqladmin) ]; then 20 | PASTE="$PASTE $N $N $(mysqladmin processlist | head)" 21 | fi 22 | 23 | if [ $(command -v iotop) ]; then 24 | PASTE="$PASTE $N $N $(iotop -n 2 -q -t | head)" 25 | fi 26 | 27 | PASTE_RES=$(curl -X POST --data "api_option=paste&api_user_key=&api_paste_private=1&api_paste_name=high load&api_paste_expire_date=1D&api_paste_format=text&api_dev_key=$PASTE_KEY&api_paste_code=$PASTE" https://pastebin.com/api/api_post.php 2>/dev/null | sed 's/pastebin\.com\//pastebin.com\/raw\//') 28 | if [[ ! "$PASTE_RES" =~ ^https://pastebin ]]; then 29 | PASTE_RES= 30 | fi 31 | fi 32 | if [ -n "$BOT_ID" -a -n "$CHAT_ID" ]; then 33 | [ -z "${IP:=$(curl -s -m1 checkip.amazonaws.com)}" ] && [ -z "${IP:=$(curl -s -m1 ident.me)}" ] && [ -z "${IP:=$(curl -s -m1 ipinfo.io/ip)}" ] 34 | curl -X POST --data "chat_id=$CHAT_ID&parse_mode=html&text=$IP $N HIGH $UPTIME $N $PASTE_RES" $TG_URL >/dev/null 2>&1 35 | sleep 61s 36 | AVG=$(awk -v avg_max=${AVG_MAX} '$1<=avg_max{print $1}' /proc/loadavg) 37 | if [ -n "$AVG" ]; then 38 | UPTIME=$(uptime) 39 | curl -X POST --data "chat_id=$CHAT_ID&parse_mode=html&text=$IP $N NORM $UPTIME" $TG_URL >/dev/null 2>&1 40 | fi 41 | fi 42 | fi 43 | 44 | # successful installation marker 45 | 46 | exit 0 47 | --------------------------------------------------------------------------------