【开源软件】服务器状态监控通知平台

这篇具有很好参考价值的文章主要介绍了【开源软件】服务器状态监控通知平台。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

声明:
  本文仅以学习交流为目的分享自己的开发成果,希望为更多人提供开发设计的思路,还请善待笔者的开发成果。有任何问题欢迎在文章下方留言或私信,也欢迎评论或私信指教,和大家共同进步!

1. Server Monitor Platform 简介

  • 开发语言: C、C++
  • 开发平台: Linux、Windows
  • 开发工具: Vim、Qt Creator
  • 应用平台: 跨平台使用

【开源软件】服务器状态监控通知平台

  本文将介绍笔者开发的一套服务器状态监控通知软件 (Server Monitor Platform),该软件功能包含监测服务器 CPU 温度和内存使用率(目前只监测这两个),该软件在服务器端分布式部署服务程序,以主动监测的方式获取服务器状态信息。用户将在每日 06点、12点、19点、23点整收到以邮件方式通知的被监测服务器实时状态。当服务器存在风险时(服务器温度超过 65℃),用户将会收到及时通知邮件,用户即时将视情况处理。若用户超时未能处理,本软件将会在风险等级达到最高时强制服务器关机,同时用户将收到风险解除通知,从而保障服务器安全。

2. 软件的整体分布架构介绍

  软件分为两个部分服务端和监控平台(也可以理解为客户端),服务端程序主体采用 C 语言开发,部署在被监测服务器上,监控平台主体采用 C++ 开发,运行在带有图形界面的操作系统上 (WindowsMacOSLinux-Desktop)。服务端与监控平台采用 TCP/IP 协议连接。

【开源软件】服务器状态监控通知平台

  在建立好握手后,软件以主动的方式监测服务器状态。监控平台主动向服务端发送握手信息,服务端在接收到握手信号后,初次将会发送当前机器的 CPU 核心数以及内存的总大小。之后服务端将以 2s 为时间单位发送自己当前机器的状态信息给监控平台。(状态信息包含:当前使用内存大小,当前每个 CPU 核心温度值)

【开源软件】服务器状态监控通知平台
  监控平台以分布式采集的方式获取服务器状态信息,运行在带有图形界面操作系统的监控平台将每隔 2s 接收到来自服务端的状态信息,经过处理后将实时显示在显示界面上。并且在指定时间以邮件的方式向用户们发送服务器状态信息,当服务器达到预设的风险等级时,将立刻向用户们发送及时同时邮件,并告知风险等级系数,当风险等级系数达到最高时,监测平台将在超过操作时间后强制时服务器关机。
【开源软件】服务器状态监控通知平台

3. 服务端程序

  服务端代码比较少就直接贴在本文中了,服务端程序可以简单的看作一个 TCP 的服务器,使用的是固定端口 21031,当然你也可以自由修改。服务端的主要功能是采集当前 CPU 温度和当前使用的内存大小。

  采集温度功能可使用现有工具 lm-sensors 直接获取,然后对其输出的结果进行处理即可;当前的内存使用大小可直接通过读取 /proc/meminfo 文件获得。握手等信号均采用自协商字段。整体来说服务端的实现较为简单。
【开源软件】服务器状态监控通知平台

[注]:lm-sensors 是运行在 Linux 的一款温度采集软件,直接安装即可 yum install lm-sensors,接着执行 sensors-detect 检测可使用的传感器。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
#include <error.h>
#include <errno.h>

#define TCP_IP4     ("10.1.0.149")
#define TCP_PORT    (21031)
#define DATA_LENGTH (1024)
#define TEMP_LENGTH (15)

#define GETTEMP_CMD     ("sensors")
#define GETCORENUM_CMD  ("grep 'core id' /proc/cpuinfo | sort -u | wc -l")
#define GETMEM_TOTAL_CMD             ("cat /proc/meminfo | grep MemTotal")
#define GETMEM_AVAILABLE_CMD         ("cat /proc/meminfo | grep MemAvailable")

#define CORE_STR        ("Core")

#define INITDATA_CMD    ("initdata")
#define ACKDATA_CMD     ("ackdata")
#define POWERDOWN_CMD   ("poweroff")

