ServerStatus

编辑 / blog / C/C++ / 发布于2021-10-20 / 更新于2023-03-16 / 阅读 252

服务器探针

使用的源码地址
- ServerStatus中文版
- ServerStatus-HostLoc

其中客户端和web主要在ServerStatus-HostLoc的基础上稍作修改,因为ServerStatus中文版中有月流量统计功能,所以使用它做服务端

原理

整个系统共包括三个部分:

  1. 客户端
  2. 服务器
  3. web

客户端

这个是运行在想要监控的各个服务器上的,主要功能是采集各个客户端(服务器)上的。运行状态,将这些内容发送给服务端。
因为这两个版本略有差别,所以我将客户端ip连接数的key值,修改成了load_1(在服务端这个key值应该接收到的内容是1分钟内的平均负载),然后将ip连接数获取位置的tcp6改为tcp(ipv6 or ipv4 ?)

服务端

服务端运行在你想要部署你的网站的那台服务器上,主要功能是接受客户端发送来的数据,生成json格式的数据,然后把这些数据放到web网站的文件夹内。
一台主机既可以做服务端又可以当客户端

web

这个就是我们能看到的监控页面了,这个其实是个没有后端的静态的页面,主要的动态效果靠前端js实现,主要功能是使用前端js解析服务端生成的放到文件夹内的json数据,然后在前端页面上生成可视化页面
这里我主要使用的ServerStatus-HostLoc的web页面,添加了个顶部图片,服务器信息只保留卡片的形式显示,在卡片上增加了月流量统计,
使用的时候将web服务器(nginx or caddy)的 root 设置为web文件夹的路径就好了,一般都放在 /home/wwwroot/xxx/

Telegram bot

自己主要加了自主获取服务器状态和内存占用超过90%自动给我发消息
库链接 python-telegram-bot

自主获取服务器状态

效果

def get_table(i):
    ss = PrettyTable()
    ss.border = False 
    ss.header = False 
    ss.add_column('',
        [  
            "节点名",
            "位置",
            "在线时间",
            "IP连接数",
            "网络 ↓|↑",
            "月流量 ↓|↑",
            "总流量 ↓|↑",
            "处理器",
            "内存",
            "内存",
            "交换分区",
            "交换分区",
            "硬盘",
            "硬盘"
        ],
    )
    if i["online4"] is False and i["online6"] is False:
        ss.add_column(
            "",
            [
                "%s" % i["name"],
                "%s" % i["location"],
                '-',
                '-',
                '-',
                '-',
                '-',
                '-',
                '-',
                '-',
                '-',
                '-',
                '-',
                '-'
            ]
        )
    else:
        ss.add_column(
            "",
            [
                "%s" % i["name"],
                "%s" % i["location"],
                "%s" % i["uptime"],
                "%s" % (i["load_1"]),
                "%.2fM|%.2fM" % (float(i["network_rx"]) / 1000 / 1000, float(i["network_tx"]) / 1000 / 1000),
                "%.2fG|%.2fG" % (float(i["last_network_in"]) / 1024 / 1024 / 1024, float(i["last_network_out"]) / 1024 / 1024 / 1024),
                "%.2fG|%.2fG" % (float(i["network_in"]) / 1024 / 1024 / 1024, float(i["network_out"]) / 1024 / 1024 / 1024),
                "%d%%" % (i["cpu"]),
                "%.2fG/%.2fG" % (float(i["memory_used"]) / 1024 / 1024, float(i["memory_total"]) / 1024 / 1024),
                "%d%%" % (float(i["memory_used"]) / i["memory_total"] * 100),
                "%.2fG/%.2fG" % (float(i["swap_used"]) / 1024 / 1024, float(i["swap_total"]) / 1024 / 1024),
                "%d%%" % (0 if i["swap_total"]==0 else float(i["swap_used"]) / i["swap_total"] * 100),
                "%.2fG/%.2fG" % (float(i["hdd_used"]) / 1024, float(i["hdd_total"]) / 1024),
                "%d%%" % (float(i["hdd_used"]) / i["hdd_total"] * 100),
            ]
        )
    return ss.get_string().replace(' ','  ')



def server_status(update: Update, context: CallbackContext) :
    if not validate(update):
        return 

    r = requests.get(
            url='http://ip:port/json/stats.json',
            headers={
                "User-Agent": "ServerStatus/20181203",
            }
        )
    jsonR = r.json()
    for i in jsonR["servers"]:
        update.message.reply_text('服务器信息\n\n'+get_table(i))

#命令设置
status_handler = CommandHandler('status', server_status)
dispatcher.add_handler(status_handler)

定时报警

def check_server_status(context: CallbackContext):
    r = requests.get(
            url='http://ip:port/json/stats.json',
            headers={
                "User-Agent": "ServerStatus/20181203",
            }
        )
    jsonR = r.json()
    for i in jsonR["servers"]:
        if i["online4"] is False and i["online6"] is False :
            context.bot.send_message(chat_id=user_id,text='服务器警报\n\n'+get_table(i))
        elif float(i["memory_used"]) / i["memory_total"] >0.9:
            context.bot.send_message(chat_id=user_id,text='服务器警报\n\n'+get_table(i))

#定时器设置
updater.job_queue.run_repeating(check_server_status, interval=1800, first=10)

最终效果 ServerStatus