forked from segmentio/redis-go
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from dolab/handler-metrics
What: export internal metrics for handler develop
- Loading branch information
Showing
9 changed files
with
404 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package redis | ||
|
||
import ( | ||
"net/http" | ||
"sync" | ||
|
||
"github.com/prometheus/client_golang/prometheus" | ||
"github.com/prometheus/client_golang/prometheus/promhttp" | ||
|
||
"github.com/dolab/redis-go/metrics" | ||
) | ||
|
||
var ( | ||
gometrics *metrics.Metrics | ||
gometricsOnce sync.Once | ||
) | ||
|
||
func init() { | ||
gometricsOnce.Do(func() { | ||
gometrics = metrics.NewMetrics(nil) | ||
|
||
prometheus.MustRegister(gometrics) | ||
}) | ||
} | ||
|
||
// ServeMetrics exports prometheus metrics of internal server. | ||
func ServeMetrics(w http.ResponseWriter, r *http.Request) { | ||
promhttp.Handler().ServeHTTP(w, r) | ||
} | ||
|
||
// NewCounterVec returns a *prometheus.CounterVec for handler usage. | ||
func NewCounterVec(name, help string, labels []string) *prometheus.CounterVec { | ||
return gometrics.Counter(name, help, labels) | ||
} | ||
|
||
// NewGaugeVec returns a *prometheus.GaugeVec for handler usage. | ||
func NewGaugeVec(name, help string, labels []string) *prometheus.GaugeVec { | ||
return gometrics.Gauge(name, help, labels) | ||
} | ||
|
||
// NewHistogramVec returns a *prometheus.HistogramVec for handler usage. | ||
func NewHistogramVec(name, help string, labels []string) *prometheus.HistogramVec { | ||
return gometrics.Histogram(name, help, labels) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,158 @@ | ||
package metrics | ||
|
||
import ( | ||
"net" | ||
"time" | ||
"sync" | ||
|
||
"github.com/prometheus/client_golang/prometheus" | ||
) | ||
|
||
// Metrics implements both prometheus Collector interface and | ||
// grpc interceptor interface. | ||
// Metrics implements prometheus Collector interface for server and handler. | ||
type Metrics struct { | ||
monitor *Monitor | ||
trackPeers bool | ||
monitor *Monitor | ||
|
||
// for custom metrics with handler | ||
mutex sync.RWMutex | ||
counters map[string]*prometheus.CounterVec | ||
gauges map[string]*prometheus.GaugeVec | ||
histograms map[string]*prometheus.HistogramVec | ||
} | ||
|
||
// NewMetrics creates a new metrics of grpc interceptor for shared usage. | ||
func NewMetrics(labels prometheus.Labels) *Metrics { | ||
return &Metrics{ | ||
monitor: NewMonitor(labels), | ||
monitor: NewMonitor(labels), | ||
counters: make(map[string]*prometheus.CounterVec), | ||
gauges: make(map[string]*prometheus.GaugeVec), | ||
histograms: make(map[string]*prometheus.HistogramVec), | ||
} | ||
} | ||
|
||
// Describe implements prometheus Collector interface. | ||
func (m *Metrics) Describe(in chan<- *prometheus.Desc) { | ||
m.monitor.Describe(in) | ||
|
||
for _, vec := range m.counters { | ||
vec.Describe(in) | ||
} | ||
|
||
for _, vec := range m.gauges { | ||
vec.Describe(in) | ||
} | ||
|
||
for _, vec := range m.histograms { | ||
vec.Describe(in) | ||
} | ||
} | ||
|
||
// Collect implements prometheus Collector interface. | ||
func (m *Metrics) Collect(in chan<- prometheus.Metric) { | ||
m.monitor.Collect(in) | ||
|
||
for _, vec := range m.counters { | ||
vec.Collect(in) | ||
} | ||
|
||
for _, vec := range m.gauges { | ||
vec.Collect(in) | ||
} | ||
|
||
for _, vec := range m.histograms { | ||
vec.Collect(in) | ||
} | ||
} | ||
|
||
// Counter ... | ||
func (m *Metrics) Counter(name, help string, labels []string) *prometheus.CounterVec { | ||
// find | ||
m.mutex.RLock() | ||
if vec, ok := m.counters[name]; ok { | ||
m.mutex.RUnlock() | ||
|
||
return vec | ||
} | ||
m.mutex.RUnlock() | ||
|
||
// create | ||
m.mutex.Lock() | ||
defer m.mutex.Unlock() | ||
|
||
if vec, ok := m.counters[name]; ok { | ||
return vec | ||
} | ||
|
||
m.counters[name] = prometheus.NewCounterVec( | ||
prometheus.CounterOpts{ | ||
Namespace: "redis", | ||
Subsystem: "handler", | ||
Name: name, | ||
Help: help, | ||
}, | ||
labels, | ||
) | ||
|
||
return m.counters[name] | ||
} | ||
|
||
// Gauge ... | ||
func (m *Metrics) Gauge(name, help string, labels []string) *prometheus.GaugeVec { | ||
// find | ||
m.mutex.RLock() | ||
if vec, ok := m.gauges[name]; ok { | ||
m.mutex.RUnlock() | ||
|
||
return vec | ||
} | ||
m.mutex.RUnlock() | ||
|
||
// create | ||
m.mutex.Lock() | ||
defer m.mutex.Unlock() | ||
|
||
if vec, ok := m.gauges[name]; ok { | ||
return vec | ||
} | ||
|
||
m.gauges[name] = prometheus.NewGaugeVec( | ||
prometheus.GaugeOpts{ | ||
Namespace: "redis", | ||
Subsystem: "handler", | ||
Name: name, | ||
Help: help, | ||
}, | ||
labels, | ||
) | ||
|
||
return m.gauges[name] | ||
} | ||
|
||
// Dialer ... | ||
func (m *Metrics) Dialer(f func(string, time.Duration) (net.Conn, error)) func(string, time.Duration) (net.Conn, error) { | ||
return func(addr string, timeout time.Duration) (net.Conn, error) { | ||
m.monitor.dialer.WithLabelValues(addr).Inc() | ||
// Histogram ... | ||
func (m *Metrics) Histogram(name, help string, labels []string) *prometheus.HistogramVec { | ||
// find | ||
m.mutex.RLock() | ||
if vec, ok := m.histograms[name]; ok { | ||
m.mutex.RUnlock() | ||
|
||
return f(addr, timeout) | ||
return vec | ||
} | ||
m.mutex.RUnlock() | ||
|
||
// create | ||
m.mutex.Lock() | ||
defer m.mutex.Unlock() | ||
|
||
if vec, ok := m.histograms[name]; ok { | ||
return vec | ||
} | ||
|
||
m.histograms[name] = prometheus.NewHistogramVec( | ||
prometheus.HistogramOpts{ | ||
Namespace: "redis", | ||
Subsystem: "handler", | ||
Name: name, | ||
Help: help, | ||
}, | ||
labels, | ||
) | ||
|
||
return m.histograms[name] | ||
} |
Oops, something went wrong.