diff options
author | Roland Reichwein <mail@reichwein.it> | 2020-04-30 12:25:29 +0200 |
---|---|---|
committer | Roland Reichwein <mail@reichwein.it> | 2020-04-30 12:25:29 +0200 |
commit | 292235b5c5ae25139d5945c2a298e13272a4f29b (patch) | |
tree | 40aeaa4fd3217e900787c9bd861aaf0f2f0d9319 /os.cpp | |
parent | 851f4d84d4b8dcff032f5304235917bc58e1e46e (diff) |
Uptime in stats
Diffstat (limited to 'os.cpp')
-rw-r--r-- | os.cpp | 78 |
1 files changed, 78 insertions, 0 deletions
@@ -0,0 +1,78 @@ +#include "os.h" + +#include <boost/algorithm/string/split.hpp> + +#include <unistd.h> + +#include <fstream> +#include <vector> + +using namespace std::string_literals; + +namespace { + + std::string to_string(uint32_t v, size_t size) + { + std::string result{std::to_string(v)}; + + return (size > result.size() ? std::string(size - result.size(), char('0')) : ""s) + result; + } + + std::string to_time_string(uint32_t sec) + { + uint32_t days = sec / (24 * 3600); + uint32_t hours = (sec % (24 * 3600)) / 3600; + uint32_t minutes = (sec % 3600) / 60; + uint32_t seconds = (sec % 60); + + return std::to_string(days) + " days, "s + to_string(hours, 2) + ":"s + to_string(minutes, 2) + ":"s + to_string(seconds, 2); + } + + uint64_t uptime() + { + double uptime_seconds{}; + if (std::ifstream("/proc/uptime", std::ios::in) >> uptime_seconds) + { + return static_cast<uint64_t>(uptime_seconds); + } + + return 0; + } + +} // anonymous namespace + +std::string OS::uptime_host() +{ + return to_time_string(uptime()); +} + +std::string OS::uptime_process() +{ + std::string filepath{"/proc/self/stat"}; + std::ifstream f(filepath, std::ios::in); + if (f.is_open()) { + std::string line; + std::getline(f, line); + std::vector<std::string> elements; + boost::algorithm::split(elements, line, [](char c){ return c == ' '; }); + if (elements.size() < 22) + throw std::runtime_error("Bad contents of /proc/self/stat"); + + long jiffies_per_second {sysconf(_SC_CLK_TCK)}; + if (jiffies_per_second == 0) + throw std::runtime_error("Jiffies per second is 0"); + + try { + unsigned long starttime { std::stoul(elements[21])}; + + unsigned long runtime = uptime() - starttime / jiffies_per_second; + + return to_time_string(runtime); + } catch (const std::exception& ex) { + throw std::runtime_error("Bad value in /proc/self/stat: "s + ex.what()); + } + + } else + throw std::runtime_error("Reading /proc/self/stat"); +} + |