diff options
author | Roland Reichwein <mail@reichwein.it> | 2020-04-25 18:36:54 +0200 |
---|---|---|
committer | Roland Reichwein <mail@reichwein.it> | 2020-04-25 18:36:54 +0200 |
commit | 683d2cb48c4f3620fc3be68ba97b2d3bb5a40e30 (patch) | |
tree | 8c0ae6438f6ec706a170eb41f683d6c91dc4a800 /statistics.cpp | |
parent | b2c34d03399978a3d0838ee7ed92c760e7908721 (diff) |
Added statistics
Diffstat (limited to 'statistics.cpp')
-rw-r--r-- | statistics.cpp | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/statistics.cpp b/statistics.cpp new file mode 100644 index 0000000..19d0258 --- /dev/null +++ b/statistics.cpp @@ -0,0 +1,87 @@ +#include "statistics.h" + +#include <filesystem> +#include <fstream> +#include <iostream> + +namespace fs = std::filesystem; + +namespace { + const fs::path statsfilepath{ "/var/lib/webserver/stats.db" }; +} // anonymous namespace + +Statistics::Statistics() +{ + std::cout << "Loading statistics..." << std::endl; + std::ifstream file{statsfilepath, std::ios::in | std::ios::binary}; + if (file.is_open()) { + Serialization::IArchive archive{file}; + + archive >> mBins; + } else { + std::cerr << "Warning: Couldn't read statistics" << std::endl; + } +} + +Statistics::~Statistics() +{ + std::cout << "Saving statistics..." << std::endl; + std::lock_guard<std::mutex> lock(mMutex); + std::ofstream file{statsfilepath, std::ios::out | std::ios::binary | std::ios::trunc}; + if (file.is_open()) { + Serialization::OArchive archive{file}; + + archive << mBins; + } else { + std::cerr << "Warning: Couldn't write statistics" << std::endl; + } +} + +bool Statistics::Bin::expired() const +{ + auto now {time(nullptr)}; + + if (now < start_time) + std::runtime_error("Statistics time is in the future"); + + return start_time + binsize < now; +} + +void Statistics::limit() +{ + while (mBins.size() * sizeof(Bin) > maxSize) + mBins.pop_front(); // discard oldest element +} + +void Statistics::count(size_t bytes_in, size_t bytes_out, bool error, bool ipv6, bool https) +{ + std::lock_guard<std::mutex> lock(mMutex); + + if (mBins.empty() || mBins.back().expired()) { + mBins.emplace_back(Bin{static_cast<uint64_t>((time(nullptr) / binsize) * binsize), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}); + } + + Bin& bin{mBins.back()}; + + bin.requests++; + if (error) bin.errors++; + bin.bytes_in += bytes_in; + bin.bytes_out += bytes_out; + + if (ipv6) { + bin.requests_ipv6++; + if (error) bin.errors_ipv6++; + bin.bytes_in_ipv6 += bytes_in; + bin.bytes_out_ipv6 += bytes_out; + } + + if (https) { + bin.requests_https++; + if (error) bin.errors_https++; + bin.bytes_in_https += bytes_in; + bin.bytes_out_https += bytes_out; + } + + limit(); +} + |