long unsigned int get_memsize(char * cmd)
{
        long unsigned int mem = 0;
        FILE * fp = NULL;
        char cmdout[DATA_LENGTH] = {0};

        printf("Get Mem Size.\n");

        fp = popen(cmd, "r");
        if (fp == NULL) {
                perror("popen error.\n");

                return -1;
        }

        while (fgets(cmdout, sizeof(cmdout), fp) != NULL) {
                printf("%s", cmdout);
        }
        pclose(fp);

        int m_s = 0, m_e = 0;

        for (int i = 8; i < strlen(cmdout); i++) {
                if (cmdout[i] == ' ' && (cmdout[i + 1] >= '0' && cmdout[i + 1] <= '9')) {
                        m_s = i + 1;
                        continue;
                }
                if (cmdout[i] == ' ' && (cmdout[i - 1] >= '0' && cmdout[i - 1] <= '9') && m_s > 0) {
                        m_e = i;
                        break;
                }
        }

        int i = 0;
        printf("%d:%d\n", m_s, m_e);
        for ( ; m_s < m_e; m_s++) {
                cmdout[i++] = cmdout[m_s];
        }
        cmdout[i] = '\0';

        printf("> %s\n", cmdout);

        for (i = 0; i < strlen(cmdout); i++) {
                mem *= 10;
                mem += (cmdout[i] - '0');
        }

        return mem;
}

int get_corenumber(void)
{
        int core_num = 0;
        FILE * fp = NULL;
        char cmdout[DATA_LENGTH] = {0};

        printf("Get CPU Core number.\n");

        fp = popen(GETCORENUM_CMD, "r");
        if (fp == NULL) {
                perror("popen error.\n");

                return -1;
        }

        while (fgets(cmdout, sizeof(cmdout), fp) != NULL) {
                printf("%s", cmdout);
        }
        pclose(fp);

        core_num = atoi(cmdout);

        printf("num:%d\n", core_num);

        return core_num;
}

char ** get_coretemp_fromcmdout(char * cmdout, char ** core_list, int core_num)
{
        int i = 0, t_s = 0, t_e = 0, list_num = 0;

        if (0 == strncmp(CORE_STR, cmdout, strlen(CORE_STR))) {
                for (i = 0; i < strlen(cmdout); i++) {
                        if (cmdout[i] == ':') {
                                i += 1;
                                for ( ; i < strlen(cmdout); i++) {
                                        if (0 == t_s && cmdout[i] != ' ') {
                                                t_s = i + 1;
                                        }
                                        if (t_s && cmdout[i] == ' ') {
                                                t_e = i - 3;
                                                break;
                                        }
                                }
                                break;

                        }
                        continue;
                }

                // find the first null char*
                for (i = 0; i < core_num; i++) {
                        if (0 == strlen(core_list[i])) {
                                list_num = i;
                                break;
                        }
                }

                for (i = 0; t_s < t_e; i++) {
                        core_list[list_num][i] = cmdout[t_s++];
                }
                core_list[list_num][i] = '\0';
        }

        return core_list;
}

char ** get_coretemp(char ** core_list, int num)
{
        char cmdout[DATA_LENGTH] = {0};
        FILE * fp = NULL;
        int core_num = num;
        printf("Core number: %d\n", core_num);

        printf("Get Temperature.\n");

        fp = popen(GETTEMP_CMD, "r");
        if (fp == NULL) {
                perror("popen error.\n");

                return NULL;
        }


        printf("core_list size: %d\n", sizeof(core_list[0]));
        int i = 0;

        while (fgets(cmdout, sizeof(cmdout), fp) != NULL) {
                printf("[%d]>%s", i++, cmdout);
                get_coretemp_fromcmdout(cmdout, core_list, core_num);
        }

        pclose(fp);

        printf("-----------------------------------\n");

        return core_list;
}

void clear_corelist_data(char ** core_list, int core_num)
{
        for (int i = 0; i < core_num; i++) {
                core_list[i][0] = '\0';
        }
}

void free_corelist(char ** core_list, int core_num)
{

        for (int i = 0; i < core_num; i++) {
                if (core_list[i] != NULL) {
                        free(core_list[i]);
                        core_list[i] = NULL;
                }
        }

        if (core_list != NULL) {
                free(core_list);
        }


        return ;
}

