首次提交
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
|
||||
#include <drogon/drogon.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
class Access_Logger {
|
||||
public:
|
||||
static void log(const drogon::HttpRequestPtr& request,
|
||||
const drogon::HttpResponsePtr& response,
|
||||
const double elapsed_ms) {
|
||||
std::cout << "[http access] method=" << request->methodString()
|
||||
<< ", path=" << request->path()
|
||||
<< ", status=" << static_cast<int>(response->statusCode())
|
||||
<< ", cost_ms=" << elapsed_ms << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
class Slow_Request_Monitor {
|
||||
public:
|
||||
static void log_if_slow(const drogon::HttpRequestPtr& request,
|
||||
const drogon::HttpResponsePtr& response,
|
||||
const double elapsed_ms,
|
||||
const std::size_t threshold_ms) {
|
||||
if (elapsed_ms < static_cast<double>(threshold_ms)) return;
|
||||
std::cout << "[slow http request] method=" << request->methodString()
|
||||
<< ", path=" << request->path()
|
||||
<< ", status=" << static_cast<int>(response->statusCode())
|
||||
<< ", cost_ms=" << elapsed_ms
|
||||
<< ", threshold_ms=" << threshold_ms << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
class Scope_Timer {
|
||||
public:
|
||||
Scope_Timer(std::string name, const std::size_t threshold_ms)
|
||||
: name_(std::move(name)),
|
||||
threshold_ms_(threshold_ms),
|
||||
start_(std::chrono::steady_clock::now()) {}
|
||||
|
||||
~Scope_Timer() {
|
||||
const auto elapsed_ms =
|
||||
std::chrono::duration<double, std::milli>(
|
||||
std::chrono::steady_clock::now() - start_).count();
|
||||
if (elapsed_ms < static_cast<double>(threshold_ms_)) return;
|
||||
std::cout << "[slow scope] name=" << name_
|
||||
<< ", cost_ms=" << elapsed_ms
|
||||
<< ", threshold_ms=" << threshold_ms_ << std::endl;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
std::size_t threshold_ms_;
|
||||
std::chrono::steady_clock::time_point start_;
|
||||
};
|
||||
|
||||
inline constexpr const char* kHttpRequestStart = "ecap.http_request_start";
|
||||
|
||||
inline void register_http_performance_monitor(const bool access_log,
|
||||
const std::size_t slow_request_threshold_ms) {
|
||||
drogon::app().registerSyncAdvice(
|
||||
[](const drogon::HttpRequestPtr& request) -> drogon::HttpResponsePtr {
|
||||
request->attributes()->insert(kHttpRequestStart, std::chrono::steady_clock::now());
|
||||
return {};
|
||||
});
|
||||
drogon::app().registerPreSendingAdvice(
|
||||
[access_log, slow_request_threshold_ms](
|
||||
const drogon::HttpRequestPtr& request,
|
||||
const drogon::HttpResponsePtr& response) {
|
||||
const auto& start =
|
||||
request->attributes()->get<std::chrono::steady_clock::time_point>(
|
||||
kHttpRequestStart);
|
||||
if (start == std::chrono::steady_clock::time_point{}) return;
|
||||
const auto elapsed_ms =
|
||||
std::chrono::duration<double, std::milli>(
|
||||
std::chrono::steady_clock::now() - start).count();
|
||||
if (access_log) Access_Logger::log(request, response, elapsed_ms);
|
||||
Slow_Request_Monitor::log_if_slow(
|
||||
request, response, elapsed_ms, slow_request_threshold_ms);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user