diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index ff6e46b..e57f969 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -44,6 +44,27 @@ Sample response * All responses are in kB * Same as /proc/meminfo file +[GET] /proc/loadavg +------------------- + +* returns system load averaged over 1, 5, and 10 mins +* returns number of currently running processes over the total number of + process +* returns the last proccessed PID used +* Same as /proc/loadavg file + +Sample response + +``` +{ + "1" : 0.56, + "5" : 0.69, + "10" : 1.30, + "processes" : "2/849", + "lastPID" : 28225, +} +``` + Special formatted responses =========================== @@ -55,18 +76,7 @@ Special formatted responses [GET] /load ---------- -* Returns load average over the past 1, 5, and 10 mins -* formatted version of /proc/loadavg - -Sample response - -``` -{ - "1" : 0.56 - "5" : 0.69 - "10" : 1.30 -} -``` +* Returns a redirect to /proc/loadavg [GET] /mem ---------- diff --git a/src/components/state.cpp b/src/components/state.cpp index a3c4b51..c20ecbc 100644 --- a/src/components/state.cpp +++ b/src/components/state.cpp @@ -7,7 +7,7 @@ #include "state.hpp" bool state::getUptime(crow::json::wvalue& ret){ - std::ifstream f ("/proc/uptime"); + std::ifstream f (procuptimepath); std::string line; if(f.is_open()){ int space = -1; @@ -34,10 +34,54 @@ bool state::getUptime(crow::json::wvalue& ret){ } bool state::getRawUptime(std::string& ret){ - std::ifstream f ("/proc/uptime"); + std::ifstream f (procuptimepath); if(f.is_open()){ std::getline(f, ret); - ret += "\n"; + ret += '\n'; + f.close(); + } else { + ret = "Failed to open proc filesystem"; + return false; + } + + return true; +} + +bool state::getLoadAvg(crow::json::wvalue& ret){ + std::ifstream f (procloadavgpath); + std::string line; + if(f.is_open()){ + int spaces[4]; + int ind = 0; + std::getline(f, line); + + for(int i = 0; line[i] != '\0'; ++i){ + if(line[i] == ' '){ + spaces[ind] = i; + ++ind; + } + } + + ret["1"] = std::stof(line.substr(0,spaces[0])); + ret["5"] = std::stof(line.substr(spaces[0] + 1, spaces[1] - spaces[0])); + ret["10"] = std::stof(line.substr(spaces[1] + 1, spaces[2] - spaces[1])); + ret["processes"] = line.substr(spaces[2] + 1, spaces[3] - spaces[2] - 1); + ret["lastPID"] = std::stoi(line.substr(spaces[3] + 1)); + + f.close(); + } else { + ret["message"] = "Failed to open proc filesystem"; + return false; + } + + return true; +} + +bool state::getRawLoadAvg(std::string& ret){ + std::ifstream f (procloadavgpath); + if(f.is_open()){ + std::getline(f, ret); + ret += '\n'; f.close(); } else { ret = "Failed to open proc filesystem"; diff --git a/src/components/state.hpp b/src/components/state.hpp index f2bb8c8..01603a7 100644 --- a/src/components/state.hpp +++ b/src/components/state.hpp @@ -11,7 +11,12 @@ #include #include +constexpr char procuptimepath[] = "/proc/uptime"; +constexpr char procloadavgpath[] = "/proc/loadavg"; + namespace state{ bool getUptime(crow::json::wvalue&); bool getRawUptime(std::string&); + bool getLoadAvg(crow::json::wvalue&); + bool getRawLoadAvg(std::string&); } diff --git a/src/routes.cpp b/src/routes.cpp index f074db5..224fc03 100644 --- a/src/routes.cpp +++ b/src/routes.cpp @@ -56,4 +56,27 @@ void setRoutes(crow::SimpleApp& app){ return ret; }); + CROW_ROUTE(app, "/proc/loadavg")([](const crow::request& req){ + bool status; + std::string accept = req.get_header_value("Accept"); + + std::transform(accept.begin(), accept.end(), accept.begin(), ::tolower); + + if(accept == "text/plain"){ + accept.clear(); + status = state::getRawLoadAvg(accept); + return crow::response(status ? 200 : 503, accept); + } else { + crow::json::wvalue json; + status = state::getLoadAvg(json); + return crow::response(status ? 200 : 503, json.dump()); + } + }); + + CROW_ROUTE(app, "/load")([](){ + crow::response ret; + ret.moved_perm("/proc/loadavg"); + return ret; + }); + }