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