The Battle for Wesnoth  1.19.0-dev
metrics.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2024
3  by David White <dave@whitevine.net>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 /**
17  * @file
18  * Various server-statistics.
19  */
20 
22 
23 #include <algorithm>
24 #include <ostream>
25 
28  {
29  return a < b;
30  }
31 };
32 
34  bool operator()(const metrics::sample& a, const metrics::sample& b) const {
35  return a.processing_time < b.processing_time;
36  }
37 };
38 
40  : samples_()
41  , most_consecutive_requests_(0)
42  , current_requests_(0)
43  , nrequests_(0)
44  , nrequests_waited_(0)
45  , started_at_(std::time(nullptr))
46  , terminations_()
47 {
48 }
49 
51 {
52  for(auto& s : samples_) {
53  delete[] s.name.begin();
54  }
55 
56  samples_.clear();
57 }
58 
60 {
61  if(current_requests_ > 0) {
63  }
64 
65  ++nrequests_;
69  }
70 }
71 
73 {
75 }
76 
77 void metrics::record_sample(const simple_wml::string_span& name, clock_t parsing_time, clock_t processing_time)
78 {
79  auto isample = std::lower_bound(samples_.begin(), samples_.end(), name,compare_samples_to_stringspan());
80  if(isample == samples_.end() || isample->name != name) {
81  //protect against DoS with memory exhaustion
82  if(samples_.size() > 30) {
83  return;
84  }
85  int index = std::distance(samples_.begin(), isample);
86  simple_wml::string_span dup_name(name.duplicate());
87  sample new_sample;
88  new_sample.name = dup_name;
89  samples_.insert(isample, new_sample);
90 
91  isample = samples_.begin() + index;
92  }
93 
94  isample->nsamples++;
95  isample->parsing_time += parsing_time;
96  isample->processing_time += processing_time;
97  isample->max_parsing_time = std::max(parsing_time,isample->max_parsing_time);
98  isample->max_processing_time = std::max(processing_time,isample->max_processing_time);
99 }
100 
101 void metrics::game_terminated(const std::string& reason)
102 {
103  terminations_[reason]++;
104 }
105 
106 std::ostream& metrics::games(std::ostream& out) const
107 {
108  if (terminations_.empty()) return out << "No game ended so far.";
109 
110  std::size_t n = 0;
111  out << "Games have been terminated in the following ways:\n";
112  for(const auto& t : terminations_) {
113  out << t.first << ": " << t.second << "\n";
114  n += t.second;
115  }
116  out << "Total number of games = " << n;
117 
118  return out;
119 }
120 
121 std::ostream& metrics::requests(std::ostream& out) const
122 {
123  if (samples_.empty()) return out;
124 
125  std::vector<metrics::sample> ordered_samples = samples_;
126  std::sort(ordered_samples.begin(), ordered_samples.end(), compare_samples_by_time());
127 
128  out << "\nSampled request types:\n";
129 
130  std::size_t n = 0;
131  std::size_t pa = 0;
132  std::size_t pr = 0;
133  for(const auto& s : ordered_samples) {
134  out << "'" << s.name << "' called " << s.nsamples << " times "
135  << s.parsing_time << "("<< s.max_parsing_time <<") parsing time, "
136  << s.processing_time << "("<<s.max_processing_time<<") processing time\n";
137  n += s.nsamples;
138  pa += s.parsing_time;
139  pr += s.processing_time;
140  }
141  out << "Total number of request samples = " << n << "\n"
142  << "Total parsing time = " << pa << "\n"
143  << "Total processing time = " << pr;
144 
145  return out;
146 }
147 
148 std::ostream& operator<<(std::ostream& out, metrics& met)
149 {
150  const std::time_t time_up = std::time(nullptr) - met.started_at_;
151  const int seconds = time_up%60;
152  const int minutes = (time_up/60)%60;
153  const int hours = (time_up/(60*60))%24;
154  const int days = time_up/(60*60*24);
155  const int requests_immediate = met.nrequests_ - met.nrequests_waited_;
156  const int percent_immediate = (requests_immediate*100)/(met.nrequests_ > 0 ? met.nrequests_ : 1);
157  out << "METRICS\nUp " << days << " days, " << hours << " hours, "
158  << minutes << " minutes, " << seconds << " seconds\n"
159  << met.nrequests_ << " requests serviced. " << requests_immediate
160  << " (" << percent_immediate << "%) "
161  << "requests were serviced immediately.\n"
162  << "longest burst of requests was: " << met.most_consecutive_requests_;
163 
164  return out;
165 }
double t
Definition: astarsearch.cpp:63
std::map< std::string, int > terminations_
Definition: metrics.hpp:73
void service_request()
Definition: metrics.cpp:59
std::ostream & requests(std::ostream &out) const
Definition: metrics.cpp:121
void no_requests()
Definition: metrics.cpp:72
int nrequests_waited_
Definition: metrics.hpp:71
std::ostream & games(std::ostream &out) const
Definition: metrics.cpp:106
std::vector< sample > samples_
Definition: metrics.hpp:66
int current_requests_
Definition: metrics.hpp:69
void record_sample(const simple_wml::string_span &name, clock_t parsing_time, clock_t processing_time)
Definition: metrics.cpp:77
int most_consecutive_requests_
Definition: metrics.hpp:68
metrics()
Definition: metrics.cpp:39
const std::time_t started_at_
Definition: metrics.hpp:72
~metrics()
Definition: metrics.cpp:50
void game_terminated(const std::string &reason)
Definition: metrics.cpp:101
int nrequests_
Definition: metrics.hpp:70
char * duplicate() const
Definition: simple_wml.cpp:188
std::ostream & operator<<(std::ostream &out, metrics &met)
Definition: metrics.cpp:148
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:70
bool operator()(const metrics::sample &a, const metrics::sample &b) const
Definition: metrics.cpp:34
bool operator()(const simple_wml::string_span &a, const simple_wml::string_span &b) const
Definition: metrics.cpp:27
simple_wml::string_span name
Definition: metrics.hpp:54
static map_location::DIRECTION n
static map_location::DIRECTION s
#define a
#define b