Suppress HTTP Connection Log for Local Connections

I.E., No logs for HTTP connections from localhost, 127.0.0.1,
::1 (IPv6 localhost), or any other local IP addresses.
This commit is contained in:
Jason-JP-Yang 2025-05-29 20:03:53 +08:00
parent 5853becb61
commit b6348581e8
3 changed files with 143 additions and 32 deletions

View File

@ -20,12 +20,72 @@ using namespace std;
#include <srs_core_autofree.hpp>
#include <srs_kernel_buffer.hpp>
#include <srs_protocol_kbps.hpp>
#include <set>
#include <srs_protocol_utility.hpp>
SrsPps* _srs_pps_ids = NULL;
SrsPps* _srs_pps_fids = NULL;
SrsPps* _srs_pps_fids_level0 = NULL;
SrsPps* _srs_pps_dispose = NULL;
// Add method to check if IP is local address
bool is_local_address_for_logging(const std::string& ip_addr)
{
// Check for localhost
if (ip_addr == "localhost") {
return true;
}
// Check for IPv4 loopback addresses (127.x.x.x)
if (ip_addr.find("127.") == 0) {
return true;
}
// Check for IPv6 loopback (::1)
if (ip_addr == "::1") {
return true;
}
// Get all local network interface addresses
static bool local_ips_cached = false;
static std::set<std::string> local_ips_cache;
if (!local_ips_cached) {
// Cache local IPs for performance
std::vector<SrsIPAddress*>& ips = srs_get_local_ips();
for (size_t i = 0; i < ips.size(); i++) {
local_ips_cache.insert(ips[i]->ip);
}
local_ips_cached = true;
}
// Check if the IP is one of our local interface addresses
return local_ips_cache.find(ip_addr) != local_ips_cache.end();
}
// Check if resource is HTTP connection from local address
bool should_suppress_resource_log(ISrsResource* c)
{
if (!c) return false;
// Check if it's an HTTP connection based on description
std::string desc = c->desc();
bool is_http_conn = (desc == "HttpConn" || desc == "HttpsConn");
if (!is_http_conn) {
return false; // Not HTTP connection, don't suppress
}
// Try to get remote IP from connection
ISrsConnection* conn = dynamic_cast<ISrsConnection*>(c);
if (conn) {
std::string remote_ip = conn->remote_ip();
return is_local_address_for_logging(remote_ip);
}
return false;
}
ISrsDisposingHandler::ISrsDisposingHandler()
{
}
@ -246,7 +306,7 @@ void SrsResourceManager::do_remove(ISrsResource* c)
check_remove(c, in_zombie, in_disposing);
bool ignored = in_zombie || in_disposing;
if (verbose_) {
if (verbose_ && !should_suppress_resource_log(c)) {
_srs_context->set_id(c->get_id());
srs_trace("%s: before dispose resource(%s)(%p), conns=%d, zombies=%d, ign=%d, inz=%d, ind=%d",
label_.c_str(), c->desc().c_str(), c, (int)conns_.size(), (int)zombies_.size(), ignored,
@ -304,9 +364,20 @@ void SrsResourceManager::clear()
}
SrsContextRestore(cid_);
if (verbose_) {
srs_trace("%s: clear zombies=%d resources, conns=%d, removing=%d, unsubs=%d",
label_.c_str(), (int)zombies_.size(), (int)conns_.size(), removing_, (int)unsubs_.size());
if (verbose_ && !zombies_.empty()) {
// Check if we should suppress log for all zombies
bool suppress_log = true;
for (size_t i = 0; i < zombies_.size(); i++) {
if (!should_suppress_resource_log(zombies_[i])) {
suppress_log = false;
break;
}
}
if (!suppress_log) {
srs_trace("%s: clear zombies=%d resources, conns=%d, removing=%d, unsubs=%d",
label_.c_str(), (int)zombies_.size(), (int)conns_.size(), removing_, (int)unsubs_.size());
}
}
// Clear all unsubscribing handlers, if not removing any resource.
@ -328,7 +399,7 @@ void SrsResourceManager::do_clear()
for (int i = 0; i < (int)copy.size(); i++) {
ISrsResource* conn = copy.at(i);
if (verbose_) {
if (verbose_ && !should_suppress_resource_log(conn)) {
_srs_context->set_id(conn->get_id());
srs_trace("%s: disposing #%d resource(%s)(%p), conns=%d, disposing=%d, zombies=%d", label_.c_str(),
i, conn->desc().c_str(), conn, (int)conns_.size(), (int)copy.size(), (int)zombies_.size());

View File

@ -12,6 +12,7 @@
#include <stdlib.h>
#include <sstream>
#include <set>
using namespace std;
#include <srs_protocol_stream.hpp>
@ -67,6 +68,10 @@ SrsHttpConn::SrsHttpConn(ISrsHttpConnOwner* handler, ISrsProtocolReadWriter* fd,
delta_ = new SrsNetworkDelta();
delta_->set_io(skt, skt);
trd = new SrsSTCoroutine("http", this, _srs_context->get_id());
// Initialize connection state
request_completed_ = false;
requests_processed_ = 0;
}
SrsHttpConn::~SrsHttpConn()
@ -126,31 +131,8 @@ srs_error_t SrsHttpConn::cycle()
// client close peer.
// TODO: FIXME: Only reset the error when client closed it.
if (srs_is_client_gracefully_close(err)) {
// Check if we should suppress the warning for API or file requests
bool suppress_warning = false;
if (last_req_path_.length() > 0) {
// Suppress warning for API requests (starting with /api/)
if (srs_string_starts_with(last_req_path_, "/api/")) {
suppress_warning = true;
}
// Suppress warning for common static files
else if (srs_string_ends_with(last_req_path_, ".ico") ||
srs_string_ends_with(last_req_path_, ".css") ||
srs_string_ends_with(last_req_path_, ".js") ||
srs_string_ends_with(last_req_path_, ".png") ||
srs_string_ends_with(last_req_path_, ".jpg") ||
srs_string_ends_with(last_req_path_, ".gif") ||
srs_string_ends_with(last_req_path_, ".svg") ||
srs_string_ends_with(last_req_path_, ".woff") ||
srs_string_ends_with(last_req_path_, ".woff2") ||
srs_string_ends_with(last_req_path_, ".ttf")) {
suppress_warning = true;
}
// Suppress warning for console requests
else if (srs_string_starts_with(last_req_path_, "/console/")) {
suppress_warning = true;
}
}
// Check if we should suppress the warning for this connection
bool suppress_warning = should_suppress_close_warning();
if (!suppress_warning) {
srs_warn("client disconnect peer. ret=%d", srs_error_code(err));
@ -257,15 +239,22 @@ srs_error_t SrsHttpConn::process_request(ISrsHttpResponseWriter* w, ISrsHttpMess
// Store the request path for warning suppression
last_req_path_ = r->url();
requests_processed_++;
srs_trace("HTTP #%d %s:%d %s %s, content-length=%" PRId64 "", rid, ip.c_str(), port,
r->method_str().c_str(), r->url().c_str(), r->content_length());
// Only log HTTP requests if they are not from local addresses
if (!is_local_address(ip)) {
srs_trace("HTTP #%d %s:%d %s %s, content-length=%" PRId64 "", rid, ip.c_str(), port,
r->method_str().c_str(), r->url().c_str(), r->content_length());
}
// proxy to cors-->auth-->http_remux.
if ((err = cors->serve_http(w, r)) != srs_success) {
return srs_error_wrap(err, "cors serve");
}
// Mark request as successfully completed
request_completed_ = true;
return err;
}
@ -331,6 +320,48 @@ void SrsHttpConn::expire()
trd->interrupt();
}
bool SrsHttpConn::should_suppress_close_warning()
{
// If we have successfully processed at least one request, consider this a normal close
if (request_completed_ && requests_processed_ > 0) {
return true;
}
}
bool SrsHttpConn::is_local_address(const std::string& ip_addr)
{
// Check for localhost
if (ip_addr == "localhost") {
return true;
}
// Check for IPv4 loopback addresses (127.x.x.x)
if (ip_addr.find("127.") == 0) {
return true;
}
// Check for IPv6 loopback (::1)
if (ip_addr == "::1") {
return true;
}
// Get all local network interface addresses
static bool local_ips_cached = false;
static std::set<std::string> local_ips_cache;
if (!local_ips_cached) {
// Cache local IPs for performance
std::vector<SrsIPAddress*>& ips = srs_get_local_ips();
for (size_t i = 0; i < ips.size(); i++) {
local_ips_cache.insert(ips[i]->ip);
}
local_ips_cached = true;
}
// Check if the IP is one of our local interface addresses
return local_ips_cache.find(ip_addr) != local_ips_cache.end();
}
SrsHttpxConn::SrsHttpxConn(ISrsResourceManager* cm, ISrsProtocolReadWriter* io, ISrsHttpServeMux* m, string cip, int port, string key, string cert) : manager(cm), io_(io), enable_stat_(false), ssl_key_file_(key), ssl_cert_file_(cert)
{
// Create a identify for this client.

View File

@ -85,6 +85,10 @@ private:
int64_t create_time;
// The last request path for warning suppression.
std::string last_req_path_;
// Whether the request was successfully completed
bool request_completed_;
// Number of requests processed in this connection
int requests_processed_;
public:
SrsHttpConn(ISrsHttpConnOwner* handler, ISrsProtocolReadWriter* fd, ISrsHttpServeMux* m, std::string cip, int port);
virtual ~SrsHttpConn();
@ -107,6 +111,11 @@ private:
// e.g. log msg of connection and report to other system.
// @param request: request which is converted by the last http message.
virtual srs_error_t on_disconnect(SrsRequest* req);
private:
// Check if we should suppress the warning for this connection
bool should_suppress_close_warning();
// Check if the given IP address is a local address (localhost, 127.x.x.x, or local network interface)
bool is_local_address(const std::string& ip_addr);
public:
// Get the HTTP message handler.
virtual ISrsHttpConnOwner* handler();