summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--TODO1
-rw-r--r--debian/control2
-rw-r--r--os.cpp78
-rw-r--r--os.h10
-rw-r--r--plugins/statistics/statistics.cpp2
-rw-r--r--response.cpp3
7 files changed, 97 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 17ae99c..4f0e435 100644
--- a/Makefile
+++ b/Makefile
@@ -71,6 +71,7 @@ PROGSRC=\
file.cpp \
http.cpp \
https.cpp \
+ os.cpp \
plugin.cpp \
privileges.cpp \
response.cpp \
diff --git a/TODO b/TODO
index 19b773c..60d72ce 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,4 @@
+Cache control: no cache of index, cache articles
Speed up config.GetPath
weblog: link consistency check (cron?)
weblog: style: zitate
diff --git a/debian/control b/debian/control
index 930d347..a417c81 100644
--- a/debian/control
+++ b/debian/control
@@ -21,3 +21,5 @@ Description: Web server
- Virtual Servers
- CGI interface
- Upload/Download Statistics
+
+# weblog: Depends: mpack
diff --git a/os.cpp b/os.cpp
new file mode 100644
index 0000000..10bf1c1
--- /dev/null
+++ b/os.cpp
@@ -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");
+}
+
diff --git a/os.h b/os.h
new file mode 100644
index 0000000..ed08234
--- /dev/null
+++ b/os.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <string>
+
+namespace OS {
+
+ std::string uptime_host();
+ std::string uptime_process();
+
+} // namespace OS
diff --git a/plugins/statistics/statistics.cpp b/plugins/statistics/statistics.cpp
index 03f4c94..543cc4e 100644
--- a/plugins/statistics/statistics.cpp
+++ b/plugins/statistics/statistics.cpp
@@ -81,6 +81,8 @@ std::string statistics_plugin::generate_page(
std::string result{header};
result += "<h1>Webserver Statistics</h1>";
+ result += "<p>Host uptime: "s + GetServerParam("uptime_host") + "</p>";
+ result += "<p>Host webserver: "s + GetServerParam("uptime_webserver") + "</p>";
result += "<pre>"s + GetServerParam("statistics") + "</pre>"s;
result += footer;
diff --git a/response.cpp b/response.cpp
index 9eda5ff..1752466 100644
--- a/response.cpp
+++ b/response.cpp
@@ -3,6 +3,7 @@
#include "auth.h"
#include "base64.h"
#include "file.h"
+#include "os.h"
#include <boost/algorithm/string/predicate.hpp>
@@ -85,6 +86,8 @@ std::unordered_map<std::string, std::function<std::string(Server&)>> GetServerPa
{"port", [](Server& server) { return server.GetSocket().port; }},
{"statistics", [](Server& server) { return server.GetStatistics().getValues(); }},
{"version", [](Server& server) { return Server::VersionString; }},
+ {"uptime_host", [](Server& server) { return OS::uptime_host(); }},
+ {"uptime_webserver", [](Server& server) { return OS::uptime_process(); }},
};
std::string GetServerParam(const std::string& key, Server& server)