diff --git a/.gitignore b/.gitignore index 1a80bf0..767f74b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -tokens.py +#tokens.py graph.png diff --git a/README.md b/README.md index 004d24a..f01981b 100644 --- a/README.md +++ b/README.md @@ -1,89 +1,115 @@ # Server Manager Bot -A Telegram Bot: +原项目详见fork源,您正在看的这个repo某种意义上属于二开版,Working in progress之后是原readme的完整翻译,也可以当做部署教程,实际上,这个repo只是比原repo维护+新功能+汉化。 -* Commands - * `/stats` - gives summed statistics about memory \ disk \ processes (will improve) - * `/shell` - goes into the mode of executing shell commands & sends you the output - * `/memgraph` - plots a graph of memory usage for a past period and sends you a picture of the graph - * `/setmem` - set memory threshold (%) to monitor and notify if memory usage goes above it - * `/setpoll` - set polling interval in seconds (higher than 10) -* Monitors memory usage and if it reaches above the set threshold = sends you warning message +后续更新请看[这里](https://github.com/iamydp/ServerMonitorBot),此版本不做后续维护 +2020-3-31新增 -Example summary: [Gif](http://i.imgur.com/AhCvy9W.gifv) +输入/start或/help或help时回复所有可用的命令。(虽然在向@botfather添加命令过后这个显得有点多余) + +Known Issue +* 机器人新上线一段时间内绘制图标x轴为负数,过一段时间后恢复正常。 +* 设置新阈值或探测间隔,收到新消息后不会自动stop。 + +Working in Progress +* 开机以来所用流量功能 +* 当前网速 +* 磁盘使用详细情况 +* 重启/掉进程后上线提示 + +欢迎与我或原作者(找不到人了)发邮件探讨/提issue! + +功能: +* 命令 + * `/stats` - 检查磁盘/CPU/内存使用情况(正在完善中) + * `/shell` - 进入执行命令模式并返回结果 + * `/memgraph` - 绘制近一段时间的内存使用记录表 + * `/setmem` - 设置内存占用告警阈值,并在占用情况高于这个值时告警 + * `/setpoll` - 设置探测间隔(不少于10秒) +* 检测内存使用情况并且在高于设定阈值时通过telegram发送告警消息 + + +`/stats`命令演示: [Gif](http://i.imgur.com/AhCvy9W.gifv) ![Bot](http://i.imgur.com/hXT0drx.png) -Example shell command output as a message from the bot: +`/shell`命令演示: ![Shell](https://i.imgur.com/PtvcaSD.png) -Example graph sent by bot: [Gif](http://i.imgur.com/anX7rJR.gifv) +`/memgraph`命令演示: [Gif](http://i.imgur.com/anX7rJR.gifv) ![Graph](http://i.imgur.com/K8mG3aM.jpg?1) -# Usage +# 使用方法 -## Requirements +## 所需环境 * Python 3+ * [Telepot](https://github.com/nickoala/telepot) * [Psutil](https://github.com/giampaolo/psutil) - * Make sure to install it for Python 3+ - * In order to make sure that `pip` installs packages for the 3+ version: + * 确保Psutil是为Python3工作,而非2 + * 确保`pip`是最新版本: * `curl -O https://bootstrap.pypa.io/get-pip.py` * `sudo python3 get-pip.py` - * After that `pip install psutil` - * Also Stackoverflow question about that [here](http://stackoverflow.com/questions/11268501/how-to-use-pip-with-python-3-x-alongside-python-2-x) + * 之后使用`pip install psutil` + * 在Stackoverflow上也有相关问题的回答[链接](http://stackoverflow.com/questions/11268501/how-to-use-pip-with-python-3-x-alongside-python-2-x) * [matplotlib](http://matplotlib.org/) * `sudo apt-get install python3-matplotlib` * Bot key & `tokens.py` - * Hide all the keys and admin variables in `tokens.py`. Use it only for sensitive variables. Avoid creating functions not to clutter the namespaces through the import. - * Get a key from the [Bot Father](https://telegram.me/BotFather) - * Clone that repo - * In the folder with the cloned repo create a file `tokens.py` - * It's added to the `.gitignore` so you don't commit your own (and I don't commit mine:) - * In that file put a string variable `telegrambot` which equals your key - * For example: `telegrambot = "000000000:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"` - -## Running the bot + * 把token放在`tokens.py`里. `tokens.py`只用来保存您的chat_id和bot token.不要随便定义/更改函数名. + * 从@Bot Father新建机器人/获取token[Bot Father](https://telegram.me/BotFather) + * 克隆该仓库 + * 在本地文件夹内新建文件`tokens.py` + * 已经加入`.gitignore`豪华套餐,所以谁的key/token都不会提交上来 + * 将`telegrambot`后字符串换成自己的token + * 如: `telegrambot = "000000000:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + * 编者按:原readme中的确是这样写的,但作者更新的时候可能忘了改了,这里直接vim编辑tokens.py_example再mv重命名去掉_example就可以了。 + +## 开始运行 `python3 servstatsbot.py` -## Running the bot as "daemon" - -* See included file in the repo: `servstatsbot.conf` - * Open it and edit the path as mentiond in the comments there -* Place that file in `/etc/init/` -* Start the "daemon" with: `start servstatsbot` - * You can start|stop|restart - * If bot crashes it'll be automatically restarted - * It will also start after reboot +## 将bot作为进程运行 -## Setting an admin +* 参见文件: `servstatsbot.conf` + * 根据文件内注释指示更改路径 +* 将`servstatsbot.conf`放在`/etc/init/`内 +* 用该命令启动进程: `start servstatsbot` + * 之后,以下命令将可用:`start|stop|restart servstatsbot` + * 如果进程崩溃将会自动重启 + * 开机启动 -You have to set a variable `adminchatid` in `tokens.py` to be equal your chat_id or multiple chat_id (if more people will use your bot). -For example: +## 设定一个管理员 +在`tokens.py`中设定`adminchatid`变量为chat_id(如果您的工具人是个公交车,参照如下方法). * `adminchatid = [443355]` * `adminchatid = [443355, 55667788, 99884433]` -I will reimplement this differently later. - +之后我将会重新编写这块的代码 + +译者按:这句话是原作者写的,我没说过 + +# 欢迎一键三连 XD + 我在十分钟之内拼凑出这个代码,之后又花了一点时间使之成.我觉得这个bot是个很好的想法,并且阅读这段话当中的某些人会非常喜欢这个repo.所以请随便fork,pull,提交新功能! + + 可以给你contributors access哦!笔芯 -# PLEASE CONTRIBUTE :) - I threw this code together within 10 minutes or so as a mockup to work on it later. But I think it's a nice bot idea and some of you guys might like this too. So please feel free to fork, pull, requests features! - Can give contributors access! - Would really love to see this bot grow some fat and brain:) + 真心希望看到这个项目能够快速发展起来:) + +译者按:这些话也是作者说的,可是他已经4年没有更新了,会不会... + -# Other bot development +# 其他的bot项目 ## Alfred [http://alfredthebot.com](http://alfredthebot.com) + +译者按:已404 GB diff --git a/servstatsbot.conf b/servstatsbot.conf index c45eedd..faa052e 100644 --- a/servstatsbot.conf +++ b/servstatsbot.conf @@ -3,6 +3,9 @@ stop on runlevel [016] respawn # Change PATH_TO_PY_FILE with the path to the bots py file +# 将 PATH_TO_PY_FILE 改为servstatsbot.py文件路径 # Place this file in /etc/init/ +# 把这个文件放在/etc/init/ 里 # And it will be running as "daemon". You can start|stop|restart like this: start servstatsbot +# 之后bot就会以进程方式运行,以下命令有效:start|stop|restart servstatsbot exec python3 /PATH_TO_PY_FILE/servstatsbot.py > /dev/null diff --git a/servstatsbot.py b/servstatsbot.py index 95c1ffc..7a851b5 100644 --- a/servstatsbot.py +++ b/servstatsbot.py @@ -76,11 +76,11 @@ def on_chat_message(self, msg): disk = psutil.disk_usage('/') boottime = datetime.fromtimestamp(psutil.boot_time()) now = datetime.now() - timedif = "Online for: %.1f Hours" % (((now - boottime).total_seconds()) / 3600) - memtotal = "Total memory: %.2f GB " % (memory.total / 1000000000) - memavail = "Available memory: %.2f GB" % (memory.available / 1000000000) - memuseperc = "Used memory: " + str(memory.percent) + " %" - diskused = "Disk used: " + str(disk.percent) + " %" + timedif = "在线时间: %.1f 小时" % (((now - boottime).total_seconds()) / 3600) + memtotal = "总内存: %.2f GB " % (memory.total / 1000000000) + memavail = "可用内存: %.2f GB" % (memory.available / 1000000000) + memuseperc = "使用内存: " + str(memory.percent) + " %" + diskused = "磁盘占用: " + str(disk.percent) + " %" pids = psutil.pids() pidsreply = '' procs = {} @@ -105,44 +105,52 @@ def on_chat_message(self, msg): diskused + "\n\n" + \ pidsreply bot.sendMessage(chat_id, reply, disable_web_page_preview=True) + elif msg['text'] == "help" or msg['text'] == "/help" or msg['text'] == "/start": + bot.sendMessage(chat_id, "以下命令可用") + bot.sendMessage(chat_id, "/stats -检查磁盘/CPU/内存使用情况") + bot.sendMessage(chat_id, "/shell -字面意思") + bot.sendMessage(chat_id, "/memgraph -绘制近一段时间的内存使用记录表") + bot.sendMessage(chat_id, "/setmem -设置内存占用告警阈值,并在占用情况高于这个值是告警") + bot.sendMessage(chat_id, "/setpoll -设置探测间隔(不少于10秒)") + bot.sendMessage(chat_id, "/stop -AZ5") elif msg['text'] == "Stop": clearall(chat_id) - bot.sendMessage(chat_id, "All operations stopped.", reply_markup=hide_keyboard) + bot.sendMessage(chat_id, "所有操作已经停止了", reply_markup=hide_keyboard) elif msg['text'] == '/setpoll' and chat_id not in setpolling: bot.sendChatAction(chat_id, 'typing') setpolling.append(chat_id) - bot.sendMessage(chat_id, "Send me a new polling interval in seconds? (higher than 10)", reply_markup=stopmarkup) + bot.sendMessage(chat_id, "发给我一个新的探测间隔(不少于10秒)", reply_markup=stopmarkup) elif chat_id in setpolling: bot.sendChatAction(chat_id, 'typing') try: global poll poll = int(msg['text']) if poll > 10: - bot.sendMessage(chat_id, "All set!") + bot.sendMessage(chat_id, "整好了!") clearall(chat_id) else: 1/0 except: - bot.sendMessage(chat_id, "Please send a proper numeric value higher than 10.") + bot.sendMessage(chat_id, "需要大于等于10秒,再来一次") elif msg['text'] == "/shell" and chat_id not in shellexecution: - bot.sendMessage(chat_id, "Send me a shell command to execute", reply_markup=stopmarkup) + bot.sendMessage(chat_id, "发给我一条命令以执行", reply_markup=stopmarkup) shellexecution.append(chat_id) elif msg['text'] == "/setmem" and chat_id not in settingmemth: bot.sendChatAction(chat_id, 'typing') settingmemth.append(chat_id) - bot.sendMessage(chat_id, "Send me a new memory threshold to monitor?", reply_markup=stopmarkup) + bot.sendMessage(chat_id, "发给我一个新的内存占用告警阈值?", reply_markup=stopmarkup) elif chat_id in settingmemth: bot.sendChatAction(chat_id, 'typing') try: global memorythreshold memorythreshold = int(msg['text']) if memorythreshold < 100: - bot.sendMessage(chat_id, "All set!") + bot.sendMessage(chat_id, "整好了!") clearall(chat_id) else: 1/0 except: - bot.sendMessage(chat_id, "Please send a proper numeric value below 100.") + bot.sendMessage(chat_id, "都说了要小于100啊") elif chat_id in shellexecution: bot.sendChatAction(chat_id, 'typing') @@ -151,7 +159,7 @@ def on_chat_message(self, msg): if output != b'': bot.sendMessage(chat_id, output, disable_web_page_preview=True) else: - bot.sendMessage(chat_id, "No output.", disable_web_page_preview=True) + bot.sendMessage(chat_id, "没有输出", disable_web_page_preview=True) elif msg['text'] == '/memgraph': bot.sendChatAction(chat_id, 'typing') tmperiod = "Last %.2f hours" % ((datetime.now() - graphstart).total_seconds() / 3600) @@ -184,11 +192,11 @@ def on_chat_message(self, msg): memlist.append(mempercent) memfree = memck.available / 1000000 if mempercent > memorythreshold: - memavail = "Available memory: %.2f GB" % (memck.available / 1000000000) + memavail = "可用内存: %.2f GB" % (memck.available / 1000000000) graphend = datetime.now() - tmperiod = "Last %.2f hours" % ((graphend - graphstart).total_seconds() / 3600) + tmperiod = "近 %.2f 小时" % ((graphend - graphstart).total_seconds() / 3600) for adminid in adminchatid: - bot.sendMessage(adminid, "CRITICAL! LOW MEMORY!\n" + memavail) + bot.sendMessage(adminid, "换个大内存服务器吧\n" + memavail) bot.sendPhoto(adminid, plotmemgraph(memlist, xaxis, tmperiod)) time.sleep(10) # 10 seconds tr += 10 diff --git a/tokens.py_example b/tokens.py_example index c97a832..33125cf 100644 --- a/tokens.py_example +++ b/tokens.py_example @@ -1,5 +1,7 @@ # A token you get from the Telegram's botfather +# 这边填入从@botfather 处取得的token telegrambot = '9999999:6666aaaaaa666666a6aaa' # A chat_id of your client +# 这边填入管理员的chat_id adminchatid = [99999999] \ No newline at end of file