diff options
-rw-r--r-- | README.md | 12 | ||||
-rw-r--r-- | cache/cache.go | 16 | ||||
-rw-r--r-- | cache/cache_test.go | 12 | ||||
-rw-r--r-- | http/http.go | 44 | ||||
-rw-r--r-- | http/http_test.go | 4 |
5 files changed, 69 insertions, 19 deletions
@@ -127,9 +127,15 @@ Metrics: $ curl 'http://127.0.0.1:8053/metric/v1/' | jq . { "summary": { - "since": "2020-01-05T00:58:49Z", - "total": 2307, - "hijacked": 867 + "log": { + "since": "2020-01-05T00:58:49Z", + "total": 3816, + "hijacked": 874 + }, + "cache": { + "size": 845, + "capacity": 4096 + } }, "requests": [ { diff --git a/cache/cache.go b/cache/cache.go index a0218b0..beaa5a1 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -47,6 +47,12 @@ type Value struct { msg *dns.Msg } +// Stats contains cache statistics. +type Stats struct { + Size int + Capacity int +} + // Rcode returns the response code of the cached value v. func (v *Value) Rcode() int { return v.msg.Rcode } @@ -228,6 +234,16 @@ func (c *Cache) Set(key uint32, msg *dns.Msg) { c.set(key, msg) } +// Stats returns cache statistics. +func (c *Cache) Stats() Stats { + c.mu.RLock() + defer c.mu.RUnlock() + return Stats{ + Capacity: c.capacity, + Size: len(c.values), + } +} + func (c *Cache) set(key uint32, msg *dns.Msg) bool { return c.setValue(Value{Key: key, CreatedAt: c.now(), msg: msg}) } diff --git a/cache/cache_test.go b/cache/cache_test.go index 346df25..e571f73 100644 --- a/cache/cache_test.go +++ b/cache/cache_test.go @@ -453,6 +453,18 @@ func TestCacheWithBackend(t *testing.T) { } } +func TestCacheStats(t *testing.T) { + c := New(10, nil) + msg := newA("example.com.", 60, net.ParseIP("192.0.2.1")) + c.Set(1, msg) + c.Set(2, msg) + want := Stats{Capacity: 10, Size: 2} + got := c.Stats() + if !reflect.DeepEqual(got, want) { + t.Errorf("Stats() = %+v, want %+v", got, want) + } +} + func BenchmarkNewKey(b *testing.B) { for n := 0; n < b.N; n++ { NewKey("key", 1, 1) diff --git a/http/http.go b/http/http.go index 3bf047c..3da9b4f 100644 --- a/http/http.go +++ b/http/http.go @@ -33,10 +33,14 @@ type entry struct { Rcode string `json:"rcode,omitempty"` } +type stats struct { + Summary summary `json:"summary"` + Requests []request `json:"requests"` +} + type summary struct { - Since string `json:"since"` - Total int64 `json:"total"` - Hijacked int64 `json:"hijacked"` + Log logStats `json:"log"` + Cache cacheStats `json:"cache"` } type request struct { @@ -45,8 +49,14 @@ type request struct { } type logStats struct { - Summary summary `json:"summary"` - Requests []request `json:"requests"` + Since string `json:"since"` + Total int64 `json:"total"` + Hijacked int64 `json:"hijacked"` +} + +type cacheStats struct { + Size int `json:"size"` + Capacity int `json:"capacity"` } type httpError struct { @@ -137,26 +147,32 @@ func (s *Server) logHandler(w http.ResponseWriter, r *http.Request) (interface{} } func (s *Server) metricHandler(w http.ResponseWriter, r *http.Request) (interface{}, *httpError) { - stats, err := s.logger.Stats() + lstats, err := s.logger.Stats() if err != nil { return nil, newHTTPError(err) } - requests := make([]request, 0, len(stats.Events)) - for _, e := range stats.Events { + requests := make([]request, 0, len(lstats.Events)) + for _, e := range lstats.Events { requests = append(requests, request{ Time: e.Time.Format(time.RFC3339), Count: e.Count, }) } - logStats := logStats{ + cstats := s.cache.Stats() + return stats{ Summary: summary{ - Since: stats.Since.Format(time.RFC3339), - Total: stats.Total, - Hijacked: stats.Hijacked, + Log: logStats{ + Since: lstats.Since.Format(time.RFC3339), + Total: lstats.Total, + Hijacked: lstats.Hijacked, + }, + Cache: cacheStats{ + Capacity: cstats.Capacity, + Size: cstats.Size, + }, }, Requests: requests, - } - return logStats, nil + }, nil } // Close shuts down the HTTP server. diff --git a/http/http_test.go b/http/http_test.go index 901903f..2909271 100644 --- a/http/http_test.go +++ b/http/http_test.go @@ -89,7 +89,7 @@ func TestRequests(t *testing.T) { lr1 := `[{"time":"RFC3339","remote_addr":"127.0.0.254","hijacked":true,"type":"AAAA","question":"example.com.","answers":["2001:db8::1"]},` + `{"time":"RFC3339","remote_addr":"127.0.0.42","hijacked":false,"type":"A","question":"example.com.","answers":["192.0.2.101","192.0.2.100"]}]` lr2 := `[{"time":"RFC3339","remote_addr":"127.0.0.254","hijacked":true,"type":"AAAA","question":"example.com.","answers":["2001:db8::1"]}]` - mr1 := `{"summary":{"since":"RFC3339","total":2,"hijacked":1},"requests":[{"time":"RFC3339","count":2}]}` + mr1 := `{"summary":{"log":{"since":"RFC3339","total":2,"hijacked":1},"cache":{"size":2,"capacity":10}},"requests":[{"time":"RFC3339","count":2}]}` var tests = []struct { method string @@ -104,8 +104,8 @@ func TestRequests(t *testing.T) { {http.MethodGet, "/cache/v1/", cr1, 200}, {http.MethodGet, "/cache/v1/?n=foo", cr1, 200}, {http.MethodGet, "/cache/v1/?n=1", cr2, 200}, - {http.MethodDelete, "/cache/v1/", `{"message":"Cleared cache."}`, 200}, {http.MethodGet, "/metric/v1/", mr1, 200}, + {http.MethodDelete, "/cache/v1/", `{"message":"Cleared cache."}`, 200}, } for i, tt := range tests { |