Browse Source

Track top clients by IP address, add top= option to status page

Ask Bjørn Hansen 12 years ago
parent
commit
8459fa8c5d
6 changed files with 125 additions and 84 deletions
  1. 20 4
      monitor.go
  2. 8 5
      serve.go
  3. 1 0
      serve_test.go
  4. 22 8
      status.html
  5. 71 67
      status.html.go
  6. 3 0
      zone.go

+ 20 - 4
monitor.go

@@ -12,6 +12,7 @@ import (
 	"os"
 	"os"
 	"runtime"
 	"runtime"
 	"sort"
 	"sort"
+	"strconv"
 	"time"
 	"time"
 )
 )
 
 
@@ -265,6 +266,19 @@ func StatusServer(zones Zones) func(http.ResponseWriter, *http.Request) {
 
 
 	return func(w http.ResponseWriter, req *http.Request) {
 	return func(w http.ResponseWriter, req *http.Request) {
 
 
+		req.ParseForm()
+
+		topOption := 10
+		topParam := req.Form["top"]
+
+		if len(topParam) > 0 {
+			var err error
+			topOption, err = strconv.Atoi(topParam[0])
+			if err != nil {
+				topOption = 10
+			}
+		}
+
 		tmpl := template.New("status_html")
 		tmpl := template.New("status_html")
 		tmpl, err := tmpl.Parse(string(status_html()))
 		tmpl, err := tmpl.Parse(string(status_html()))
 
 
@@ -297,15 +311,17 @@ func StatusServer(zones Zones) func(http.ResponseWriter, *http.Request) {
 				Histogram       histogramData
 				Histogram       histogramData
 				HistogramRecent histogramData
 				HistogramRecent histogramData
 			}
 			}
+			TopOption int
 		}
 		}
 
 
 		uptime := DayDuration{time.Since(timeStarted)}
 		uptime := DayDuration{time.Since(timeStarted)}
 
 
 		status := statusData{
 		status := statusData{
-			Version:  VERSION,
-			Zones:    rates,
-			Uptime:   uptime,
-			Platform: runtime.GOARCH + "-" + runtime.GOOS,
+			Version:   VERSION,
+			Zones:     rates,
+			Uptime:    uptime,
+			Platform:  runtime.GOARCH + "-" + runtime.GOOS,
+			TopOption: topOption,
 		}
 		}
 
 
 		status.Global.Queries = metrics.Get("queries").(*metrics.StandardMeter)
 		status.Global.Queries = metrics.Get("queries").(*metrics.StandardMeter)

+ 8 - 5
serve.go

@@ -40,7 +40,10 @@ func serve(w dns.ResponseWriter, req *dns.Msg, z *Zone) {
 
 
 	z.Metrics.LabelStats.Add(label)
 	z.Metrics.LabelStats.Add(label)
 
 
-	var ip string
+	realIp, _, _ := net.SplitHostPort(w.RemoteAddr().String())
+	z.Metrics.ClientStats.Add(realIp)
+
+	var ip string // EDNS or real IP
 	var edns *dns.EDNS0_SUBNET
 	var edns *dns.EDNS0_SUBNET
 	var opt_rr *dns.OPT
 	var opt_rr *dns.OPT
 
 
@@ -65,15 +68,15 @@ func serve(w dns.ResponseWriter, req *dns.Msg, z *Zone) {
 		}
 		}
 	}
 	}
 
 
+	if len(ip) == 0 { // no edns subnet
+		ip = realIp
+	}
+
 	var country string
 	var country string
 	var netmask int
 	var netmask int
 	if geoIP != nil {
 	if geoIP != nil {
-		if len(ip) == 0 { // no edns subnet
-			ip, _, _ = net.SplitHostPort(w.RemoteAddr().String())
-		}
 		country, netmask = geoIP.GetCountry(ip)
 		country, netmask = geoIP.GetCountry(ip)
 		country = strings.ToLower(country)
 		country = strings.ToLower(country)
-		logPrintln("Country:", ip, country)
 	}
 	}
 
 
 	m := new(dns.Msg)
 	m := new(dns.Msg)

+ 1 - 0
serve_test.go