int main(int argc, const char * argv[])
{
    int ret = 0;
    int connect_fd = 0;
    long unsigned int memtotal = 0, memavailable = 0, memused = 0;
    double memused_rate = 0;
    int core_num = get_corenumber();
    char **core_list = (char **)malloc(core_num * sizeof(char *));
    memset(core_list, 0, core_num * sizeof(char *));

    for (int i = 0; i < core_num; i++) {
            core_list[i] = (char *)malloc(sizeof(char) * TEMP_LENGTH);
    }
    core_list = get_coretemp(core_list, core_num);

    for (int i = 0; i < core_num; i++) {
            printf("[%d]:%s\n", i, core_list[i]);
    }

    int socket_fd = socket(PF_INET, SOCK_STREAM, 0);
    if (socket_fd < 0) {
        perror("create socket error!");
        return -1;
    }

    printf ("Create socket successful!\n");

    // Bind
    struct sockaddr_in server_addr = {0};
    server_addr.sin_family = PF_INET;   // set protocol: Internet
    server_addr.sin_port = htons(TCP_PORT);
    server_addr.sin_addr.s_addr = inet_addr(TCP_IP4);

    ret = bind(socket_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));

    if (ret < 0) {
        perror("bind error!\n");
        close(socket_fd);

        return -1;
    }

    printf("Bind successful!\n");

    ret = listen(socket_fd, 1);
    if (ret < 0) {
        perror("listen error!\n");
        close(socket_fd);

        return -1;
    }

accept:
    while (1) {
            printf("Linstening: \n");

            // Accept
            connect_fd = accept(socket_fd, NULL, NULL);
            if (connect_fd < 0) {
                    perror("accept error!\n");
                    close(socket_fd);

                    return -1;
            }

            printf("Accept successful!\n");

            // Recv
            char buf[DATA_LENGTH] = {0};

            while (1) {

                    memtotal = get_memsize(GETMEM_TOTAL_CMD);
                    memavailable = get_memsize(GETMEM_AVAILABLE_CMD);
                    memused = memtotal - memavailable;
                    memused_rate = memused * 1000 / memtotal;
                    memused_rate /= 10;

                    ret = recv(connect_fd, buf, sizeof(buf), 0);
                    if (ret <= 0) {
                            perror("recv error!\n");

                            goto accept;
                            continue;
                    }

                    buf[ret] = '\0';
                    if (ret) {
                            printf("[%d]Recv: %s\n", ret, buf);
                    }

                    if (strcmp(buf, INITDATA_CMD) == 0) {
                            memset(buf, 0, sizeof(buf));
                            sprintf(buf, "%d\n%d\n", core_num, memtotal / 1024 / 1000);
                            ret = send(connect_fd, buf, strlen(buf), 0);
                            if (ret == -1) {
                                    goto accept;
                            }
                            //sleep(1);
                            int t = 0;
                            // set core temp data
                            memset(buf, 0, sizeof(buf));
                            for (int i = 0; i < core_num; i++) {
                                    for (int z = 0; z < strlen(core_list[i]); z++) {
                                            buf[t++] = core_list[i][z];
                                    }
                                    buf[t++] = '\n';
                                    //sprintf(buf, "%s\n", core_list[i]);
                            }
                            sprintf(buf, "%s%.2lf\n", buf, memused_rate);
                            send(connect_fd, buf, strlen(buf), MSG_NOSIGNAL);
                            if (ret == -1 && errno == EPIPE) {
                                    goto accept;
                            }
                            continue;
                    }
                    if (strcmp(buf, "quit") == 0) {
                            break;
                    }
                    if (strcmp(buf, ACKDATA_CMD) == 0) {
                            printf("get new temp\n");
                            clear_corelist_data(core_list, core_num);
                            get_coretemp(core_list, core_num);
                            for (int i = 0; i < core_num; i++) {
                                    printf("%s\n", core_list[i]);
                            }

                            int t = 0;
                            // 将每个核心温度值添加入 buf 中
                            memset(buf, 0, sizeof(buf));
                            for (int i = 0; i < core_num; i++) {
                                    for (int z = 0; z < strlen(core_list[i]); z++) {
                                            buf[t++] = core_list[i][z];
                                    }
                                    buf[t++] = '\n';
                                    //sprintf(buf, "%s\n", core_list[i]);
                            }
                            // 在 buf 后添加内存使用率,单位 %
                            sprintf(buf, "%s%.2lf\n", buf, memused_rate);
                            // 通过 socket 发送
                            send(connect_fd, buf, strlen(buf), MSG_NOSIGNAL);
                            if (ret == -1 && errno == EPIPE) {
                                    goto accept;
                            }

                    }

                    if (strcmp(buf, POWERDOWN_CMD) == 0) {
                            printf("为确保系统安全,将在 5 秒后自动关机。\n");
                            sleep(5);
                            system("poweroff");
                    }
                    memset(buf, 0, sizeof(buf));

                    sleep(2);
                    continue;
            }
    }

    close(connect_fd);
    close(socket_fd);

    free_corelist(core_list, core_num);

    return 0;

}

  由于服务端需要运行在后台,因此另外创建一个进程将其以守护进程的方式启动。

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>

