diff --git a/src/facade/dragonfly_listener.cc b/src/facade/dragonfly_listener.cc index b8095faeb..c3f4303bd 100644 --- a/src/facade/dragonfly_listener.cc +++ b/src/facade/dragonfly_listener.cc @@ -156,25 +156,30 @@ bool ConfigureKeepAlive(int fd) { return true; } -thread_local size_t ssl_allocated_bytes = 0; +struct ListenerStats { + size_t tls_allocated_bytes = 0; + uint64_t refused_conn_maxclients_reached_cnt = 0; +}; + +thread_local ListenerStats listener_tl_stats; atomic_int ssl_init_refcount = 0; void* OverriddenSSLMalloc(size_t size, const char* file, int line) { void* res = mi_malloc(size); - ssl_allocated_bytes += mi_malloc_usable_size(res); + listener_tl_stats.tls_allocated_bytes += mi_malloc_usable_size(res); return res; } void* OverriddenSSLRealloc(void* addr, size_t size, const char* file, int line) { size_t prev_size = mi_malloc_usable_size(addr); void* res = mi_realloc(addr, size); - ssl_allocated_bytes += mi_malloc_usable_size(res); - ssl_allocated_bytes -= prev_size; + listener_tl_stats.tls_allocated_bytes += mi_malloc_usable_size(res); + listener_tl_stats.tls_allocated_bytes -= prev_size; return res; } void OverriddenSSLFree(void* addr, const char* file, int line) { - ssl_allocated_bytes -= mi_malloc_usable_size(addr); + listener_tl_stats.tls_allocated_bytes -= mi_malloc_usable_size(addr); mi_free(addr); } @@ -274,7 +279,11 @@ bool Listener::ReconfigureTLS() { } size_t Listener::TLSUsedMemoryThreadLocal() { - return ssl_allocated_bytes; + return listener_tl_stats.tls_allocated_bytes; +} + +uint64_t Listener::RefusedConnectionMaxClientsCount() { + return listener_tl_stats.refused_conn_maxclients_reached_cnt; } void Listener::PreAcceptLoop(util::ProactorBase* pb) { @@ -356,6 +365,7 @@ void Listener::OnConnectionClose(util::Connection* conn) { } void Listener::OnMaxConnectionsReached(util::FiberSocketBase* sock) { + listener_tl_stats.refused_conn_maxclients_reached_cnt++; sock->Write(io::Buffer("-ERR max number of clients reached\r\n")); } diff --git a/src/facade/dragonfly_listener.h b/src/facade/dragonfly_listener.h index aa58b691e..4edac5bb5 100644 --- a/src/facade/dragonfly_listener.h +++ b/src/facade/dragonfly_listener.h @@ -45,6 +45,7 @@ class Listener : public util::ListenerInterface { // Returns thread-local dynamic memory usage by TLS. static size_t TLSUsedMemoryThreadLocal(); + static uint64_t RefusedConnectionMaxClientsCount(); bool IsPrivilegedInterface() const; bool IsMainInterface() const; diff --git a/src/server/server_family.cc b/src/server/server_family.cc index ce39c7768..4b2c44ab1 100644 --- a/src/server/server_family.cc +++ b/src/server/server_family.cc @@ -1152,6 +1152,11 @@ void PrintPrometheusMetrics(const Metrics& m, StringResponse* resp) { AppendMetricWithoutLabels("script_error_total", "", m.facade_stats.reply_stats.script_error_count, MetricType::COUNTER, &resp->body()); + AppendMetricHeader("listener_accept_error_total", "Listener accept errors", MetricType::COUNTER, + &resp->body()); + AppendMetricValue("listener_accept_error_total", m.refused_conn_max_clients_reached_count, + {"reason"}, {"limit_reached"}, &resp->body()); + // DB stats AppendMetricWithoutLabels("expired_keys_total", "", m.events.expired_keys, MetricType::COUNTER, &resp->body()); @@ -1860,6 +1865,7 @@ Metrics ServerFamily::GetMetrics() const { } result.tls_bytes += Listener::TLSUsedMemoryThreadLocal(); + result.refused_conn_max_clients_reached_count += Listener::RefusedConnectionMaxClientsCount(); service_.mutable_registry()->MergeCallStats(index, cmd_stat_cb); }; diff --git a/src/server/server_family.h b/src/server/server_family.h index e81457b26..0c6824112 100644 --- a/src/server/server_family.h +++ b/src/server/server_family.h @@ -96,6 +96,7 @@ struct Metrics { uint64_t fiber_switch_cnt = 0; uint64_t fiber_switch_delay_usec = 0; uint64_t tls_bytes = 0; + uint64_t refused_conn_max_clients_reached_count = 0; // Statistics about fibers running for a long time (more than 1ms). uint64_t fiber_longrun_cnt = 0;