-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathStats.cpp
160 lines (133 loc) · 5.67 KB
/
Stats.cpp
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
//
// Created by Kosho Owa on 2016/08/19.
// Hold statistics information of HTTP requests
//
#include "Stats.h"
// Display adjustment
static const int PROGRESS_WIDTH = 9;
static const int RESULT_WIDTH = 15;
static const string PROGRESS_HEADER = "------------------------ --------- --------- -------- -------- -------- --------";
static const string RESULT_HEADER = "----------------------------------- Results ------------------------------------";
// Print progress, called by Timer every interval second
void Stats::ShowProgress() {
char time_buff[80];
time_t now_t = time(NULL);
strftime(time_buff, sizeof(time_buff), "%FT%T%z", localtime(&now_t));
u_long upload = 0;
u_long download = 0;
if ((success_ - prev_success_) != 0) {
upload = static_cast<u_int>((size_upload_ - prev_size_upload_) / (success_ - prev_success_));
download = static_cast<u_int>((size_download_ - prev_size_download_) / (success_ - prev_success_));
}
double response = 0.0;
if (success_ > 0) {
response = (time_transfer_ - prev_time_transfer_) / (success_ - prev_success_) ;
}
stringstream msg;
msg << time_buff << " " << setw(PROGRESS_WIDTH) << success_ - prev_success_ << " "
<< setw(PROGRESS_WIDTH) << error_curl_ - prev_error_curl_
<< setw(PROGRESS_WIDTH) << error_http_ - prev_error_http_
<< setw(PROGRESS_WIDTH) << upload
<< setw(PROGRESS_WIDTH) << download
<< setw(PROGRESS_WIDTH) << fixed << setprecision(4) << response << endl;
safe_cout(msg.str());
prev_success_ = success_;
prev_error_curl_ = error_curl_;
prev_error_http_ = error_http_;
prev_size_upload_ = size_upload_;
prev_size_download_ = size_download_;
prev_time_transfer_ = time_transfer_;
}
// Print the final result
void Stats::ShowResult() {
if (finished_) {
double elapsed_sec = ((clock_stop_ - clock_start_).count()) * chrono::steady_clock::period::num /
static_cast<double>(chrono::steady_clock::period::den) - options_->warmup_sec_;
cout << RESULT_HEADER << endl;
Stats::PrintLine("Time after warm-up (sec)", elapsed_sec);
Stats::PrintLine("Number of success", static_cast<u_int>(wu_success_));
Stats::PrintLine("Number of connection failure", static_cast<u_int>(wu_error_curl_));
Stats::PrintLine("Number of HTTP response >400", static_cast<u_int>(wu_error_http_));
Stats::PrintLine("Average successful requests/sec", static_cast<u_int> (wu_success_ / elapsed_sec));
Stats::PrintLine("Upload throughput (byte/sec)", static_cast<u_int>(wu_size_upload_ / elapsed_sec));
Stats::PrintLine("Download throughput (byte/sec)", static_cast<u_int> (wu_size_download_ / elapsed_sec));
double time_transfer = 0.0;
if (wu_success_ > 0) {
time_transfer = static_cast<double> (wu_time_transfer_ / wu_success_);
}
Stats::PrintLine("Average time transfer (sec)", time_transfer);
}
}
// Return if all the requests are finished
bool Stats::IsFinished() const {
return finished_;
}
// Safely count the number of requests and other statistics
void Stats::CountResult(const int success, const int error_curl, const int error_http,
const u_long size_upload, const u_long size_download, const double time_transfer) {
success_ += success;
error_curl_ += error_curl;
error_http_ += error_http;
size_upload_ += size_upload;
size_download_ += size_download;
add_to_atomic_double(&time_transfer_, time_transfer);
if ((chrono::steady_clock::now() - clock_start_).count() * chrono::steady_clock::period::num
/ static_cast<double>(chrono::steady_clock::period::den) > options_->warmup_sec_) {
wu_success_ += success;
wu_error_curl_ += error_curl;
wu_error_http_ += error_http;
wu_size_upload_ += size_upload;
wu_size_download_ += size_download;
add_to_atomic_double(&wu_time_transfer_, time_transfer);
}
if ((success_ + error_curl_ + error_http_) == options_->num_recurrence_ ) {
clock_stop_ = chrono::steady_clock::now();
finished_ = true;
}
}
void Stats::PrintLine(const string option, const u_int value) {
stringstream msg;
msg << setw(35) << right << option << ": " << setw(RESULT_WIDTH) << right << value << endl;
safe_cout(msg.str());
}
void Stats::PrintLine(const string option, const double value) {
stringstream msg;
msg << setw(35) << right << option << ": " << setw(RESULT_WIDTH) << right << fixed << setprecision(5) << value
<< endl;
safe_cout(msg.str());
}
void Stats::ShowProgressHeader() {
stringstream msg;
msg << setw(24) << left << "Timestamp" << " "
<< setw(PROGRESS_WIDTH) << right << "Success" << " " << setw(PROGRESS_WIDTH) << "Fail" << setw(PROGRESS_WIDTH)
<< "HTTP>400"
<< setw(PROGRESS_WIDTH) << "Upload" << setw(PROGRESS_WIDTH) << "Download" << setw(PROGRESS_WIDTH) << "Response"
<< endl << PROGRESS_HEADER << endl;
safe_cout(msg.str());
}
Stats::Stats(Options *options_, mutex *mtx_for_cout_) : options_(options_), mtx_for_cout_(mtx_for_cout_) {
requests_ = 0;
success_ = 0;
error_curl_ = 0;
error_http_ = 0;
size_upload_ = 0;
size_download_ = 0;
time_transfer_ = 0;
wu_success_ = 0;
wu_error_curl_ = 0;
wu_error_http_ = 0;
wu_size_upload_ = 0;
wu_size_download_ = 0;
wu_time_transfer_ = 0;
}
void Stats::safe_cout(const string msg) {
lock_guard<mutex> lock(*mtx_for_cout_);
cout << msg;
}
void Stats::safe_cerr(const string msg) {
lock_guard<std::mutex> lock(*mtx_for_cout_);
cerr << msg;
}
u_long Stats::CountRequest() {
return requests_++;
}