From 1a0dd899680f08a634c213eb1be5c22530f808d1 Mon Sep 17 00:00:00 2001 From: Jimmy Zelinskie Date: Thu, 4 Aug 2016 14:48:32 -0400 Subject: [PATCH] add metrics to http & udp trackers --- bittorrent/http/tracker.go | 40 ++++++++++++++++++++++++++++++++++++-- bittorrent/udp/tracker.go | 36 +++++++++++++++++++++------------- 2 files changed, 60 insertions(+), 16 deletions(-) diff --git a/bittorrent/http/tracker.go b/bittorrent/http/tracker.go index 00d0f0b..0b6f88f 100644 --- a/bittorrent/http/tracker.go +++ b/bittorrent/http/tracker.go @@ -16,6 +16,23 @@ // described in BEP 3 and BEP 23. 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 // Tracker. type Config struct { @@ -98,6 +115,15 @@ func (t *Tracker) ListenAndServe() error { // announceRoute parses and responds to an Announce by using t.TrackerFuncs. 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) if err != nil { WriteError(w, err) @@ -117,12 +143,22 @@ func (t *Tracker) announceRoute(w http.ResponseWriter, r *http.Request, _ httpro } 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. 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) if err != nil { WriteError(w, err) @@ -142,6 +178,6 @@ func (t *Tracker) scrapeRoute(w http.ResponseWriter, r *http.Request, _ httprout } if t.AfterScrape != nil { - t.AfterScrape(req, resp) + go t.AfterScrape(req, resp) } } diff --git a/bittorrent/udp/tracker.go b/bittorrent/udp/tracker.go index 53c1525..366721b 100644 --- a/bittorrent/udp/tracker.go +++ b/bittorrent/udp/tracker.go @@ -34,6 +34,16 @@ var promResponseDurationMilliseconds = prometheus.NewHistogramVec( []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 { Addr string PrivateKey string @@ -110,26 +120,24 @@ func (t *Tracker) ListenAndServe() error { continue } - log.Println("Got UDP packet") - start := time.Now() + log.Println("Got UDP Request") t.wg.Add(1) go func(start time.Time) { defer t.wg.Done() defer pool.Put(buffer) - // Handle the response. - response, action, err := t.handlePacket(buffer[:n], addr) - log.Printf("Handled UDP packet: %s, %s, %s\n", response, action, err) + // Handle the request. + start := time.Now() + 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 - // respond to the request. - duration := time.Since(start) + // Record to the duration of time used to respond to the request. + var errString string if err != nil { - promResponseDurationMilliseconds.WithLabelValues(action, err.Error()).Observe(float64(duration.Nanoseconds()) / float64(time.Millisecond)) - } else { - promResponseDurationMilliseconds.WithLabelValues(action, "").Observe(float64(duration.Nanoseconds()) / float64(time.Millisecond)) + errString = err.Error() } - }(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) if t.AfterAnnounce != nil { - t.AfterAnnounce(req, resp) + go t.AfterAnnounce(req, resp) } return @@ -233,7 +241,7 @@ func (t *Tracker) handleRequest(r *Request, w *ResponseWriter) (response []byte, WriteScrape(w, txID, resp) if t.AfterScrape != nil { - t.AfterScrape(req, resp) + go t.AfterScrape(req, resp) } return