@@ -95,6 +95,7 @@ func (s *ServeSuite) TestServingEDNS(c *C) {
 	r = exchangeSubnet(c, "www.test.example.com.", dns.TypeA, "194.239.134.1")
 	r = exchangeSubnet(c, "www.test.example.com.", dns.TypeA, "194.239.134.1")
 	c.Check(r.Answer, HasLen, 1)
 	c.Check(r.Answer, HasLen, 1)
 	if len(r.Answer) > 0 {
 	if len(r.Answer) > 0 {
+		// EDNS-SUBNET test (request A, respond CNAME)
 		c.Check(r.Answer[0].(*dns.CNAME).Target, Equals, "geo-europe.bitnames.com.")
 		c.Check(r.Answer[0].(*dns.CNAME).Target, Equals, "geo-europe.bitnames.com.")
 	}
 	}
 
 

+ 22 - 8
status.html

@@ -97,6 +97,8 @@
 <th>Mean QPS</th>
 <th>Mean QPS</th>
 </tr>
 </tr>
 
 
+{{ $topOption := .TopOption}}
+
 {{range  .Zones }}
 {{range  .Zones }}
 
 
 	<tr class="info">
 	<tr class="info">
@@ -119,21 +121,33 @@
 		<td>{{printf "%.2f" .Metrics.EdnsQueries.RateMean}}</td>
 		<td>{{printf "%.2f" .Metrics.EdnsQueries.RateMean}}</td>
 	</tr>
 	</tr>
 
 
-	{{ $counts := .Metrics.LabelStats.TopCounts 10 }}
+	{{ $counts := .Metrics.LabelStats.TopCounts $topOption }}
 
 
 	{{ if $counts }}
 	{{ if $counts }}
-	<tr class="info">
-		<td colspan=5>Labels</td>
-	</tr>
-
-	{{range $counts }}
-		<tr>
-			<td colspan=4>{{.Label}}</td><td>{{.Count}}</td>
+		<tr class="info">
+			<td colspan=5>Labels</td>
 		</tr>
 		</tr>
+		{{range $counts }}
+			<tr>
+				<td colspan=4>{{.Label}}</td><td>{{.Count}}</td>
+			</tr>
+		{{end}}
 	{{end}}
 	{{end}}
 
 
+	{{ $clients := .Metrics.ClientStats.TopCounts $topOption }}
+
+	{{ if $clients }}
+		<tr class="info">
+			<td colspan=5>Clients</td>
+		</tr>
+		{{range $clients }}
+			<tr>
+				<td colspan=4>{{.Label}}</td><td>{{.Count}}</td>
+			</tr>
+		{{end}}
 	{{end}}
 	{{end}}
 
 
+
 {{end}}
 {{end}}
 
 
 </table>
 </table>

+ 71 - 67
status.html.go

@@ -12,73 +12,77 @@ import (
 func status_html() []byte {
 func status_html() []byte {
 	gz, err := gzip.NewReader(bytes.NewBuffer([]byte{
 	gz, err := gzip.NewReader(bytes.NewBuffer([]byte{
 0x1f,0x8b,0x08,0x00,0x00,0x09,0x6e,0x88,0x00,0xff,0xb4,0x57,
 0x1f,0x8b,0x08,0x00,0x00,0x09,0x6e,0x88,0x00,0xff,0xb4,0x57,
-0x4d,0x73,0xe2,0x38,0x10,0x3d,0xc3,0xaf,0x50,0xb9,0x36,0xb7,
-0x8d,0x1c,0x67,0x43,0xd5,0x92,0x35,0xbe,0x6c,0x52,0xd9,0xc3,
-0x92,0x4a,0xc2,0xee,0x1c,0xe6,0x26,0xac,0x06,0xbb,0xc6,0x48,
-0x94,0xd4,0x84,0x64,0x5c,0xf9,0xef,0x23,0xcb,0x1f,0x18,0x0c,
-0x04,0x34,0x35,0x17,0x2c,0x3f,0xe9,0xa9,0x3f,0x5e,0x5b,0x2d,
-0xc2,0x04,0x17,0x59,0x14,0x26,0xc0,0x78,0x14,0x62,0x8a,0x19,
-0x44,0x0f,0x20,0xef,0x1e,0x27,0x24,0xcf,0x09,0xfd,0x02,0x4a,
-0xa7,0x52,0x90,0x8f,0x8f,0xd0,0x2f,0x27,0xfb,0x61,0x96,0x8a,
-0x6f,0x24,0x51,0x30,0x1b,0x79,0xbe,0x2f,0x00,0xb9,0x60,0x74,
-0x2a,0x25,0x6a,0x54,0x6c,0x19,0x73,0x41,0x63,0xb9,0xf0,0x71,
-0x9d,0x22,0x82,0xba,0x6c,0x26,0xfc,0x6b,0xfa,0x07,0x0d,0xfc,
-0x58,0x6b,0xbf,0xc1,0x2e,0xcd,0xca,0x69,0x2a,0x80,0xd3,0x45,
-0x6a,0x68,0x5a,0x7b,0x44,0x41,0x36,0xf2,0x34,0xbe,0x67,0xa0,
-0x13,0x00,0xf4,0x4e,0xb5,0x67,0x81,0x35,0xc3,0x38,0xa9,0x0d,
-0x81,0x5a,0x65,0xc0,0xc4,0xc6,0xda,0x51,0x23,0xf6,0x2d,0xea,
-0xf7,0x90,0xd3,0xef,0x52,0x80,0x60,0x0b,0xf8,0xdd,0x8c,0x8b,
-0xb4,0x80,0x22,0x39,0x99,0x49,0x81,0x97,0x6b,0x48,0xe7,0x09,
-0xde,0x92,0xa9,0xcc,0xf8,0x5f,0xe4,0xa3,0x1f,0xfa,0x15,0x2d,
-0x9c,0x4a,0xfe,0x1e,0xf5,0xfb,0x21,0x4f,0x5f,0x49,0x9c,0x31,
-0xad,0x47,0x5e,0x6c,0x18,0xcc,0x04,0xa7,0xbc,0x62,0x22,0x09,
-0xa2,0x87,0x4c,0x4e,0x59,0x16,0xfa,0x66,0xb8,0xbd,0x52,0xc9,
-0x75,0xb1,0xa6,0xd7,0xc6,0xf4,0x92,0x89,0x3f,0x2d,0xda,0x0b,
-0x91,0x4d,0x33,0xa8,0x27,0xca,0x17,0xfb,0x6b,0x92,0xab,0x8c,
-0x77,0xc0,0xab,0x57,0x63,0x91,0x83,0xd0,0xc0,0x0d,0xaf,0x57,
-0xf0,0x94,0x7d,0x9a,0x01,0xaf,0xd9,0xa9,0x98,0x49,0x52,0x06,
-0xe5,0x55,0x0e,0x11,0x8d,0x0c,0xb5,0x91,0x97,0x37,0xab,0xa3,
-0x80,0x98,0x5c,0x6d,0x43,0x83,0x2e,0x14,0xec,0xc1,0xc6,0x26,
-0xe5,0x0d,0x62,0x06,0xca,0x86,0xb0,0xe5,0x4b,0xf4,0xbc,0x02,
-0x95,0xc2,0x8e,0xc9,0x3c,0x5f,0xaa,0x54,0xe0,0x8c,0x78,0x17,
-0xf4,0x7a,0xe6,0x11,0x5a,0x7a,0x47,0xab,0xc5,0xf4,0x85,0x21,
-0x04,0xb6,0x0c,0xcf,0x24,0x0d,0x5c,0x48,0x81,0x13,0xab,0x08,
-0xbe,0xc5,0x2b,0xc3,0xb7,0xcf,0x42,0x9f,0x5f,0x2b,0xe6,0x3f,
-0xa9,0x46,0x39,0x57,0x6c,0xb1,0x93,0xd7,0xf1,0x51,0x85,0x2c,
-0x32,0xbc,0xba,0xd8,0x01,0x86,0x1d,0x80,0xee,0x42,0x63,0xf6,
-0xb6,0x0d,0x4c,0x90,0xdf,0xc1,0xeb,0x67,0xda,0x4f,0x52,0x11,
-0x43,0x51,0x72,0x0a,0x0f,0xe6,0x97,0x7b,0x84,0x34,0xf9,0x6d,
-0xe2,0xa2,0x26,0x92,0x53,0x45,0x69,0x91,0xb6,0x25,0x39,0x91,
-0xf5,0x14,0xe3,0xf0,0x8a,0xb8,0xf1,0x86,0xae,0xbc,0xa3,0xc4,
-0x43,0x39,0x61,0x6f,0xe7,0x5b,0x2b,0x95,0x22,0x9d,0x4a,0xed,
-0x88,0xf5,0x02,0x31,0x88,0x73,0x75,0x2a,0x49,0x4e,0x6a,0xd5,
-0x54,0x17,0xcd,0x2a,0xae,0xa3,0x72,0x2d,0xb6,0x83,0x7e,0x6d,
-0xb6,0x83,0x8a,0x75,0xd8,0x0e,0x5a,0x56,0xd4,0x23,0x8a,0xb6,
-0x0e,0x9f,0xd0,0x37,0x0d,0x66,0x5f,0xa3,0xb9,0xf9,0xa9,0x46,
-0x53,0x97,0x4c,0xeb,0x64,0xaa,0x0f,0xa5,0xff,0x97,0x98,0x2e,
-0x60,0xe3,0x94,0x0d,0x89,0x96,0x28,0xbd,0x63,0xef,0x13,0x34,
-0xe1,0xcd,0x37,0x6e,0x37,0x27,0xe6,0xe1,0x2d,0x9f,0x32,0x86,
-0x33,0xa9,0x16,0xbb,0x9b,0xd6,0xf8,0x9e,0xcd,0xba,0x19,0x68,
-0x9e,0xa6,0x17,0x7f,0x35,0xed,0x5e,0x97,0x5d,0xd9,0x29,0x01,
-0xd6,0xd7,0x10,0x93,0xc8,0xd8,0x49,0xca,0x91,0x6d,0x9f,0x2b,
-0x84,0x0d,0x32,0xa8,0x10,0xdd,0x5a,0xb4,0x07,0x2b,0x2a,0x9f,
-0x3c,0x3f,0x4d,0x2a,0xa4,0xd4,0x30,0xcf,0x15,0x13,0x73,0x30,
-0x85,0x63,0x5d,0x35,0x2a,0x17,0x91,0xa0,0x6a,0xb7,0x81,0x4a,
-0x08,0x93,0x2d,0x99,0x15,0x8a,0x8e,0x06,0xf5,0x6c,0x7d,0x9b,
-0xf1,0x8a,0x24,0x3d,0x9a,0x41,0x93,0xa0,0xba,0x44,0xc2,0x3a,
-0xe7,0x9d,0xce,0xbc,0xb7,0x04,0xc7,0x60,0x44,0x8b,0xf5,0xa1,
-0xc6,0x7c,0x32,0x67,0xe0,0xc0,0x09,0x5c,0x48,0x5b,0xc7,0xc9,
-0x9e,0xa0,0xef,0x8b,0xcb,0xee,0x39,0x91,0xdf,0x73,0xa1,0x5d,
-0xa2,0xdf,0xe5,0x9d,0x1a,0x4c,0xc7,0x9e,0x2b,0x71,0x6f,0x26,
-0xcc,0x35,0xff,0xb7,0x58,0xae,0x04,0x6a,0x72,0x3b,0xda,0x70,
-0xff,0x65,0x53,0xc8,0x26,0xc5,0xd5,0x90,0xfe,0x27,0x97,0x7f,
-0x97,0x0b,0x82,0xab,0xb2,0xfa,0x0c,0x27,0x9d,0x35,0x34,0x03,
-0x7d,0x5e,0x8f,0x91,0xdd,0x50,0x77,0x8c,0x97,0xb5,0xdd,0xde,
-0x6a,0xfb,0xeb,0xaf,0xf8,0x37,0x45,0xf9,0xda,0x2d,0xaa,0x00,
-0xaa,0xcf,0xde,0x3a,0xd6,0xf9,0xe6,0xf3,0x1c,0x04,0xaf,0x3c,
-0xad,0x46,0xcd,0x60,0x73,0x1c,0x6c,0x4e,0x83,0xf2,0xfa,0x6e,
-0x0e,0x81,0xe2,0xbf,0x50,0xff,0x47,0x00,0x00,0x00,0xff,0xff,
-0xf9,0x56,0x1c,0xc4,0x13,0x0d,0x00,0x00,
+0x41,0x73,0xf2,0x36,0x10,0x3d,0xc3,0xaf,0xd0,0x78,0xfa,0xdd,
+0x1a,0x39,0xa4,0x61,0xa6,0xa4,0xc6,0x97,0x24,0x93,0x1e,0x4a,
+0x9a,0x84,0xb6,0x87,0xde,0x84,0xb5,0x60,0x4d,0x8d,0xc4,0x48,
+0x22,0x24,0x65,0xf8,0xef,0x95,0x64,0xcb,0xd8,0xc6,0x50,0xf0,
+0x37,0xb9,0xc4,0xf2,0xb3,0xde,0x4a,0x6f,0xdf,0x46,0x2b,0xa2,
+0x54,0x2f,0xb3,0x38,0x4a,0x81,0xd0,0x38,0xd2,0x4c,0x67,0x10,
+0x3f,0x81,0x78,0x78,0x9e,0xa2,0xed,0x16,0xe1,0xbf,0x40,0x2a,
+0x26,0x38,0xda,0xed,0xa2,0x30,0xff,0xd8,0x8f,0x32,0xc6,0xff,
+0x41,0xa9,0x84,0xf9,0x38,0x08,0x43,0x0e,0x9a,0x72,0x82,0x67,
+0x42,0x68,0xa5,0x25,0x59,0x25,0x94,0xe3,0x44,0x2c,0x43,0xbd,
+0x61,0x5a,0x83,0xbc,0x2a,0x3f,0x84,0x37,0xf8,0x27,0x3c,0x08,
+0x13,0xa5,0xc2,0x12,0xbb,0x32,0x33,0x67,0x8c,0x03,0xc5,0x4b,
+0x66,0x68,0x4a,0x05,0x48,0x42,0x36,0x0e,0x94,0xfe,0xcc,0x40,
+0xa5,0x00,0x3a,0x38,0x77,0x3d,0x07,0x6c,0x88,0x4e,0x52,0xbf,
+0x10,0xc8,0x75,0x06,0x84,0xef,0x57,0x3b,0xb9,0x88,0x7b,0x8b,
+0xfb,0x3d,0x4d,0xf1,0xbf,0x82,0x03,0x27,0x4b,0xf8,0xd1,0x8c,
+0x6d,0x5a,0x40,0xa2,0x2d,0x9a,0x0b,0xae,0xaf,0x36,0xc0,0x16,
+0xa9,0xbe,0x43,0x33,0x91,0xd1,0x5f,0xd0,0xae,0x1f,0x85,0x05,
+0x2d,0x9a,0x09,0xfa,0x19,0xf7,0xfb,0x11,0x65,0xef,0x28,0xc9,
+0x88,0x52,0xe3,0x20,0x31,0x0c,0x62,0xc4,0xc9,0xc0,0x7e,0x48,
+0x07,0xf1,0x53,0x26,0x66,0x24,0x8b,0x42,0x33,0xac,0xcf,0x94,
+0x62,0x63,0xe7,0xf4,0xaa,0x98,0x5a,0x11,0xfe,0xb3,0x43,0x7b,
+0x91,0x26,0xb3,0x0c,0xfc,0x87,0xfc,0xc5,0xfd,0x35,0xc9,0x95,
+0x66,0x77,0x40,0x8b,0x57,0xb3,0x22,0x05,0xae,0x80,0x1a,0x5e,
+0xcf,0xf2,0xa4,0x7b,0x9a,0x01,0xf5,0x6c,0xc6,0xe7,0x02,0xe5,
+0xa2,0x82,0x62,0x43,0x48,0x69,0xa2,0x95,0xb1,0x97,0x96,0xb3,
+0xe3,0x01,0x32,0xb9,0xaa,0x43,0xc3,0x43,0x68,0xd0,0x82,0x4d,
+0x4c,0xca,0x4b,0xc4,0x0c,0xa4,0x93,0x50,0xdb,0x4b,0xfc,0xba,
+0x06,0xc9,0xa0,0xb1,0xe4,0x76,0xbb,0x92,0x8c,0xeb,0x39,0x0a,
+0xbe,0xe1,0x9b,0x79,0x80,0x70,0xbe,0x3b,0x5c,0x4c,0xc6,0x6f,
+0x44,0xc3,0xc0,0x95,0xe1,0x85,0xa4,0x61,0x17,0xd2,0xa0,0x13,
+0xcb,0x8a,0xaf,0xf0,0x72,0xf9,0xee,0x69,0xfd,0xf9,0x5a,0x33,
+0x7f,0x65,0x4a,0x8b,0x85,0x24,0xcb,0x46,0x5e,0x27,0x27,0x1d,
+0x72,0xc8,0xe8,0xfa,0x5b,0x03,0x18,0x1d,0x00,0xb8,0x09,0x4d,
+0xc8,0x47,0x1d,0x98,0x6a,0xfa,0x00,0xef,0xff,0xe7,0xfd,0x94,
+0xf1,0x04,0x6c,0xc9,0x49,0x7d,0x34,0xbf,0x34,0x40,0xa8,0xcc,
+0x6f,0xa9,0x0b,0x1b,0x25,0xe7,0x9a,0x52,0x21,0xd5,0x2d,0x39,
+0x93,0xf5,0x92,0xe8,0xd1,0x35,0xea,0xc6,0x1b,0x75,0xe5,0x9d,
+0x24,0x1e,0xcb,0x09,0xf9,0xb8,0x7c,0xb5,0xdc,0x29,0x74,0x50,
+0xa9,0x07,0x66,0xbd,0x41,0x02,0xfc,0x52,0x9f,0x72,0x52,0x27,
+0xb7,0x3c,0xb5,0x8b,0x67,0x05,0xb7,0xa3,0x73,0x15,0x76,0x07,
+0xff,0xaa,0xec,0x0e,0x2e,0x7a,0xd9,0x1d,0xbc,0x2c,0xa8,0x27,
+0x1c,0xad,0x1c,0x3e,0x51,0x68,0x1a,0x4c,0x5b,0xa3,0xb9,0xfd,
+0xae,0x46,0xe3,0x4b,0xa6,0x72,0x32,0xf9,0x43,0xe9,0xcf,0x95,
+0x66,0x4b,0xd8,0x6f,0xca,0x49,0xc2,0x39,0x8a,0x1f,0xc8,0xe7,
+0x54,0x1b,0x79,0x8b,0xfd,0xb6,0xcb,0x13,0xf3,0x78,0xc8,0x97,
+0x8c,0xe8,0xb9,0x90,0xcb,0x66,0x50,0x8f,0xb7,0x04,0x3b,0xcc,
+0x40,0xf9,0x34,0xbd,0xf8,0x6f,0xd3,0xee,0x55,0xde,0x95,0x3b,
+0x25,0xc0,0xed,0x35,0xd2,0x69,0x6c,0xd6,0x49,0xf3,0x91,0x6b,
+0x9f,0x6b,0x0d,0x7b,0x64,0x58,0x20,0xaa,0x32,0xa9,0x05,0xb3,
+0x95,0x8f,0x5e,0x5f,0xa6,0x05,0x92,0x7b,0x68,0xee,0x61,0x3f,
+0x68,0xb1,0xfa,0xdd,0x64,0xcd,0xdc,0xc4,0xee,0xc6,0x08,0xff,
+0xe1,0xdf,0x76,0x3b,0xfb,0x59,0x12,0xbe,0x00,0x53,0x57,0x4e,
+0x09,0xb2,0x98,0x4d,0x60,0xb5,0x4b,0x14,0x3e,0x99,0x64,0x8a,
+0xcc,0x1a,0x3e,0x1e,0xfa,0xaf,0xfe,0xb2,0x13,0xd8,0x1c,0x3e,
+0x9b,0x41,0x99,0x3f,0x5f,0x41,0x91,0xb7,0xe4,0xa0,0x71,0xb7,
+0x56,0xe8,0x04,0x8c,0xa7,0x89,0x3a,0xd6,0xb7,0xcf,0xe6,0x0c,
+0x3b,0x70,0x06,0x5d,0x48,0xb5,0xd3,0xa6,0x45,0xf4,0xa3,0xbd,
+0x0b,0x5f,0xa2,0xfc,0x91,0x72,0xd5,0x45,0x7d,0x93,0x77,0xae,
+0x98,0x83,0xf5,0xba,0x12,0x5b,0x33,0x61,0xab,0x2f,0x11,0x6b,
+0xae,0x95,0x2b,0x3d,0xcf,0xfd,0x8d,0xcc,0x20,0x9b,0xda,0x9b,
+0xa3,0xad,0xc6,0xfb,0x7c,0x42,0xa5,0x4c,0x5d,0x15,0x1a,0x2e,
+0x9b,0x97,0x74,0x03,0xf5,0x5a,0x0b,0xb3,0x5e,0x99,0xb1,0x0b,
+0xad,0x9a,0xff,0xc5,0xbe,0xcc,0x6b,0xd1,0x1a,0xd7,0xa2,0x22,
+0xc4,0xad,0xad,0x65,0x17,0xa5,0x50,0x53,0x1c,0x11,0x6e,0x97,
+0x2d,0xf7,0xb3,0xed,0x16,0x38,0xb5,0xf1,0xfc,0xa0,0x50,0x9d,
+0x31,0x68,0xca,0xbe,0x77,0xd8,0xb9,0xba,0x8b,0x00,0xe7,0x0a,
+0xcf,0x83,0x9f,0x50,0x5e,0x8d,0xf7,0x55,0xd2,0xfb,0xe5,0x68,
+0x7f,0x6e,0xee,0x8f,0xcd,0xfc,0x77,0x8e,0x39,0x2d,0xed,0x8f,
+0xc6,0xfe,0x7f,0x01,0x00,0x00,0xff,0xff,0x91,0x22,0x37,0x07,
+0x3c,0x0e,0x00,0x00,
 	}))
 	}))
 
 
 	if err != nil {
 	if err != nil {

+ 3 - 0
zone.go

@@ -47,6 +47,7 @@ type ZoneMetrics struct {
 	Queries     *metrics.StandardMeter
 	Queries     *metrics.StandardMeter
 	EdnsQueries *metrics.StandardMeter
 	EdnsQueries *metrics.StandardMeter
 	LabelStats  *zoneLabelStats
 	LabelStats  *zoneLabelStats
+	ClientStats *zoneLabelStats
 }
 }
 
 
 type Zone struct {
 type Zone struct {
@@ -84,6 +85,7 @@ func (z *Zone) SetupMetrics(old *Zone) {
 		metrics.Register(z.Origin+" queries", z.Metrics.Queries)
 		metrics.Register(z.Origin+" queries", z.Metrics.Queries)
 		metrics.Register(z.Origin+" EDNS queries", z.Metrics.EdnsQueries)
 		metrics.Register(z.Origin+" EDNS queries", z.Metrics.EdnsQueries)
 		z.Metrics.LabelStats = NewZoneLabelStats(10000)
 		z.Metrics.LabelStats = NewZoneLabelStats(10000)
+		z.Metrics.ClientStats = NewZoneLabelStats(10000)
 	}
 	}
 }
 }
 
 
@@ -91,6 +93,7 @@ func (z *Zone) Close() {
 	metrics.Unregister(z.Origin + " queries")
 	metrics.Unregister(z.Origin + " queries")
 	metrics.Unregister(z.Origin + " EDNS queries")
 	metrics.Unregister(z.Origin + " EDNS queries")
 	z.Metrics.LabelStats.Close()
 	z.Metrics.LabelStats.Close()
+	z.Metrics.ClientStats.Close()
 }
 }
 
 
 func (l *Label) firstRR(dnsType uint16) dns.RR {
 func (l *Label) firstRR(dnsType uint16) dns.RR {