From ceaff84709dfd014ec73a6e7bb0dd6ef48d2b19e Mon Sep 17 00:00:00 2001 From: Martin Polden Date: Fri, 11 Sep 2020 20:52:35 +0200 Subject: [PATCH] http, cache: Expose cache stats --- http/cache.go | 15 +++++++++++++++ http/http.go | 19 +++++++++++++++++++ http/http_test.go | 15 +++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/http/cache.go b/http/cache.go index 8ea55de..97aac30 100644 --- a/http/cache.go +++ b/http/cache.go @@ -2,6 +2,7 @@ package http import ( "container/list" + "fmt" "hash/fnv" "net" "sync" @@ -14,6 +15,11 @@ type Cache struct { values *list.List } +type CacheStats struct { + Capacity int + Size int +} + func NewCache(capacity int) *Cache { if capacity < 0 { capacity = 0 @@ -63,3 +69,12 @@ func (c *Cache) Get(ip net.IP) (Response, bool) { } return r.Value.(Response), true } + +func (c *Cache) Stats() CacheStats { + c.mu.RLock() + defer c.mu.RUnlock() + return CacheStats{ + Size: len(c.entries), + Capacity: c.capacity, + } +} diff --git a/http/http.go b/http/http.go index c41ef65..940684f 100644 --- a/http/http.go +++ b/http/http.go @@ -271,6 +271,24 @@ func (s *Server) PortHandler(w http.ResponseWriter, r *http.Request) *appError { return nil } +func (s *Server) cacheHandler(w http.ResponseWriter, r *http.Request) *appError { + cacheStats := s.cache.Stats() + var data = struct { + Size int `json:"size"` + Capacity int `json:"capacity"` + }{ + cacheStats.Size, + cacheStats.Capacity, + } + b, err := json.Marshal(data) + if err != nil { + return internalServerError(err).AsJSON() + } + w.Header().Set("Content-Type", jsonMediaType) + w.Write(b) + return nil +} + func (s *Server) DefaultHandler(w http.ResponseWriter, r *http.Request) *appError { response, err := s.newResponse(r) if err != nil { @@ -391,6 +409,7 @@ func (s *Server) Handler() http.Handler { // Profiling if s.profile { + r.Route("GET", "/debug/cache/", s.cacheHandler) r.Route("GET", "/debug/pprof/cmdline", wrapHandlerFunc(pprof.Cmdline)) r.Route("GET", "/debug/pprof/profile", wrapHandlerFunc(pprof.Profile)) r.Route("GET", "/debug/pprof/symbol", wrapHandlerFunc(pprof.Symbol)) diff --git a/http/http_test.go b/http/http_test.go index 61c1d72..f081510 100644 --- a/http/http_test.go +++ b/http/http_test.go @@ -160,6 +160,21 @@ func TestJSONHandlers(t *testing.T) { } } +func TestCacheHandler(t *testing.T) { + log.SetOutput(ioutil.Discard) + srv := testServer() + srv.profile = true + s := httptest.NewServer(srv.Handler()) + got, _, err := httpGet(s.URL+"/debug/cache/", jsonMediaType, "") + if err != nil { + t.Fatal(err) + } + want := `{"size":0,"capacity":100}` + if got != want { + t.Errorf("got %q, want %q", got, want) + } +} + func TestIPFromRequest(t *testing.T) { var tests = []struct { remoteAddr string