commit d57cd0759918d9f6c6734440acc58b24dc95766d Author: Cecylia Bocovich cohosh@torproject.org Date: Tue Jun 11 14:16:01 2019 -0400
Implemented count metrics for broker events
Added three new metrics: - proxyIdleCount counts the number of times a proxy polls and receives no snowflakes - clientDeniedCount counts the number of times a client requested a snowflake but none were available - clientProxyMatchCount counts the number of times a client successfully received a snowflake --- broker/broker.go | 3 +++ broker/metrics.go | 38 +++++++++++++++++++++++++------------- 2 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/broker/broker.go b/broker/broker.go index 274d87c..971e3ad 100644 --- a/broker/broker.go +++ b/broker/broker.go @@ -153,6 +153,7 @@ func proxyPolls(ctx *BrokerContext, w http.ResponseWriter, r *http.Request) { offer := ctx.RequestOffer(id) if nil == offer { log.Println("Proxy " + id + " did not receive a Client offer.") + ctx.metrics.proxyIdleCount++ w.WriteHeader(http.StatusGatewayTimeout) return } @@ -176,6 +177,7 @@ func clientOffers(ctx *BrokerContext, w http.ResponseWriter, r *http.Request) { // Immediately fail if there are no snowflakes available. if ctx.snowflakes.Len() <= 0 { log.Println("Client: No snowflake proxies available.") + ctx.metrics.clientDeniedCount++ w.WriteHeader(http.StatusServiceUnavailable) return } @@ -189,6 +191,7 @@ func clientOffers(ctx *BrokerContext, w http.ResponseWriter, r *http.Request) { select { case answer := <-snowflake.answerChannel: log.Println("Client: Retrieving answer") + ctx.metrics.clientProxyMatchCount++ w.Write(answer) // Initial tracking of elapsed time. ctx.metrics.clientRoundtripEstimate = time.Since(startTime) / diff --git a/broker/metrics.go b/broker/metrics.go index 4ba762a..38cdc10 100644 --- a/broker/metrics.go +++ b/broker/metrics.go @@ -21,11 +21,15 @@ type CountryStats struct {
// Implements Observable type Metrics struct { - tablev4 *GeoIPv4Table - tablev6 *GeoIPv6Table - countryStats CountryStats - // snowflakes timeseries.Float + logger *log.Logger + tablev4 *GeoIPv4Table + tablev6 *GeoIPv6Table + + countryStats CountryStats clientRoundtripEstimate time.Duration + proxyIdleCount int + clientDeniedCount int + clientProxyMatchCount int }
func (s CountryStats) Display() string { @@ -94,17 +98,25 @@ func NewMetrics(metricsLogger *log.Logger) (*Metrics, error) { counts: make(map[string]int), }
+ m.logger = metricsLogger + // Write to log file every hour with updated metrics - go once.Do(func() { - heartbeat := time.Tick(metricsResolution) - for range heartbeat { - metricsLogger.Println("Country stats: ", m.countryStats.Display()) + go once.Do(m.logMetrics) + + return m, nil +}
- //restore all metrics to original values - m.countryStats.counts = make(map[string]int) +func (m *Metrics) logMetrics() {
- } - }) + heartbeat := time.Tick(metricsResolution) + for range heartbeat { + m.logger.Println("snowflake-stats-end ") + m.logger.Println("snowflake-ips ", m.countryStats.Display()) + m.logger.Println("snowflake-idle-count ", m.proxyIdleCount) + m.logger.Println("client-denied-count ", m.clientDeniedCount) + m.logger.Println("client-snowflake-match-count ", m.clientProxyMatchCount)
- return m, nil + //restore all metrics to original values + m.countryStats.counts = make(map[string]int) + } }