u
This commit is contained in:
@@ -83,11 +83,12 @@ static void handle_request(tls_session* sess) {
|
|||||||
size_t resp_size = resp_body.size();
|
size_t resp_size = resp_body.size();
|
||||||
|
|
||||||
const bool is_init = (req.path == "/v1/init");
|
const bool is_init = (req.path == "/v1/init");
|
||||||
const bool log_request = !is_init
|
if (is_init) {
|
||||||
|| router.should_log_init(url, resp.status_code, static_cast<int>(elapsed), resp_body);
|
if (!router.should_log_init(url)) {
|
||||||
|
return;
|
||||||
if (!log_request) {
|
}
|
||||||
return;
|
} else {
|
||||||
|
router.flush_suppressed_init_logs();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Console log with response size and truncated body
|
// Console log with response size and truncated body
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
#include "router.hpp"
|
#include "router.hpp"
|
||||||
#include "log.hpp"
|
#include "log.hpp"
|
||||||
|
|
||||||
#include <chrono>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
void Router::add_route(const std::string& method, const std::string& path, Handler handler) {
|
void Router::add_route(const std::string& method, const std::string& path, Handler handler) {
|
||||||
@@ -52,32 +50,20 @@ void Router::dispatch(tls_session* sess, PairingStore& pairing, const json& conf
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init suppression: log only if non-200, slow, or first/different request
|
// Suppress consecutive identical /v1/init URLs; report count on non-init logs.
|
||||||
// within 30s window. Port of server.js shouldLogInit().
|
bool Router::should_log_init(const std::string& url) {
|
||||||
bool Router::should_log_init(const std::string& url, int status, int duration_ms,
|
if (last_logged_init_url_ == url) {
|
||||||
const std::string& response) {
|
suppressed_init_count_++;
|
||||||
// Report suppressed count hourly
|
|
||||||
auto now = std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
||||||
std::chrono::system_clock::now().time_since_epoch()).count();
|
|
||||||
|
|
||||||
if (suppressed_count_ > 0 && (now - suppressed_report_ts_) > 3'600'000) {
|
|
||||||
logc::info("Suppressed %d init log(s) in the last hour", suppressed_count_);
|
|
||||||
suppressed_count_ = 0;
|
|
||||||
suppressed_report_ts_ = now;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status != 200) return true;
|
|
||||||
if (duration_ms > 400) return true;
|
|
||||||
|
|
||||||
int64_t time_since_last = now - last_init_timestamp_;
|
|
||||||
if (time_since_last < 30'000 && url == last_init_url_ && response == last_init_result_) {
|
|
||||||
last_init_timestamp_ = now;
|
|
||||||
suppressed_count_++;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
last_logged_init_url_ = url;
|
||||||
last_init_url_ = url;
|
|
||||||
last_init_result_ = response;
|
|
||||||
last_init_timestamp_ = now;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Router::flush_suppressed_init_logs() {
|
||||||
|
if (suppressed_init_count_ > 0) {
|
||||||
|
logc::info("Suppressed %d duplicate init log(s)", suppressed_init_count_);
|
||||||
|
suppressed_init_count_ = 0;
|
||||||
|
}
|
||||||
|
last_logged_init_url_.clear();
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,17 +19,16 @@ public:
|
|||||||
// Dispatch a request. Called from the TLS on_request callback.
|
// Dispatch a request. Called from the TLS on_request callback.
|
||||||
void dispatch(tls_session* sess, PairingStore& pairing, const json& config);
|
void dispatch(tls_session* sess, PairingStore& pairing, const json& config);
|
||||||
|
|
||||||
// Suppress init logs for repeated identical requests within 30s
|
// Suppress consecutive identical init URLs; return false if suppressed.
|
||||||
bool should_log_init(const std::string& url, int status, int duration_ms,
|
bool should_log_init(const std::string& url);
|
||||||
const std::string& response);
|
|
||||||
|
// Print suppressed init count (if any) before a non-init log line.
|
||||||
|
void flush_suppressed_init_logs();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<std::string, Handler> routes_;
|
std::unordered_map<std::string, Handler> routes_;
|
||||||
|
|
||||||
// Init suppression state
|
// Init suppression state
|
||||||
std::string last_init_url_;
|
std::string last_logged_init_url_;
|
||||||
std::string last_init_result_;
|
int suppressed_init_count_ = 0;
|
||||||
int64_t last_init_timestamp_ = 0;
|
|
||||||
int suppressed_count_ = 0;
|
|
||||||
int64_t suppressed_report_ts_ = 0;
|
|
||||||
};
|
};
|
||||||
|
|||||||
62
server.js
62
server.js
@@ -36,33 +36,14 @@ function truncateUrl(url) {
|
|||||||
return `${url.slice(0, CONSOLE_URL_MAX_LENGTH)}...`;
|
return `${url.slice(0, CONSOLE_URL_MAX_LENGTH)}...`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lastInitState = { url: '', result: '', timestamp: 0 };
|
let lastLoggedInitUrl = null;
|
||||||
let suppressedCount = 0;
|
let suppressedInitCount = 0;
|
||||||
|
|
||||||
setInterval(() => {
|
function flushSuppressedInitLogs() {
|
||||||
if (suppressedCount > 0) {
|
if (suppressedInitCount > 0) {
|
||||||
logger.info(`Suppressed ${suppressedCount} init log(s) in the last hour`);
|
logger.info(`Suppressed ${suppressedInitCount} duplicate init log(s)`);
|
||||||
suppressedCount = 0;
|
suppressedInitCount = 0;
|
||||||
}
|
}
|
||||||
}, 60 * 60 * 1000);
|
|
||||||
|
|
||||||
function shouldLogInit(url, statusCode, durationMs, responseBody) {
|
|
||||||
if (statusCode !== 200) return true;
|
|
||||||
if (durationMs > 400) return true;
|
|
||||||
|
|
||||||
const now = Date.now();
|
|
||||||
const timeSinceLast = now - lastInitState.timestamp;
|
|
||||||
|
|
||||||
if (timeSinceLast < 30_000 && url === lastInitState.url && responseBody === lastInitState.result) {
|
|
||||||
lastInitState.timestamp = now;
|
|
||||||
suppressedCount++;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastInitState.url = url;
|
|
||||||
lastInitState.result = responseBody;
|
|
||||||
lastInitState.timestamp = now;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatBody(buffer) {
|
function formatBody(buffer) {
|
||||||
@@ -100,18 +81,27 @@ const loggedJtlHandler = async (req, res) => {
|
|||||||
const durationMs = Date.now() - started;
|
const durationMs = Date.now() - started;
|
||||||
const isInit = req.url.startsWith('/api/v1/init');
|
const isInit = req.url.startsWith('/api/v1/init');
|
||||||
|
|
||||||
if (!isInit || shouldLogInit(req.url, res.statusCode, durationMs, responseBody)) {
|
if (isInit) {
|
||||||
logger.info(`${req.socket.remoteAddress} ${req.method} ${truncateUrl(req.url)} ${res.statusCode} ${durationMs}ms`);
|
if (lastLoggedInitUrl === req.url) {
|
||||||
|
suppressedInitCount++;
|
||||||
logRequest({
|
return;
|
||||||
remoteAddress: req.socket.remoteAddress,
|
}
|
||||||
method: req.method,
|
lastLoggedInitUrl = req.url;
|
||||||
url: req.url,
|
} else {
|
||||||
statusCode: res.statusCode,
|
flushSuppressedInitLogs();
|
||||||
durationMs,
|
lastLoggedInitUrl = null;
|
||||||
response: responseBody,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.info(`${req.socket.remoteAddress} ${req.method} ${truncateUrl(req.url)} ${res.statusCode} ${durationMs}ms`);
|
||||||
|
|
||||||
|
logRequest({
|
||||||
|
remoteAddress: req.socket.remoteAddress,
|
||||||
|
method: req.method,
|
||||||
|
url: req.url,
|
||||||
|
statusCode: res.statusCode,
|
||||||
|
durationMs,
|
||||||
|
response: responseBody,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const httpsServer = https.createServer(
|
const httpsServer = https.createServer(
|
||||||
|
|||||||
Reference in New Issue
Block a user