From 1a84bdc1a35d46b6797229d8f3ffed16de31be36 Mon Sep 17 00:00:00 2001 From: amass <168062547@qq.com> Date: Sat, 9 Nov 2024 19:21:15 +0800 Subject: [PATCH] add network minitor. --- .gitea/workflows/deploy.yaml | 18 ++++++++++ Server/SystemUsage.cpp | 66 +++++++++++++++++++++++++++++++++++- Server/SystemUsage.h | 10 ++++++ 3 files changed, 93 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml index b60fbe3..60a6738 100755 --- a/.gitea/workflows/deploy.yaml +++ b/.gitea/workflows/deploy.yaml @@ -39,6 +39,24 @@ jobs: echo -n "提交消息: ${{ github.event.head_commit.message }}">> notify.tpl cat notify.tpl | envsubst | jq -sR . | xargs -0 -I {} curl -H "Content-Type: application/json" -X POST -d '{"type":"text","msg":{} }' https://amass.fun/notify - run: resources/build.sh build + - name: Copy files to server + uses: appleboy/scp-action@v0.1.3 + with: + host: ${{ vars.YUYUN_SERVER }} + username: ${{ vars.YUYUN_USER }} + password: ${{ secrets.SERVER_ROOT_PASSWORD }} + source: build/Server/HttpServer + target: /root/Server/HttpServer + - name: Restart server + uses: appleboy/ssh-action@v0.1.3 + with: + host: ${{ vars.YUYUN_SERVER }} + username: ${{ vars.YUYUN_USER }} + password: ${{ secrets.SERVER_ROOT_PASSWORD }} + script: | + pkill -f HttpServer || true + cp /root/Server/HttpServer /root/Server/HttpServer.bak + nohup /root/Server/HttpServer > /dev/null 2>&1 & - name: Notify-End if: ${{ always() }} run: | diff --git a/Server/SystemUsage.cpp b/Server/SystemUsage.cpp index dc40249..0753283 100644 --- a/Server/SystemUsage.cpp +++ b/Server/SystemUsage.cpp @@ -1,6 +1,11 @@ #include "SystemUsage.h" #include "BoostLog.h" +#include "DateTime.h" #include "NetworkUtility.h" +#include "ServiceManager.h" +#include +#include +#include #include #include #include @@ -15,7 +20,8 @@ SystemUsage::SystemUsage(boost::asio::io_context &ioContext, const std::string & } void SystemUsage::start() { - m_timer->expires_after(std::chrono::seconds(10)); + using namespace std::chrono; + m_timer->expires_after(seconds(10)); m_timer->async_wait([this](const boost::system::error_code &error) { if (error) { LOG(error) << error.message(); @@ -27,6 +33,35 @@ void SystemUsage::start() { publish("yuyun_disk_usage", static_cast(100.0f * diskUsage("/")), "%", "磁盘占用率"); m_lastCpuStats = currentCpuStats; + + m_networkStats.push_back(networkStats("eth0")); + while (m_networkStats.size() >= 2) { + constexpr auto SpeedInterval = seconds(60 * 15); + auto front = m_networkStats.front(); + auto back = m_networkStats.back(); + auto duration = duration_cast(back.time - front.time); + if (duration > SpeedInterval) { + m_networkStats.pop_front(); + } else { + constexpr auto gigabyte = 1024 * 1024 * 1024; + auto receiveGigabyte = static_cast(back.receiveBytes - front.receiveBytes) / gigabyte; + auto transmitGigabyte = static_cast(back.transmitBytes - front.transmitBytes) / gigabyte; + auto speed = (receiveGigabyte + transmitGigabyte) / duration.count() * SpeedInterval.count(); + LOG(info) << "network speed: " << std::fixed << std::setprecision(2) << speed << "GB/h"; + if (speed >= 1.f) { // 一个小时1GB的流量 + std::ostringstream oss; + oss << "当前服务器流量存在异常, " << DateTime::toString(front.time) << " - " + << DateTime::toString(back.time) << ": " << std::endl; + oss << "进出总速率: " << std::fixed << std::setprecision(2) << speed << "GB/h" << std::endl; + oss << "接收流量: " << std::fixed << std::setprecision(2) << receiveGigabyte << "GB" << std::endl; + oss << "发送流量: " << std::fixed << std::setprecision(2) << transmitGigabyte << "GB" << std::endl; + auto manager = Amass::Singleton::instance(); + if (manager) manager->sendMessage(NotifyServerChan, oss.str()); + LOG(warning) << oss.str(); + } + break; + } + } start(); }); } @@ -94,3 +129,32 @@ float SystemUsage::diskUsage(const std::string &disk) { return result; } + +SystemUsage::NetworkStats SystemUsage::networkStats(const std::string &interface) { + NetworkStats ret; + try { + std::ifstream ifs("/proc/net/dev"); + if (!ifs.is_open()) { + LOG(error) << "failed to open /proc/net/dev"; + return ret; + } + std::string line; + while (std::getline(ifs, line)) { + if (line.find(interface) == std::string::npos) continue; + boost::trim(line); + std::vector results; + boost::split(results, line, boost::algorithm::is_any_of(" "), boost::token_compress_on); + if (results.size() < 9) continue; + ret.interface = results.at(0); + ret.interface = ret.interface.substr(0, ret.interface.size() - 1); // Remove the trailing ':' + ret.receiveBytes = std::stoll(results.at(1)); + ret.transmitBytes = std::stoll(results.at(9)); + // LOG(info) << "interface: " << ret.interface << ", receive bytes: " << ret.receiveBytes + // << ", transmit bytes: " << ret.transmitBytes; + break; + } + } catch (const std::exception &e) { + LOG(error) << e.what(); + } + return ret; +} diff --git a/Server/SystemUsage.h b/Server/SystemUsage.h index e28f3ed..a168f1d 100644 --- a/Server/SystemUsage.h +++ b/Server/SystemUsage.h @@ -2,6 +2,7 @@ #define __SYSTEMUSAGE_H__ #include +#include /** * @brief 参考 https://github.com/improvess/cpp-linux-system-stats @@ -29,6 +30,13 @@ public: return user + nice + system + irq + softirq + steal + guest + guestNice; } }; + + struct NetworkStats { + std::string interface; + int64_t receiveBytes = 0; + int64_t transmitBytes = 0; + std::chrono::system_clock::time_point time = std::chrono::system_clock::now(); + }; SystemUsage(boost::asio::io_context &ioContext, const std::string &accessToken); void start(); @@ -38,11 +46,13 @@ protected: CpuStats readCpuData(); float cpuUsage(const CpuStats &first, const CpuStats &second); float diskUsage(const std::string &disk); + NetworkStats networkStats(const std::string &interface); private: boost::asio::io_context &m_ioContext; std::shared_ptr m_timer; std::string m_accessToken; CpuStats m_lastCpuStats; + std::list m_networkStats; }; #endif // __SYSTEMUSAGE_H__ \ No newline at end of file