diff --git a/metrics/counters.go b/metrics/counters.go index 95090f4..12d6bb5 100644 --- a/metrics/counters.go +++ b/metrics/counters.go @@ -10,9 +10,9 @@ var msgCounters [4]uint64 var msgLast [4]uint64 var msgCurrent [4]uint64 -var httpCounters [8]uint64 -var httpLast [8]uint64 -var httpCurrent [8]uint64 +var httpCounters [9]uint64 +var httpLast [9]uint64 +var httpCurrent [9]uint64 // A MsgCounters records message counters. type MsgCounters struct { @@ -55,6 +55,9 @@ type HttpCounters struct { // StatusServiceUnavailable is the count of http 503 responses. StatusServiceUnavailable uint64 + // StatusTooManyRequests is the count of http 429 responses. + StatusTooManyRequests uint64 + // Written is the number of bytes written. Written uint64 @@ -97,7 +100,8 @@ func ReadHttpCounters(m *HttpCounters) { m.StatusNotFound = httpCurrent[4] - httpLast[4] m.StatusInternalServerError = httpCurrent[5] - httpLast[5] m.StatusServiceUnavailable = httpCurrent[6] - httpLast[6] - m.Written = httpCurrent[7] - httpLast[7] + m.StatusTooManyRequests = httpCurrent[7] - httpLast[7] + m.Written = httpCurrent[8] - httpLast[8] for i := range httpCounters { httpLast[i] = httpCurrent[i] @@ -159,7 +163,12 @@ func StatusServiceUnavailable() { atomic.AddUint64(&httpCounters[6], 1) } +// StatusTooManyRequests increments the http response 429 counter. It is safe for concurrent access. +func StatusTooManyRequests() { + atomic.AddUint64(&httpCounters[7], 1) +} + // Written increments the bytes sent counter by n. func Written(n int64) { - atomic.AddUint64(&httpCounters[7], uint64(n)) //nolint:gosec + atomic.AddUint64(&httpCounters[8], uint64(n)) //nolint:gosec } diff --git a/metrics/counters_test.go b/metrics/counters_test.go index fb38846..0f23f6f 100644 --- a/metrics/counters_test.go +++ b/metrics/counters_test.go @@ -79,6 +79,7 @@ func TestHttpCounters(t *testing.T) { {i: l(), f: metrics.StatusNotFound, e: metrics.HttpCounters{StatusNotFound: 1}}, {i: l(), f: metrics.StatusInternalServerError, e: metrics.HttpCounters{StatusInternalServerError: 1}}, {i: l(), f: metrics.StatusServiceUnavailable, e: metrics.HttpCounters{StatusServiceUnavailable: 1}}, + {i: l(), f: metrics.StatusTooManyRequests, e: metrics.HttpCounters{StatusTooManyRequests: 1}}, } var m metrics.HttpCounters @@ -108,6 +109,9 @@ func TestHttpCounters(t *testing.T) { if m.StatusServiceUnavailable != 0 { t.Errorf("expected 0 got %d", m.StatusServiceUnavailable) } + if m.StatusTooManyRequests != 0 { + t.Errorf("expected 0 got %d", m.StatusTooManyRequests) + } // increment one counter // and check we incremented the correct counter @@ -136,7 +140,9 @@ func TestHttpCounters(t *testing.T) { if m.StatusServiceUnavailable != v.e.StatusServiceUnavailable { t.Errorf("%s StatusServiceUnavailable expected %d got %d", v.i, v.e.StatusServiceUnavailable, m.StatusServiceUnavailable) } - + if m.StatusTooManyRequests != v.e.StatusTooManyRequests { + t.Errorf("%s StatusTooManyRequests expected %d got %d", v.i, v.e.StatusTooManyRequests, m.StatusTooManyRequests) + } } } diff --git a/weft/handlers.go b/weft/handlers.go index 36dd0df..7eb3aec 100644 --- a/weft/handlers.go +++ b/weft/handlers.go @@ -304,6 +304,9 @@ func writeResponseAndLogMetrics(err error, w http.ResponseWriter, r *http.Reques case http.StatusServiceUnavailable: metrics.StatusServiceUnavailable() logger.Printf("%d %s %s %s %s", status, r.Method, r.RequestURI, name, err.Error()) + case http.StatusTooManyRequests: + metrics.StatusTooManyRequests() + logger.Printf("%d %s %s %s %s", status, r.Method, r.RequestURI, name, err.Error()) } }