Source File
stats.go
Belonging Package
go.pact.im/x/httptrack
package httptrackimport ()// counterSize is the count of [http.ConnState] states that are used for// counter-based statistics.const counterSize = http.StateClosed + 1 // all states// gaugeSize is the count of [http.ConnState] states that are used for// gauge-based statistics.const gaugeSize = http.StateIdle + 1 // non-terminal states// Stats holds a snapshot of HTTP connection state statistics.type Stats struct {counter [counterSize]uint64gauge [gaugeSize]uint}// Accepted returns the number of connections currently in the [http.StateNew]// state.//// A non-zero value typically indicates that there are accepted connections// which have not yet sent a complete HTTP request. This may occur naturally// under normal traffic, but a persistently high number of connections in this// state can suggest://// - Slow or high-latency clients// - Clients intentionally delaying requests (e.g. denial-of-service attack)// - Server under heavy load or accepting connections faster than it can// process themfunc ( *Stats) () uint {return .gauge[http.StateNew]}// Active returns the number of connections currently in the [http.StateActive]// state.//// In HTTP/1.x, this usually means that a request is currently being processed.//// In HTTP/2, this state indicates that the connection has at least one open// stream. However, the connection may briefly enter the Active state after// being accepted as part of reading the HTTP/2 connection preface, before// transitioning to Idle state. Therefore, a connection in the Active state// is not guaranteed to be actively handling a request.func ( *Stats) () uint {return .gauge[http.StateActive]}// Idle returns the number of connections currently in the [http.StateIdle]// state.//// In HTTP/1.x, Idle connections are typically those that have completed// a request and are being kept alive. A non-zero Idle count is normal in// servers that support HTTP keep-alive.//// In HTTP/2, this state indicates that the connection has no open streams.// A newly established HTTP/2 connection enters the Idle state after reading// the connection preface.func ( *Stats) () uint {return .gauge[http.StateIdle]}// AcceptedTotal returns the total number of connections ever seen in the// [http.StateNew] state.//// This is a monotonically increasing counter that reflects the cumulative// number of accepted connections. It includes all connections, regardless of// whether they were later closed, hijacked, or reused.func ( *Stats) () uint64 {return .counter[http.StateNew]}// ActiveTotal returns the total number of times connections have transitioned// into the [http.StateActive] state.//// This counter increases every time a connection becomes active. It does not// represent the number of requests, since a single connection may enter Active// state for multiple requests (e.g. HTTP/2 streams).func ( *Stats) () uint64 {return .counter[http.StateActive]}// IdleTotal returns the total number of times connections have entered the// [http.StateIdle] state.func ( *Stats) () uint64 {return .counter[http.StateIdle]}// HijackedTotal returns the number of connections that have been hijacked via// [http.Hijacker].//// A hijacked connection is taken over by the application (e.g. for WebSocket// upgrade) and is no longer managed by the HTTP server.func ( *Stats) () uint64 {return .counter[http.StateHijacked]}// ClosedTotal returns the number of connections that have been closed.//// A non-zero Closed count indicates connections that have been fully closed// by either the server or the client, including normal connection termination// and error scenarios.//// High numbers in Closed are typical over time, but a sudden spike may// indicate://// - Mass client disconnects// - Server-side timeouts or errors// - Deployment cycles or load balancer resetsfunc ( *Stats) () uint64 {return .counter[http.StateClosed]}// StatsTracker is a [Tracker] implementation that keeps counts of HTTP// connections in each state. It can be used for monitoring connections// and their lifecycle.type StatsTracker struct {mu sync.Mutexconns map[net.Conn]http.ConnStatestats Stats}// Track records the transition of a connection’s state. It updates internal// statistics and tracks the current state of each connection.//// The dynamic type of the provided net.Conn must be comparable (i.e. usable as// a map key). Most standard connection types (such as tls.Conn pointer) meet// this requirement. Passing a non-comparable type will cause a runtime panic.func ( *StatsTracker) ( net.Conn, http.ConnState) {.mu.Lock()defer .mu.Unlock().stats.counter[]++if , := .conns[]; {.stats.gauge[]--}switch {case http.StateHijacked, http.StateClosed:delete(.conns, )default: // non-terminal statesif .conns == nil {.conns = make(map[net.Conn]http.ConnState)}.conns[] =.stats.gauge[]++}}// Stats returns a snapshot of connection statistics.func ( *StatsTracker) () Stats {.mu.Lock()defer .mu.Unlock()return .stats}// Connections returns a snapshot of connection states.func ( *StatsTracker) () map[net.Conn]http.ConnState {.mu.Lock()defer .mu.Unlock()// Note that we return the original map instead of a cloned map. That// is, as a side effect of this method, the internal map is shrunk.// See https://go.dev/issue/20135 and https://antonz.org/go-map-shrinkvar map[net.Conn]http.ConnState.conns, = maps.Clone(.conns), .connsreturn}
The pages are generated with Golds v0.7.6. (GOOS=linux GOARCH=amd64)