Browse Source

Begin more detailed /status page

(and mark 2.2.6)
Ask Bjørn Hansen 12 years ago
parent
commit
72e1aed500
6 changed files with 122 additions and 0 deletions
  1. 1 0
      geodns.go
  2. 42 0
      metrics.go
  3. 67 0
      monitor.go
  4. 1 0
      serve.go
  5. 2 0
      types.go
  6. 9 0
      zones.go

+ 1 - 0
geodns.go

@@ -113,6 +113,7 @@ func main() {
 
 	go configWatcher(configFileName)
 	go statHatPoster()
+	go metricsPoster()
 
 	if *flaginter == "*" {
 		addrs, _ := net.InterfaceAddrs()

+ 42 - 0
metrics.go

@@ -0,0 +1,42 @@
+package main
+
+import (
+	metrics "github.com/abh/go-metrics"
+	"log"
+	"os"
+	"runtime"
+	"time"
+)
+
+func metricsPoster() {
+
+	lastQueryCount := expVarToInt64(qCounter)
+
+	queries := metrics.NewMeter()
+	metrics.Register("queries", queries)
+
+	queriesHistogram := metrics.NewHistogram(metrics.NewUniformSample(600))
+	metrics.Register("queriesHistogram", queriesHistogram)
+
+	goroutines := metrics.NewGauge()
+	metrics.Register("goroutines", goroutines)
+
+	go metrics.Log(metrics.DefaultRegistry, 30, log.New(os.Stderr, "metrics: ", log.Lmicroseconds))
+
+	// metrics.
+
+	for {
+		time.Sleep(1 * time.Second)
+
+		// log.Println("updating metrics")
+
+		current := expVarToInt64(qCounter)
+		newQueries := current - lastQueryCount
+		lastQueryCount = current
+
+		queries.Mark(newQueries)
+		queriesHistogram.Update(newQueries)
+		goroutines.Update(int64(runtime.NumGoroutine()))
+
+	}
+}

+ 67 - 0
monitor.go

@@ -4,11 +4,14 @@ import (
 	"code.google.com/p/go.net/websocket"
 	"encoding/json"
 	"expvar"
+	"fmt"
+	"github.com/abh/go-metrics"
 	"io"
 	"log"
 	"net/http"
 	"os"
 	"runtime"
+	"sort"
 	"strconv"
 	"time"
 )
@@ -187,10 +190,74 @@ func MainServer(w http.ResponseWriter, req *http.Request) {
 		`</body></html>`)
 }
 
+type rate struct {
+	Name  string
+	Count int64
+	str   string
+}
+type Rates []*rate
+
+func (s Rates) Len() int      { return len(s) }
+func (s Rates) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+type RatesByCount struct{ Rates }
+
+func (s RatesByCount) Less(i, j int) bool {
+	ic := s.Rates[i].Count
+	jc := s.Rates[j].Count
+	if ic == jc {
+		return s.Rates[i].Name < s.Rates[j].Name
+	}
+	return ic > jc
+}
+
+func StatusServer(w http.ResponseWriter, req *http.Request) {
+
+	io.WriteString(w, `<html><head><title>GeoDNS `+
+		VERSION+`</title><body>`+
+		initialStatus())
+
+	rates := make(Rates, 0)
+
+	// https://github.com/rcrowley/go-metrics/blob/master/log.go
+	metrics.Each(func(name string, i interface{}) {
+
+		switch m := i.(type) {
+		case metrics.Meter:
+			str := fmt.Sprintf(
+				"<h3>meter %s</h3>\n"+
+					"count: %9d<br>"+
+					"  1-min rate:  %12.2f\n"+
+					"  5-min rate:  %12.2f\n"+
+					"15-min rate: %12.2f\n"+
+					"  mean rate:   %12.2f\n",
+				name,
+				m.Count(),
+				m.Rate1(),
+				m.Rate5(),
+				m.Rate15(),
+				m.RateMean(),
+			)
+			rates = append(rates, &rate{Name: name, Count: m.Count(), str: str})
+		}
+	})
+
+	sort.Sort(RatesByCount{rates})
+
+	for _, rate := range rates {
+		io.WriteString(w, rate.str)
+	}
+
+	io.WriteString(w, `</body></html>`)
+}
+
 func httpHandler() {
 	http.Handle("/monitor", websocket.Handler(wsHandler))
+	http.HandleFunc("/status", StatusServer)
 	http.HandleFunc("/", MainServer)
 
+	log.Println("Starting HTTP interface on", *flaghttp)
+
 	log.Fatal(http.ListenAndServe(*flaghttp, nil))
 }
 

+ 1 - 0
serve.go

@@ -28,6 +28,7 @@ func serve(w dns.ResponseWriter, req *dns.Msg, z *Zone) {
 		dns.TypeToString[qtype], req.MsgHdr.Id, w.RemoteAddr())
 
 	qCounter.Add(1)
+	z.Metrics.Mark(1)
 
 	logPrintln("Got request", req)
 

+ 2 - 0
types.go

@@ -2,6 +2,7 @@ package main
 
 import (
 	"github.com/abh/geodns/countries"
+	"github.com/abh/go-metrics"
 	"github.com/miekg/dns"
 	"strings"
 	"time"
@@ -46,6 +47,7 @@ type Zone struct {
 	LenLabels int
 	Options   Options
 	LastRead  time.Time
+	Metrics   *metrics.StandardMeter
 }
 
 type qTypes []uint16

+ 9 - 0
zones.go

@@ -4,6 +4,7 @@ import (
 	"camlistore.org/pkg/errorutil"
 	"encoding/json"
 	"fmt"
+	"github.com/abh/go-metrics"
 	"github.com/miekg/dns"
 	"io/ioutil"
 	"log"
@@ -25,6 +26,14 @@ func zonesReader(dirName string, zones Zones) {
 }
 
 func addHandler(zones Zones, name string, config *Zone) {
+	oldZone, ok := zones[name]
+	if ok {
+		config.Metrics = oldZone.Metrics
+	} else {
+		config.Metrics = metrics.NewMeter()
+		metrics.Register(config.Origin+" queries", config.Metrics)
+	}
+
 	zones[name] = config
 	dns.HandleFunc(name, setupServerFunc(config))
 }