add metrics to http & udp trackers

This commit is contained in:
Jimmy Zelinskie 2016-08-04 14:48:32 -04:00
parent 437c3be9ec
commit 1a0dd89968
2 changed files with 60 additions and 16 deletions

View file

@ -16,6 +16,23 @@
// described in BEP 3 and BEP 23. // described in BEP 3 and BEP 23.
package http package http
var promResponseDurationMilliseconds = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "trakr_http_response_duration_milliseconds",
Help: "The duration of time it takes to receive and write a response to an API request",
Buckets: prometheus.ExponentialBuckets(9.375, 2, 10),
},
[]string{"action", "error"},
)
// recordResponseDuration records the duration of time to respond to a UDP
// Request in milliseconds .
func recordResponseDuration(action, err error, duration time.Duration) {
promResponseDurationMilliseconds.
WithLabelValues(action, err.Error()).
Observe(float64(duration.Nanoseconds()) / float64(time.Millisecond))
}
// Config represents all of the configurable options for an HTTP BitTorrent // Config represents all of the configurable options for an HTTP BitTorrent
// Tracker. // Tracker.
type Config struct { type Config struct {
@ -98,6 +115,15 @@ func (t *Tracker) ListenAndServe() error {
// announceRoute parses and responds to an Announce by using t.TrackerFuncs. // announceRoute parses and responds to an Announce by using t.TrackerFuncs.
func (t *Tracker) announceRoute(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { func (t *Tracker) announceRoute(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
start := time.Now()
defer func() {
var errString string
if err != nil {
errString = err.Error()
}
recordResponseDuration("announce", errString, time.Since(start))
}()
req, err := ParseAnnounce(r, t.RealIPHeader, t.AllowIPSpoofing) req, err := ParseAnnounce(r, t.RealIPHeader, t.AllowIPSpoofing)
if err != nil { if err != nil {
WriteError(w, err) WriteError(w, err)
@ -117,12 +143,22 @@ func (t *Tracker) announceRoute(w http.ResponseWriter, r *http.Request, _ httpro
} }
if t.AfterAnnounce != nil { if t.AfterAnnounce != nil {
t.AfterAnnounce(req, resp) go t.AfterAnnounce(req, resp)
} }
recordResponseDuration("announce")
} }
// scrapeRoute parses and responds to a Scrape by using t.TrackerFuncs. // scrapeRoute parses and responds to a Scrape by using t.TrackerFuncs.
func (t *Tracker) scrapeRoute(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { func (t *Tracker) scrapeRoute(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
start := time.Now()
defer func() {
var errString string
if err != nil {
errString = err.Error()
}
recordResponseDuration("scrape", errString, time.Since(start))
}()
req, err := ParseScrape(r) req, err := ParseScrape(r)
if err != nil { if err != nil {
WriteError(w, err) WriteError(w, err)
@ -142,6 +178,6 @@ func (t *Tracker) scrapeRoute(w http.ResponseWriter, r *http.Request, _ httprout
} }
if t.AfterScrape != nil { if t.AfterScrape != nil {
t.AfterScrape(req, resp) go t.AfterScrape(req, resp)
} }
} }

View file

@ -34,6 +34,16 @@ var promResponseDurationMilliseconds = prometheus.NewHistogramVec(
[]string{"action", "error"}, []string{"action", "error"},
) )
// recordResponseDuration records the duration of time to respond to a UDP
// Request in milliseconds .
func recordResponseDuration(action, err error, duration time.Duration) {
promResponseDurationMilliseconds.
WithLabelValues(action, err.Error()).
Observe(float64(duration.Nanoseconds()) / float64(time.Millisecond))
}
// Config represents all of the configurable options for a UDP BitTorrent
// Tracker.
type Config struct { type Config struct {
Addr string Addr string
PrivateKey string PrivateKey string
@ -110,26 +120,24 @@ func (t *Tracker) ListenAndServe() error {
continue continue
} }
log.Println("Got UDP packet") log.Println("Got UDP Request")
start := time.Now()
t.wg.Add(1) t.wg.Add(1)
go func(start time.Time) { go func(start time.Time) {
defer t.wg.Done() defer t.wg.Done()
defer pool.Put(buffer) defer pool.Put(buffer)
// Handle the response. // Handle the request.
response, action, err := t.handlePacket(buffer[:n], addr) start := time.Now()
log.Printf("Handled UDP packet: %s, %s, %s\n", response, action, err) response, action, err := t.handleRequest(&Request{buffer[:n], addr.IP})
log.Printf("Handled UDP Request: %s, %s, %s\n", response, action, err)
// Record to Prometheus the time in milliseconds to receive, handle, and // Record to the duration of time used to respond to the request.
// respond to the request. var errString string
duration := time.Since(start)
if err != nil { if err != nil {
promResponseDurationMilliseconds.WithLabelValues(action, err.Error()).Observe(float64(duration.Nanoseconds()) / float64(time.Millisecond)) errString = err.Error()
} else {
promResponseDurationMilliseconds.WithLabelValues(action, "").Observe(float64(duration.Nanoseconds()) / float64(time.Millisecond))
} }
}(start) recordResponseDuration(action, errString, time.Since(start))
}()
} }
} }
@ -207,7 +215,7 @@ func (t *Tracker) handleRequest(r *Request, w *ResponseWriter) (response []byte,
WriteAnnounce(w, txID, resp) WriteAnnounce(w, txID, resp)
if t.AfterAnnounce != nil { if t.AfterAnnounce != nil {
t.AfterAnnounce(req, resp) go t.AfterAnnounce(req, resp)
} }
return return
@ -233,7 +241,7 @@ func (t *Tracker) handleRequest(r *Request, w *ResponseWriter) (response []byte,
WriteScrape(w, txID, resp) WriteScrape(w, txID, resp)
if t.AfterScrape != nil { if t.AfterScrape != nil {
t.AfterScrape(req, resp) go t.AfterScrape(req, resp)
} }
return return