int main(int argc, char * argv[])
{
        pid_t pid = fork();

        if (pid < 0) {
                perror("fork error.\n");

                return -1;
        } else if (pid > 0) {
                exit(0);
        } else {
                printf("Start Monitor_IM Service...\n");
                system("monitor_server");
                printf("Stop Monitor_IM Service...\n");
        }

        return 0;
}

4. 监控平台软件

  监控平台软件代码虽然不是特别多,但还是有一些代码量的,至少不适合直接贴在文章中,因此笔者将其上传到各大 git 仓库,读者们可以通过以下几个可以访问的 git 仓库直接下载就好。

GitHub: https://github.com/ImagineMiracle-wxn/Server-Monitor-Platform
Gitee: https://gitee.com/imaginemiracle_wxn_1/server-monitor-platform
GitCode: https://gitcode.net/qq_36393978/server-monitor-platform/-/tree/master
[注]:三个链接均无法打开,也可通过私信笔者获取。

4.1. 监控平台软件整体设计

  由于在代码中笔者添加了大量注释来帮助读者们阅读代码,在本文中笔者就简要的说明监控平台端的软件设计结构。笔者提供的源码目录如下图。

【开源软件】服务器状态监控通知平台
其中每个目录的内容如下:

  • Monitor_Server-v0.3: 服务端监控源码;
  • Server_Monitoring_Platform: 监控平台源码;
  • build😗 使用 Qt Creator 编译后生成的构建目录;
  • doc: 简单的描述文档;
  • object: 打包发布后的应用程序;
  • pic: 一些图片;

  下载好源码后,可以直接使用 Qt Creator 打开 Server_Monitoring_Platform/Server_Monitoring_Platform.pro 文件,笔者使用的是 Qt 6.4.3 MSVC2019_64bit 构建的工程,若你当前的 Qt 并不支持的话,删掉 Server_Monitoring_Platform/Server_Monitoring_Platform.pro.user 文件后,再重新打开即可。使用 Qt Createor 打开该工程后即可看到如下这样的源码列表。
【开源软件】服务器状态监控通知平台

File List:
typelist.h	    // 通用类型结构体和枚举定义在此
email_im.h		// 电子邮件功能类
about_im.h		// 关于界面类
emailconfigure.h			// 邮件配置界面类
monitorthread_im.h			// 监测线程头类
monitoringplatform_im.h		// 监测平台顶层类
email_im.cpp				// 电子邮件功能类实现
about_im.cpp				// 关于界面类实现
emailconfigure.cpp			// 邮件配置界面类实现
monitorthread_im.cpp		// 监测线程类实现
monitoringplarform_im.cpp	// 监测平台顶层实现
main.cpp		// 调用顶层类,显示顶层类界面

......		    // 其它源文件均为实现邮件功能

  其中,如果只是像快速掌握并使用起来的话,读者们只需要重点关注标记的这些文件及其对应的 .h 文件即可,若希望完全掌握那么需要将所有的源码都过一遍就好。
