#description: telegram bot for monitoring the system #dependencies: telebot #usage: python3 lainmonitor.py | or run it as a service #author: hornetmaidan import subprocess import telebot #define the variables status, hostname, uptime, zerotier, prosody, postgres, tailscale, disk, ping = 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown' #telegram bot token TOKEN = 'PLACE_YOUR_TOKEN_HERE' #bot init bot = telebot.TeleBot(TOKEN) #get system info def getinfo(): global status, hostname, uptime, zerotier, prosody, postgres, tailscale, disk hostname = subprocess.check_output(['hostname']).decode().strip() uptime = subprocess.check_output(['uptime', '-p']).decode().strip() #systemd-only services zerotier = subprocess.Popen("sudo systemctl status zerotier-one | grep 'Active'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip() prosody = subprocess.Popen("sudo systemctl status prosody | grep 'Active'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip() postgres = subprocess.Popen("sudo systemctl status postgresql | grep 'Active'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip() tailscale = subprocess.Popen("sudo systemctl status tailscaled | grep 'Active'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip() disk = subprocess.check_output(['df', '-h']).decode().strip() if hostname == 'unknown': status = 'offline' else: status = 'online' return hostname, uptime, zerotier, prosody, postgres, tailscale, disk #ping tailscale (change the IP address to the one you want or add more) def check_tailscale(): global ping ping = subprocess.Popen("ping TAILSCALE_IP -c 1 | grep '1 packets'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip() if '1 received' in ping: ping = 'connected' else: ping = 'unreachable' return ping #debug handler def check(): global status, hostname, uptime, zerotier, prosody, postgres, tailscale, disk getinfo() print('system status:', status) print('hostname:', hostname) print('uptime:', uptime) print('zerotier:', zerotier) print('prosody:', prosody) print('postgres:', postgres) print('tailscale:', tailscale) print('disk:', disk) return status, hostname, uptime, zerotier, prosody, postgres, tailscale, disk #message handling @bot.message_handler(commands=['start', 'help', 'status', 'reboot', 'ping']) def handle(message): if message.text == '/start': bot.reply_to(message, 'lainmonitor v1.0 --- standing by...') elif message.text == '/help': bot.reply_to(message, 'commands: /start, /help, /status, /reboot, /ping') elif message.text == '/status': check() status_message = f'hostname: {hostname}\nsystem status: {status}\nuptime: {uptime}\nzerotier: {zerotier}\nprosody: {prosody}\npostgres: {postgres}\ntailscale: {tailscale}' bot.reply_to(message, status_message) bot.reply_to(message, f'filesystem info for {hostname}: \n\n{disk}') elif message.text == '/reboot': bot.reply_to(message, 'work in progress...') elif message.text == '/ping': check_tailscale() bot.reply_to(message, f'ping status: {ping}') #polling bot.polling()