1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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();
}
|