【开源软件】服务器状态监控通知平台

  上图简要描绘了软件整体的类设计结构,其中名为 MonitoringPlatform_IM 作为整个 App 的主类,由它来调度所有的功能,其中有两种重要的线程类型,一种是 TimeThread_IM,它的作用主要为实时的时间显示和计时功能,确保邮件发送时间的精确;另一个是 MonitorThread_IM,它的作用主要是异步监测每台服务器的状态(每一台服务器使用独立的线程来监测状态)。Email_IM 类是封装了邮件功能的顶层类,读者们想要使用邮件功能的话直接可调用该类的成员函数即可非常的方便。还有另外两个 UI 类,一个是 EmailConfigure 类是提供了一个邮件信息配置的界面,并将最终的配置提交给主类;另一个是 About 类,其功能主要是用于展示软件的基本信息。

5. Server Monitor Platform 部署步骤

  上文介绍了该软件由两部分组成,一个是运行在服务器上的服务端程序,另一个则是运行在其它平台的监测软件,接下来看看该如何部署这些软件。

5.1. 在服务器上部署服务端程序并打开

5.1.1. 安装 lm_sensors

yum install lm_sensors

首先安装 lm_sensors 工具,由于笔者已经安装过了,因此这里提示没有做任何操作。
【开源软件】服务器状态监控通知平台
接着执行 sensors-detect,监测当前的传感器类型,看到有出现 Success 字样则说明匹配成功。

【开源软件】服务器状态监控通知平台

5.1.2. 部署服务端软件

在工程的 Monitor_Server-v0.3/monitor_server/ 目录下有如下几个文件。

【开源软件】服务器状态监控通知平台
这里需要打开 monitor_server_v0.3.c,将其中的 IP 地址修改为服务器的 IP 地址。

【开源软件】服务器状态监控通知平台

修改完后编译代码,并放置入 /bin 目录下:

gcc monitor_server_v0.3.c -o monitor_server
cp monitor_server monitor_service /bin

  由于该程序是指定端口连接,因此需要在防火墙上开放该端口,或者直接关闭防火墙(并不建议这样做,毕竟是服务器):

# 开放防火墙 21031 端口
firewall-cmd --permanent --add-port=21031/tcp
# 重新加载防火墙
systemctl reload firewalld
# 查看防火墙开放的端口号
firewall-cmd --list-port

启动服务端程序:

monitor_service

【开源软件】服务器状态监控通知平台
看到 Linstening: 则表示启动成功,由于这样会一直输出 Log 信息,直接关闭该 ssh 连接即可。

5.2. 在图形界面操作系统上打开监控平台软件

5.2.1. 使用 Qt Creator 打开工程

  用 Qt Creator 打开 Server_Monitoring_Platform 目录下的 Server_Monitoring_Platform.pro 文件,找到 monitoringplatform_im.cpp 文件,在下图地方处修改添加所要监测的服务器 IP、使用人、管理人、服务器名。

【开源软件】服务器状态监控通知平台

5.2.2. 编译并发布

  修改好代码后,使用 Qt Creator 编译出 Release 版本的可执行程序,再使用 Qt 自带的对应编译器版本的终端,用 windeployqt 命令将其所依赖的所有库文件都搜集完整,再使用 Enigma Virtual Box 将其打包,生成一个可以独立运行的可执行文件。在工程中,笔者并没有将服务器信息的录入单独写成模块在运行时录入,这一点各位读者们可以自己动手实现该功能。

5.2.3. 运行并设置监控平台

  本文以 Windows 为例,其它操作系统一样。这里使用笔者之前编译发布好的程序,打开工程目录的 object 目录。

【开源软件】服务器状态监控通知平台
直接双击运行 IM Monitoring v1.4.1000 EDA版 可执行程序。

【开源软件】服务器状态监控通知平台
  打开可执行程序后立即看到的是各服务器的状态新信息,现在程序已经处于实时监控的状态,但要使用邮件服务,还需要设置一番。

<1> 依次点击 设置 > Email设置

【开源软件】服务器状态监控通知平台
<2> 根据提示填写信息,发送所使用的邮箱邮箱密码邮件发送使用的名字邮箱类型收件人邮箱地址

【开源软件】服务器状态监控通知平台

<3> 填写完成后点击 提交,即可设置成功并退出到主界面。需要注意的是这里笔者并没有实现邮箱密码校验功能,也就是说,加入你输入错误的密码,在实际看到的现象是并不会收到邮件,不会提示任何错误信息。目前笔者仅添加了两种发送邮箱的类型,一种是微软家的 Outlook 邮箱,一种是腾讯家的企业微信邮箱。

