diff --git a/jtlsrv-cpp/src/main.cpp b/jtlsrv-cpp/src/main.cpp index d2af08c..17984d6 100644 --- a/jtlsrv-cpp/src/main.cpp +++ b/jtlsrv-cpp/src/main.cpp @@ -83,11 +83,12 @@ static void handle_request(tls_session* sess) { size_t resp_size = resp_body.size(); const bool is_init = (req.path == "/v1/init"); - const bool log_request = !is_init - || router.should_log_init(url, resp.status_code, static_cast(elapsed), resp_body); - - if (!log_request) { - return; + if (is_init) { + if (!router.should_log_init(url)) { + return; + } + } else { + router.flush_suppressed_init_logs(); } // Console log with response size and truncated body diff --git a/jtlsrv-cpp/src/router.cpp b/jtlsrv-cpp/src/router.cpp index ca7599d..d75634c 100644 --- a/jtlsrv-cpp/src/router.cpp +++ b/jtlsrv-cpp/src/router.cpp @@ -1,8 +1,6 @@ #include "router.hpp" #include "log.hpp" -#include -#include #include 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 -// within 30s window. Port of server.js shouldLogInit(). -bool Router::should_log_init(const std::string& url, int status, int duration_ms, - const std::string& response) { - // Report suppressed count hourly - auto now = std::chrono::duration_cast( - 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_++; +// Suppress consecutive identical /v1/init URLs; report count on non-init logs. +bool Router::should_log_init(const std::string& url) { + if (last_logged_init_url_ == url) { + suppressed_init_count_++; return false; } - - last_init_url_ = url; - last_init_result_ = response; - last_init_timestamp_ = now; + last_logged_init_url_ = url; 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(); +} diff --git a/jtlsrv-cpp/src/router.hpp b/jtlsrv-cpp/src/router.hpp index 98dbda7..c3df1e8 100644 --- a/jtlsrv-cpp/src/router.hpp +++ b/jtlsrv-cpp/src/router.hpp @@ -19,17 +19,16 @@ public: // Dispatch a request. Called from the TLS on_request callback. void dispatch(tls_session* sess, PairingStore& pairing, const json& config); - // Suppress init logs for repeated identical requests within 30s - bool should_log_init(const std::string& url, int status, int duration_ms, - const std::string& response); + // Suppress consecutive identical init URLs; return false if suppressed. + bool should_log_init(const std::string& url); + + // Print suppressed init count (if any) before a non-init log line. + void flush_suppressed_init_logs(); private: std::unordered_map routes_; // Init suppression state - std::string last_init_url_; - std::string last_init_result_; - int64_t last_init_timestamp_ = 0; - int suppressed_count_ = 0; - int64_t suppressed_report_ts_ = 0; + std::string last_logged_init_url_; + int suppressed_init_count_ = 0; }; diff --git a/server.js b/server.js index 3b9c35c..d40af10 100644 --- a/server.js +++ b/server.js @@ -36,33 +36,14 @@ function truncateUrl(url) { return `${url.slice(0, CONSOLE_URL_MAX_LENGTH)}...`; } -const lastInitState = { url: '', result: '', timestamp: 0 }; -let suppressedCount = 0; +let lastLoggedInitUrl = null; +let suppressedInitCount = 0; -setInterval(() => { - if (suppressedCount > 0) { - logger.info(`Suppressed ${suppressedCount} init log(s) in the last hour`); - suppressedCount = 0; +function flushSuppressedInitLogs() { + if (suppressedInitCount > 0) { + logger.info(`Suppressed ${suppressedInitCount} duplicate init log(s)`); + 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) { @@ -100,18 +81,27 @@ const loggedJtlHandler = async (req, res) => { const durationMs = Date.now() - started; const isInit = req.url.startsWith('/api/v1/init'); - if (!isInit || shouldLogInit(req.url, res.statusCode, durationMs, 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, - }); + if (isInit) { + if (lastLoggedInitUrl === req.url) { + suppressedInitCount++; + return; + } + lastLoggedInitUrl = req.url; + } else { + flushSuppressedInitLogs(); + lastLoggedInitUrl = null; } + + 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(