Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "../global.hpp"
00022
00023 #include "metrics.hpp"
00024
00025 #include <algorithm>
00026 #include <iostream>
00027
00028 struct compare_samples_to_stringspan {
00029 bool operator()(const simple_wml::string_span& a, const simple_wml::string_span& b)
00030 {
00031 return a < b;
00032 }
00033 };
00034
00035 struct compare_samples_by_time {
00036 bool operator()(const metrics::sample& a, const metrics::sample& b) const {
00037 return a.processing_time < b.processing_time;
00038 }
00039 };
00040
00041
00042 metrics::metrics() :
00043 samples_(),
00044 most_consecutive_requests_(0),
00045 current_requests_(0),
00046 nrequests_(0),
00047 nrequests_waited_(0),
00048 started_at_(time(NULL)),
00049 terminations_()
00050 {}
00051
00052 metrics::~metrics()
00053 {
00054
00055 for(std::vector<sample>::iterator itor = samples_.begin();
00056 itor != samples_.end(); ++itor)
00057 {
00058 delete[] itor->name.begin();
00059 }
00060 samples_.clear();
00061 }
00062
00063 void metrics::service_request()
00064 {
00065 if(current_requests_ > 0) {
00066 ++nrequests_waited_;
00067 }
00068
00069 ++nrequests_;
00070 ++current_requests_;
00071 if(current_requests_ > most_consecutive_requests_) {
00072 most_consecutive_requests_ = current_requests_;
00073 }
00074 }
00075
00076 void metrics::no_requests()
00077 {
00078 current_requests_ = 0;
00079 }
00080
00081 void metrics::record_sample(const simple_wml::string_span& name,
00082 clock_t parsing_time, clock_t processing_time)
00083 {
00084 std::vector<sample>::iterator isample = std::lower_bound(samples_.begin(), samples_.end(), name,compare_samples_to_stringspan());
00085 if(isample == samples_.end()
00086 || isample->name != name) {
00087
00088 if(samples_.size() > 30) {
00089 return;
00090 }
00091 int index = isample - samples_.begin();
00092 simple_wml::string_span dup_name(name.duplicate());
00093 sample new_sample;
00094 new_sample.name = dup_name;
00095 samples_.insert(isample, new_sample);
00096
00097 isample = samples_.begin() + index;
00098 }
00099
00100 isample->nsamples++;
00101 isample->parsing_time += parsing_time;
00102 isample->processing_time += processing_time;
00103 isample->max_parsing_time = std::max(parsing_time,isample->max_parsing_time);
00104 isample->max_processing_time = std::max(processing_time,isample->max_processing_time);
00105 }
00106
00107 void metrics::game_terminated(const std::string& reason)
00108 {
00109 terminations_[reason]++;
00110 }
00111
00112 std::ostream& metrics::games(std::ostream& out) const
00113 {
00114 if (terminations_.empty()) return out << "No game ended so far.";
00115
00116 size_t n = 0;
00117 out << "Games have been terminated in the following ways:\n";
00118 for(std::map<std::string,int>::const_iterator i = terminations_.begin(); i != terminations_.end(); ++i) {
00119 out << i->first << ": " << i->second << "\n";
00120 n += i->second;
00121 }
00122 out << "Total number of games = " << n;
00123
00124 return out;
00125 }
00126
00127 std::ostream& metrics::requests(std::ostream& out) const
00128 {
00129 if (samples_.empty()) return out;
00130
00131 std::vector<metrics::sample> ordered_samples = samples_;
00132 std::sort(ordered_samples.begin(), ordered_samples.end(), compare_samples_by_time());
00133
00134 out << "\nSampled request types:\n";
00135
00136 size_t n = 0;
00137 size_t pa = 0;
00138 size_t pr = 0;
00139 for(std::vector<metrics::sample>::const_iterator s = ordered_samples.begin(); s != ordered_samples.end(); ++s) {
00140 out << "'" << s->name << "' called " << s->nsamples << " times "
00141 << s->parsing_time << "("<< s->max_parsing_time <<") parsing time, "
00142 << s->processing_time << "("<<s->max_processing_time<<") processing time\n";
00143 n += s->nsamples;
00144 pa += s->parsing_time;
00145 pr += s->processing_time;
00146 }
00147 out << "Total number of request samples = " << n << "\n"
00148 << "Total parsing time = " << pa << "\n"
00149 << "Total processing time = " << pr;
00150
00151 return out;
00152 }
00153
00154 std::ostream& operator<<(std::ostream& out, metrics& met)
00155 {
00156 const time_t time_up = time(NULL) - met.started_at_;
00157 const int seconds = time_up%60;
00158 const int minutes = (time_up/60)%60;
00159 const int hours = (time_up/(60*60))%24;
00160 const int days = time_up/(60*60*24);
00161 const int requests_immediate = met.nrequests_ - met.nrequests_waited_;
00162 const int percent_immediate = (requests_immediate*100)/(met.nrequests_ > 0 ? met.nrequests_ : 1);
00163 out << "METRICS\nUp " << days << " days, " << hours << " hours, "
00164 << minutes << " minutes, " << seconds << " seconds\n"
00165 << met.nrequests_ << " requests serviced. " << requests_immediate
00166 << " (" << percent_immediate << "%) "
00167 << "requests were serviced immediately.\n"
00168 << "longest burst of requests was: " << met.most_consecutive_requests_;
00169
00170 return out;
00171 }