#include "SystemUsage.h" #include "BoostLog.h" #include "NetworkUtility.h" #include #include #include #include #include #include SystemUsage::SystemUsage(boost::asio::io_context &ioContext, const std::string &accessToken) : m_ioContext(ioContext), m_accessToken(accessToken) { m_timer = std::make_shared(m_ioContext); // LOG(info) << "access token: " << m_accessToken; } void SystemUsage::start() { m_timer->expires_after(std::chrono::seconds(10)); m_timer->async_wait([this](const boost::system::error_code &error) { if (error) { LOG(error) << error.message(); return; } auto currentCpuStats = readCpuData(); int usage = 100.0f * cpuUsage(m_lastCpuStats, currentCpuStats); publish("yuyun_cpu_usage", usage, "%", "CPU占用率"); publish("yuyun_disk_usage", static_cast(100.0f * diskUsage("/")), "%", "磁盘占用率"); m_lastCpuStats = currentCpuStats; start(); }); } void SystemUsage::publish(const std::string_view &deviceName, float value, const std::string_view &unit, const std::string_view &friendlyName) { // LOG(info) << "cpu usage: " << usage << "%"; Http::Client http(m_ioContext, Http::Transparent); std::ostringstream oss; oss << "Bearer " << m_accessToken; http.addRequestField(boost::beast::http::field::authorization, oss.str()); http.addRequestField(boost::beast::http::field::content_type, "application/json"); boost::json::object request; request["state"] = value; boost::json::object attributes; attributes["unit_of_measurement"] = unit; attributes["friendly_name"] = friendlyName; request["attributes"] = std::move(attributes); oss.str(""); oss << "/api/states/sensor." << deviceName; boost::system::error_code error; auto reply = http.post("iot.amass.fun", "80", oss.str(), boost::json::serialize(request), error); if (error) { LOG(error) << error.message(); } } SystemUsage::CpuStats SystemUsage::readCpuData() { CpuStats result; std::ifstream proc_stat("/proc/stat"); if (proc_stat.good()) { std::string line; getline(proc_stat, line); unsigned int *stats_p = (unsigned int *)&result; std::stringstream iss(line); std::string cpu; iss >> cpu; while (iss >> *stats_p) { stats_p++; }; } proc_stat.close(); return result; } float SystemUsage::cpuUsage(const CpuStats &first, const CpuStats &second) { const float active_time = static_cast(second.totalActive() - first.totalActive()); const float idle_time = static_cast(second.totalIdle() - first.totalIdle()); const float total_time = active_time + idle_time; return active_time / total_time; } float SystemUsage::diskUsage(const std::string &disk) { struct statvfs diskData; statvfs(disk.c_str(), &diskData); auto total = diskData.f_blocks; auto free = diskData.f_bfree; auto diff = total - free; float result = static_cast(diff) / total; return result; }