这里有一个 初次通知的选项,用于设置是否需要向所有用户发送软件介绍。

【开源软件】服务器状态监控通知平台
<4> 提交完成后,到主界面点击左下角的 邮件通知,即表示开启邮件服务。

【开源软件】服务器状态监控通知平台

若在邮件设置中勾选了 初次通知,则在点击 邮件通知 的同时会向所有收件人发送软件介绍的邮件。如下:

【开源软件】服务器状态监控通知平台

  倘若没有勾选 初次通知,则只会给邮件的发送人发送软件开启提醒邮件,用来提示使用人软件的邮件服务已正常运转。如下:

【开源软件】服务器状态监控通知平台
  在菜单中还有其它功能,工具 > 重连,该功能是在服务器掉线后重启并启动服务端程序后,点击此按钮则会重连所有断开连接的服务器并恢复监控显示功能。

【开源软件】服务器状态监控通知平台
  帮助 > 关于,点击则会弹出软件的基本信息介绍。

【开源软件】服务器状态监控通知平台

6. 邮件功能介绍

邮件通知功能有以下三种:

  • 服务器日常通知: 用于在每天的指定时间定时汇报服务器当前状态;
  • 紧急通知邮件: 当服务器温度超过 65℃ 时即刻发送邮件通知管理人和所有收件人,此时风险等级为 Lv:1。当服务器持续温度超过 65℃ 半个小时后,连续发送两次 “紧急通知邮件” 此时风险等级为 Lv:2,每次间隔 5 min,若在此期间没有管理人员操作使得机器温度降低,那么在总共收到 3 封紧急通知邮件,软件将会强制使服务器关机;
  • 风险解除通知邮件: 当风险等级达到 Lv:2 时仍无人处理,软件会强制服务器关机,在执行完关机动作后会向收件人群发送 “风险解除,高温机器已关机” 的邮件。

6.1. 服务器日常通知示例邮件

  该软件会在每天的指定时间向邮件接收人发送服务器的实时状态,以及当日的最高温度,其效果如下。

【开源软件】服务器状态监控通知平台

6.2. 服务器高温测试示例

  在此例演示时,笔者将服务器的预警温度设为 25℃,以便快速达到预警温度值。以服务器 Server30-122 为例,当其第一次温度超过 25℃ 时,系统会向收件人发送 “紧急通知邮件”,此时风险等级为 Lv:1

【开源软件】服务器状态监控通知平台
  持续 25℃ 以上运行半小时以后继续再次发送 “紧急通知邮件”,此时风险等级为 Lv:2

【开源软件】服务器状态监控通知平台

  当第接收到第二封风险等级为 Lv:2“紧急通知邮件” 时,之后系统将执行强制关机指令,稍后将会收到 “风险解除通知”

【开源软件】服务器状态监控通知平台

7. 补充

  事实上在代码中笔者已经完善了邮件发送的文字,目前发送的邮件中,温度若低于预警值则会以 绿色 显示,若高于预警值则会以 红色 显示,若该服务器以关机则以不显眼的 淡紫色 显示。

#完

觉得这篇文章对你有帮助的话,就留下一个赞吧^v^*
请尊重作者,转载还请注明出处!感谢配合~
[作者]: Imagine Miracle
[版权]: 本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
[本文链接]: https://blog.csdn.net/qq_36393978/article/details/126369492文章来源地址https://www.toymoban.com/news/detail-430877.html

