diff --git a/README.md b/README.md
index 004d24a..9c0233f 100644
--- a/README.md
+++ b/README.md
@@ -1,89 +1,63 @@
-# Server Manager Bot
+# SERVER MANAGER BOT
+Команды и возможности бота:
-A Telegram Bot:
+| Команда | Описание |
+| ------ | ------ |
+| `/stats` | дает обобщенную статистику о памяти \ диске \ процессах, а также общую нагрузку за определнный период времени |
+| `/shell` | позволяет использовать бот в режиме Shell |
+| `/memgraph` | строит график использования памяти за прошедший период |
+| `/setmem` | возможность установить порог оперативной памяти (%) для мониторинга |
+| `/setpoll` | интервал опроса в секундах (выше 10) |
-* 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
+------------
+**Как это работает**: [Смотреть GIF](https://i.13.wf/2019/08/17/1566074720-2541.gif)
+
-Example summary: [Gif](http://i.imgur.com/AhCvy9W.gifv)
+**Пример графика**:
-
+
+------------
-Example shell command output as a message from the bot:
+## Установка
-
+```sh
+$ git https://github.com/vladios13/ServerStatsBot.git
+$ cd ServerStatsBot
+$ sudo pip3 install -r requirements.txt
+```
+* Все ключи и токены сохраняйте в `tokens.py`.
+* Получить токен для бота можно в [Bot Father](https://t.me/BotFather)
+* В этот файл поместите строковую переменную `telegrambot` токен вашего бота.
+* Пример: `telegrambot = "000000000:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"`
+Вы должны установить переменную. `adminchatid` в `tokens.py`. Вы так же можете указать несколько пользователей.
+**Пример**:
+* `adminchatid = [443355]`
+* `adminchatid = [443355, 55667788, 99884433]`
-Example graph sent by bot: [Gif](http://i.imgur.com/anX7rJR.gifv)
-
-
-
-# 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:
- * `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)
-* [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
-
-`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
+Выполните: `python3 servstatsbot.py`
-## Setting an admin
+------------
-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:
+## Запуск в режиме "daemon"
-* `adminchatid = [443355]`
-* `adminchatid = [443355, 55667788, 99884433]`
+* Вся нужная информация находится в: `servstatsbot.conf`
+* Откройте его и отредактируйте путь, как указано в комментариях к нему.
+* Поместите файл в папку `/etc/init/`
+* Запустите как "daemon" : `start servstatsbot`
+ * Используйте `start|stop|restart`
+ * Если произойдет сбой, он будет автоматически перезапущен.
+ * Он также заработает после перезагрузки.
+------------
+# Разработчики бота
-I will reimplement this differently later.
-
-
-# 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:)
-
-
-# Other bot development
-
-## Alfred
+### Alfred - разрботчик
[http://alfredthebot.com](http://alfredthebot.com)
-
-
- GB
+### vladios13 - локализация и доработка 🌚
+[Blog vladios13](http://blog.vladios13.com)
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..bc12e76
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,3 @@
+psutil
+telepot
+matplotlib
\ No newline at end of file
diff --git a/servstatsbot.py b/servstatsbot.py
index 95c1ffc..c3226fa 100644
--- a/servstatsbot.py
+++ b/servstatsbot.py
@@ -1,3 +1,5 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
from tokens import *
import matplotlib
matplotlib.use("Agg") # has to be before any other matplotlibs imports to set a "headless" backend
@@ -12,14 +14,14 @@
# import threading
# import random
import telepot
-# from telepot.namedtuple import ReplyKeyboardMarkup, KeyboardButton, ReplyKeyboardHide, ForceReply
+from telepot.namedtuple import ReplyKeyboardMarkup, KeyboardButton
# from telepot.namedtuple import InlineKeyboardMarkup, InlineKeyboardButton
# from telepot.namedtuple import InlineQueryResultArticle, InlineQueryResultPhoto, InputTextMessageContent
-memorythreshold = 85 # If memory usage more this %
-poll = 300 # seconds
+memorythreshold = 85 # Если потребляется больше памяти, то этот % равен:
+poll = 300 # значения в секундах
shellexecution = []
timelist = []
@@ -29,7 +31,8 @@
setpolling = []
graphstart = datetime.now()
-stopmarkup = {'keyboard': [['Stop']]}
+stopmarkup = ReplyKeyboardMarkup(keyboard=[[KeyboardButton(text="Stop Shell")]],resize_keyboard=True)
+# stopmarkup = {'keyboard': [['Stop']]}
hide_keyboard = {'hide_keyboard': True}
def clearall(chat_id):
@@ -44,9 +47,9 @@ def plotmemgraph(memlist, xaxis, tmperiod):
# print(memlist)
# print(xaxis)
plt.xlabel(tmperiod)
- plt.ylabel('% Used')
- plt.title('Memory Usage Graph')
- plt.text(0.1*len(xaxis), memorythreshold+2, 'Threshold: '+str(memorythreshold)+ ' %')
+ plt.ylabel('% использовано')
+ plt.title('График использования ОЗУ')
+ plt.text(0.1*len(xaxis), memorythreshold+2, 'Порог: '+str(memorythreshold)+ ' %')
memthresholdarr = []
for xas in xaxis:
memthresholdarr.append(memorythreshold)
@@ -54,7 +57,7 @@ def plotmemgraph(memlist, xaxis, tmperiod):
plt.axis([0, len(xaxis)-1, 0, 100])
plt.savefig('/tmp/graph.png')
plt.close()
- f = open('/tmp/graph.png', 'rb') # some file on local disk
+ f = open('/tmp/graph.png', 'rb') # файл изображние на локальном диске
return f
@@ -67,20 +70,30 @@ def __init__(self, *args, **kwargs):
def on_chat_message(self, msg):
content_type, chat_type, chat_id = telepot.glance(msg)
# Do your stuff according to `content_type` ...
- print("Your chat_id:" + str(chat_id)) # this will tell you your chat_id
- if chat_id in adminchatid: # Store adminchatid variable in tokens.py
+ print("Ваш chat_id:" + str(chat_id)) # узнать chat_id
+ if chat_id in adminchatid: # Переменная adminchatid хранится в tokens.py
if content_type == 'text':
if msg['text'] == '/stats' and chat_id not in shellexecution:
bot.sendChatAction(chat_id, 'typing')
memory = psutil.virtual_memory()
disk = psutil.disk_usage('/')
+ cpuget = psutil.getloadavg()
+ сpu_countF = psutil.cpu_count(logical=False)
+ сpu_countL = psutil.cpu_count(logical=True)
+ cpufr = psutil.cpu_freq(percpu=False)
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) + " %"
+ cpuget = "Средняя нагрузка CPU: " + str(cpuget)
+ cpufr = "Текущая частота CPU: " + str(cpufr.current) + "Mhz"
+ сpu_countF = "Физических ядер: " + str(сpu_countF)
+ сpu_countL = "Логических ядер: " + str(сpu_countL)
+ timedif = "Сервер работает уже: %.1f часов" % (((now - boottime).total_seconds()) / 3600)
+ memtotal = "Всего ОЗУ: %.2f GB " % (memory.total / 1000000000)
+ memavail = "Свободно ОЗУ: %.2f GB" % (memory.available / 1000000000)
+ memuseperc = "Используется ОЗУ: " + str(memory.percent) + " %"
+ diskused = "Использовано HDD: " + str(disk.percent) + " %"
+ pidsinf = "Текущие процессы:"
+
pids = psutil.pids()
pidsreply = ''
procs = {}
@@ -94,24 +107,29 @@ def on_chat_message(self, msg):
else:
procs[p.name()] = pmem
except:
- print("Hm")
+ print("ХМ?")
sortedprocs = sorted(procs.items(), key=operator.itemgetter(1), reverse=True)
for proc in sortedprocs:
pidsreply += proc[0] + " " + ("%.2f" % proc[1]) + " %\n"
reply = timedif + "\n" + \
+ cpuget + "\n" + \
+ cpufr + "\n" + \
memtotal + "\n" + \
+ сpu_countF + "\n" + \
+ сpu_countL + "\n" + \
memavail + "\n" + \
memuseperc + "\n" + \
diskused + "\n\n" + \
+ pidsinf + "\n" + \
pidsreply
- bot.sendMessage(chat_id, reply, disable_web_page_preview=True)
+ bot.sendMessage(chat_id, reply, disable_web_page_preview=True, parse_mode='HTML')
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:
@@ -123,26 +141,26 @@ def on_chat_message(self, msg):
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, "Отправьте мне Shell-комманду", 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,14 +169,12 @@ 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)
+ bot.sendChatAction(chat_id, 'upload_photo')
+ tmperiod = "За %.2f часа" % ((datetime.now() - graphstart).total_seconds() / 3600)
bot.sendPhoto(chat_id, plotmemgraph(memlist, xaxis, tmperiod))
-
-
TOKEN = telegrambot
bot = YourBot(TOKEN)
@@ -184,11 +200,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..da53b3a 100644
--- a/tokens.py_example
+++ b/tokens.py_example
@@ -1,5 +1,4 @@
-# A token you get from the Telegram's botfather
+# Токен бота
telegrambot = '9999999:6666aaaaaa666666a6aaa'
-
-# A chat_id of your client
+# Введите chat_id канала/группы/пользователя. Можно использовать несколько значений, подробнее в readme.md
adminchatid = [99999999]
\ No newline at end of file