]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/histog.hh
Meson: Separate test files from common files
[thirdparty/pdns.git] / pdns / histog.hh
CommitLineData
ef890b79 1#pragma once
7ad71bdf
FM
2#pragma GCC diagnostic push
3#pragma GCC diagnostic ignored "-Wunused-parameter"
d65e98fd 4#if __clang_major__ >= 15
7ad71bdf 5#pragma GCC diagnostic ignored "-Wdeprecated-copy-with-user-provided-copy"
d65e98fd 6#endif
ef890b79 7#include <boost/accumulators/accumulators.hpp>
8#include <boost/accumulators/statistics.hpp>
7ad71bdf 9#pragma GCC diagnostic pop
ef890b79 10
11#include <vector>
12#include <fstream>
13#include <deque>
14#include <map>
15
16struct LogHistogramBin
17{
18 double percentile;
19 double latLimit;
20 double latAverage;
21 double latMedian;
22 double latStddev;
23 uint64_t count;
24 double cumulLatAverage;
25 double cumulLatMedian;
26};
27
28template<typename T>
4caba288 29std::vector<LogHistogramBin> createLogHistogram(const T& bins)
ef890b79 30{
4caba288 31 std::deque<double> percentiles={0.001, 0.01, 0.1, 0.2, 0.5, 1, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 94, 95, 96, 97, 97.5, 98, 98.5, 99, 99.5, 99.6, 99.9, 99.99, 99.999, 99.9999};
ef890b79 32 uint64_t totcumul=0, sum=0;
33
34 for(const auto& c: bins) {
35 totcumul += c.second;
36 }
37
38 namespace ba=boost::accumulators;
39 ba::accumulator_set<double, ba::features<ba::tag::mean, ba::tag::median, ba::tag::variance>, unsigned> acc;
40
41 ba::accumulator_set<double, ba::features<ba::tag::mean, ba::tag::median, ba::tag::variance>, unsigned int> cumulstats;
42
43 uint64_t bincount=0;
44 std::vector<LogHistogramBin> ret;
45 for(const auto& c: bins) {
46 if(percentiles.empty())
47 break;
48 sum += c.second;
49 bincount += c.second;
fc5d04c9 50
ef890b79 51 acc(c.first/1000.0, ba::weight=c.second);
52 for(unsigned int i=0; i < c.second; ++i)
53 cumulstats(c.first/1000.0, ba::weight=1); // "weighted" does not work for median
54 if(sum > percentiles.front() * totcumul / 100.0) {
55 ret.push_back({100.0-percentiles.front(), (double)c.first/1000.0, ba::mean(acc), ba::median(acc), sqrt(ba::variance(acc)), bincount, ba::mean(cumulstats), ba::median(cumulstats)});
fc5d04c9 56
ef890b79 57 percentiles.pop_front();
58 acc=decltype(acc)();
59 bincount=0;
60 }
61 }
62 std::sort(ret.begin(), ret.end(), [](const LogHistogramBin& a, const LogHistogramBin& b) {
63 return a.percentile < b.percentile;
64 });
65 return ret;
66}
67
68template<typename T>
4caba288 69void writeLogHistogramFile(const T& bins, std::ostream& out)
ef890b79 70{
4caba288 71 auto vec = createLogHistogram(bins);
ef890b79 72 out<< R"(# set logscale xy
73# set mxtics 10
74# set mytics 10
75# set grid xtics
76# set grid ytics
77# set xlabel "Slowest percentile"
78# set ylabel "Millisecond response time"
79# set terminal svg
80# set output 'log-histogram.svg'
81# plot 'log-histogram' using 1:2 with linespoints title 'Average latency per percentile', \
82# 'log-histogram' using 1:6 with linespoints title 'Cumulative average latency', \
83# 'log-histogram' using 1:7 with linespoints title 'Cumulative median latency')"<<"\n";
84
85 out<<"# slow-percentile usec-latency-mean usec-latency-max usec-latency-median usec-latency-stddev usec-latency-cumul usec-latency-median-cumul num-queries\n";
fc5d04c9
FM
86
87
ef890b79 88 for(const auto& e : vec) {
89 out<<e.percentile<<" "<<e.latAverage<<" "<<e.latLimit<<" "<<e.latMedian<<" "<<e.latStddev<<" "<<e.cumulLatAverage<<" "<<e.cumulLatMedian<<" "<<e.count<<"\n";
90 }
91 out.flush();
92}
93
94template<typename T>
95void writeFullHistogramFile(const T& bins, double binMsec, std::ofstream& out)
96{
97 std::map<unsigned int, uint64_t> reducedBins;
98 for(const auto& b : bins) {
99 reducedBins[b.first/(1000.0*binMsec)]+=b.second;
100 }
101 out<<"# msec-bin-low count\n";
102 for(const auto& rb : reducedBins) {
103 out<<rb.first*binMsec<<" "<<rb.second<<"\n";
104 }
105 out.flush();
106}