到了这里,关于【开源软件】服务器状态监控通知平台的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 可以与宝塔共存的一个 “魔法” 服务器状态监控应用 ——xui

    之前有一期我们搭建了一个服务器监控,颜值非常不错,这期我们再来搭建一个 “特殊” 的服务器监控 ——XUI。 不仅可以监控服务器的数据,还可以干一些高级的,大家感兴趣的事情。 重要的是,它可以和宝塔面板共存! 一个非常直观,简洁大气的监控面板。 系统状态监

    2024年02月02日
    浏览(49)
  • 开源视频监控服务器Shinobi

    什么是 Shinobi ? Shinobi 是用 Node.JS 编写的开源 CCTV 解决方案。采用多帐户系统、 WebSocket Streams 和直接保存到 MP4 的设计。 Shinobi 提供了一个基于 Web 的用户界面,使用户可以通过浏览器来查看和管理监控视频, Shinobi 支持多个品牌的摄像头和网络视频流,并提供了广泛的定制选

    2024年02月07日
    浏览(40)
  • 【系统工具】开源服务器监控工具WGCLOUD初体验

    经常看到服务器上传下载流量一直在跑,也不知道是啥软件在偷偷联网~~~官网地址:www.wgstart.com,个人使用是免费的。 \\\"WGCLOUD支持主机各种指标监测(cpu使用率,cpu温度,内存使用率,磁盘容量空间,磁盘IO,硬盘SMART健康状态,系统负载,连接数量,网卡流量,硬件系统信息

    2024年02月12日
    浏览(44)
  • Linux C/C++ 多线程TCP/UDP服务器 (监控系统状态)

    Linux环境中实现并发TCP/IP服务器。多线程在解决方案中提供了并发性。由于并发性,它允许多个客户端同时连接到服务器并与服务器交互。 Linux多线程编程概述 许多应用程序同时处理多项杂务。服务器应用程序处理并发客户端;交互式应用程序通常在处理后台计算时处理用户

    2024年02月07日
    浏览(39)
  • 哪吒监控:开源、轻量、易用的服务器监控、运维工具(内附主题美化代码)

    哪吒监控是一款开源、轻量、易用的服务器监控、运维工具,为用户提供了一系列强大的功能和便捷的操作方式。 一键安装:支持一键脚本安装面板和监控服务,适用于Linux、Windows、MacOS、OpenWRT等主流系统,让您轻松上手。 实时监控:能够同时监控多个服务器的系统状态,

    2024年03月10日
    浏览(122)
  • 适用于动态 IT 环境的服务器流量监控软件

    服务器在网络性能中起着至关重要的作用,这意味着保持其最佳容量至关重要。企业需要将 AI、ML 和云技术融入其 IT 中,从而提供充分的敏捷性、安全性和灵活性,在这方面,服务器流量监控已成为当务之急。通过定期监控通信、跟踪流量上下文和识别瓶颈,管理员可以了解

    2024年02月02日
    浏览(41)
  • 免费开源服务器资源监控系统grafana+prometheus+node_exporter

    有项目做测试的时候需要查询服务器资源利用情况,自己又没写相应的模块,此时就需要一套好用的资源监控系统,,咨询了运维人员给推荐了一套,装完后真的很好用。 就是grafana+prometheus+ node_exporter(linux)或者windows_exporter(wins) 具体介绍不多说: 1、grafana是对数据做展

    2024年02月12日
    浏览(49)
  • 性能测试平台 - 集分布式压测、服务器资源监控、远程连接Linux于一体的平台

    前情提要:   网上搜了一下开源性能测试平台或全链路压测平台,只找到了一个stressTestSystem,其他的都是一些垃圾公司的广告。至于使用体验,stressTestSystem没用过,不好评价。本文开源的性能测试平台,在实现功能的前提下,极大地考虑到了使用体验,功能“强大”且部

    2024年02月10日
    浏览(52)
  • Jetson硬件平台状态查看工具jtop安装,服务器平台上可以通过nvtop工具来查看资源使用情况

    首先安装支持环境包(maybe…need) sudo apt-get install git cmake sudo apt-get install python3-dev sudo apt-get install libhdf5-serial-dev hdf5-tools sudo apt-get install libatlas-base-dev gfortran 安装 pip3 因为最终需要用 pip3 安装,所以这一步是不可缺少的。 sudo apt install python3-pip 安装 jtop sudo -H pip3 install -U jetso

    2023年04月23日
    浏览(56)
  • 部标JT808车辆定位监控平台单服务器13.6万接入压力测试记录(附源码)

    之前经常有人问平台能支持多少设备同时在线,由于事情多没时间做。最近刚好有机会做下压力测试。在不间断的连续压测三天,最终结果为13.6万TCP连接,30秒上报频率。 测试平台同时接入设备数量与并发处理能力。 一台主服务器用于部署车辆定位平台,是常见的8核16G内存

    2024年04月12日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包