Skip to content

Commit 75fec56

Browse files
committed
Keep track of request handling time
Signed-off-by: Leonardo Cecchi <[email protected]>
1 parent 87fb9e0 commit 75fec56

File tree

2 files changed

+39
-7
lines changed

2 files changed

+39
-7
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ Environment variables are your friends:
2121
As previously said, a new connection is established per request, without any
2222
connection pool. Use pgbouncer if you need something like that.
2323

24+
## Docker image
25+
26+
A simple Docker image containing this utility can be found at
27+
[hub.docker.com/r/leonardoce/webtest](https://hub.docker.com/r/leonardoce/webtest).
28+
2429
## Thanks
2530

2631
https://github.com/yhirose/cpp-httplib is a great tool, really.

http_test.cpp

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* You should have received a copy of the GNU General Public License
1313
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1414
**/
15-
15+
1616
#include "httplib.h"
1717
#include <chrono>
1818
#include <ctime>
@@ -41,17 +41,38 @@ int main() {
4141

4242
// Starting HTTP server
4343
httplib::Server svr;
44-
svr.set_logger(logger);
4544
svr.Get("/tx", tx);
4645
svr.listen("0.0.0.0", 8080);
4746

4847
return 0;
4948
}
5049

5150
/**
52-
* Given a request/response pair, put a small log message in stdout
51+
* This is a context class that to be used inside a request handler. It will
52+
* log the request handling time
53+
*/
54+
struct RequestHandlerLogger {
55+
const httplib::Request &_request;
56+
const httplib::Response &_response;
57+
58+
const std::chrono::system_clock::time_point _startTime;
59+
60+
RequestHandlerLogger(const httplib::Request &req,
61+
const httplib::Response &res);
62+
~RequestHandlerLogger();
63+
};
64+
65+
/**
66+
* Start a context, keeping track of when the request started
5367
*/
54-
void logger(const httplib::Request &req, const httplib::Response &res) {
68+
RequestHandlerLogger::RequestHandlerLogger(const httplib::Request &req,
69+
const httplib::Response &res)
70+
: _request(req), _response(res), _startTime(std::chrono::system_clock::now()) {}
71+
72+
/**
73+
* Stop the context, emitting a log message
74+
*/
75+
RequestHandlerLogger::~RequestHandlerLogger() {
5576
using namespace std;
5677

5778
const auto now = std::chrono::system_clock::now();
@@ -60,17 +81,22 @@ void logger(const httplib::Request &req, const httplib::Response &res) {
6081
now.time_since_epoch()) %
6182
1000;
6283

84+
const auto timeOccurred =
85+
std::chrono::duration_cast<std::chrono::milliseconds>(now - _startTime) %
86+
1000;
87+
6388
cout << std::put_time(std::localtime(&nowAsTimeT), "%a %b %d %Y %T") << '.'
64-
<< std::setfill('0') << std::setw(3) << nowMs.count();
65-
cout << " " << req.remote_addr << " " << req.path << " - " << res.status
66-
<< endl;
89+
<< std::setfill('0') << std::setw(3) << nowMs.count() << " "
90+
<< _request.remote_addr << " " << _request.path << " - " << _response.status << " - "
91+
<< timeOccurred.count() << "ms" << endl;
6792
cout.flush();
6893
}
6994

7095
/**
7196
* The test transaction on PostgreSQL
7297
*/
7398
void tx(const httplib::Request &req, httplib::Response &res) {
99+
RequestHandlerLogger _logger(req, res);
74100
PGconn *conn = PQconnectdb(database_url.c_str());
75101

76102
if (PQstatus(conn) != CONNECTION_OK) {
@@ -87,6 +113,7 @@ void tx(const httplib::Request &req, httplib::Response &res) {
87113
std::cout << PQresultErrorMessage(pgres) << std::endl;
88114
std::cout.flush();
89115
} else {
116+
res.status = 200;
90117
res.set_content("Ok!", "text/plain");
91118
}
92119
PQclear(pgres);

0 commit comments

Comments
 (0)