Make InstrumentHandler receive a Registry

Before making Registry public, the InstrumentXXX functions were
accessing the global default registry. We now inject the Registry that
we want to work with.
This commit is contained in:
Tomás Senart 2014-12-16 15:34:32 +01:00
parent c106d48719
commit e88ad73bf8
4 changed files with 47 additions and 38 deletions

View File

@ -161,7 +161,7 @@ func ExampleInstrumentHandler() {
// exported to Prometheus, partitioned by HTTP status code and method
// and by the handler name (here "fileserver").
http.Handle("/doc", prometheus.InstrumentHandler(
"fileserver", http.FileServer(http.Dir("/usr/share/doc")),
"fileserver", prometheus.DefaultRegistry, http.FileServer(http.Dir("/usr/share/doc")),
))
// The Prometheus handler still has to be registered to handle the
// "/metrics" endpoint. The handler returned by prometheus.Handler() is
@ -169,7 +169,7 @@ func ExampleInstrumentHandler() {
// example, we want the handler name to be "metrics", so we instrument
// the uninstrumented Prometheus handler ourselves.
http.Handle("/metrics", prometheus.InstrumentHandler(
"metrics", prometheus.UninstrumentedHandler(),
"metrics", prometheus.DefaultRegistry, prometheus.UninstrumentedHandler(),
))
}

View File

@ -46,16 +46,16 @@ func nowSeries(t ...time.Time) nower {
})
}
// InstrumentHandler wraps the given HTTP handler for instrumentation. It
// registers four metric vector collectors (if not already done) and reports
// http metrics to the (newly or already) registered collectors:
// InstrumentHandler wraps the given HTTP handler with instrumentation.
// It registers four metric vector collectors in the provided Registry.
// http_requests_total (CounterVec), http_request_duration_microseconds
// (SummaryVec), http_request_size_bytes (SummaryVec), http_response_size_bytes
// (SummaryVec). Each has three labels: handler, method, code. The value of the
// handler label is set by the handlerName parameter of this function.
func InstrumentHandler(name string, hnd http.Handler) http.Handler {
func InstrumentHandler(name string, r Registry, hnd http.Handler) http.Handler {
return InstrumentHandlerWithOpts(
SummaryOpts{Subsystem: "http", ConstLabels: Labels{"handler": name}},
r,
hnd,
)
}
@ -85,7 +85,7 @@ func InstrumentHandler(name string, hnd http.Handler) http.Handler {
// cannot use SummaryOpts. Instead, a CounterOpts struct is created internally,
// and all its fields are set to the equally named fields in the provided
// SummaryOpts.
func InstrumentHandlerWithOpts(opts SummaryOpts, hnd http.Handler) http.Handler {
func InstrumentHandlerWithOpts(opts SummaryOpts, r Registry, hnd http.Handler) http.Handler {
reqCnt := NewCounterVec(
CounterOpts{
Namespace: opts.Namespace,
@ -109,10 +109,10 @@ func InstrumentHandlerWithOpts(opts SummaryOpts, hnd http.Handler) http.Handler
opts.Help = "The HTTP response sizes in bytes."
resSz := NewSummaryVec(opts, instLabels)
regReqCnt := MustRegisterOrGet(reqCnt).(*CounterVec)
regReqDur := MustRegisterOrGet(reqDur).(*SummaryVec)
regReqSz := MustRegisterOrGet(reqSz).(*SummaryVec)
regResSz := MustRegisterOrGet(resSz).(*SummaryVec)
regReqCnt := r.MustRegisterOrGet(reqCnt).(*CounterVec)
regReqDur := r.MustRegisterOrGet(reqDur).(*SummaryVec)
regReqSz := r.MustRegisterOrGet(reqSz).(*SummaryVec)
regResSz := r.MustRegisterOrGet(resSz).(*SummaryVec)
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
now := time.Now()

View File

@ -39,14 +39,12 @@ func TestInstrumentHandler(t *testing.T) {
now = nowSeries(instant, end)
respBody := respBody("Howdy there!")
hndlr := InstrumentHandler("test-handler", respBody)
opts := SummaryOpts{
Subsystem: "http",
ConstLabels: Labels{"handler": "test-handler"},
}
reqCnt := MustRegisterOrGet(NewCounterVec(
reqCnt := NewCounterVec(
CounterOpts{
Namespace: opts.Namespace,
Subsystem: opts.Subsystem,
@ -55,30 +53,21 @@ func TestInstrumentHandler(t *testing.T) {
ConstLabels: opts.ConstLabels,
},
instLabels,
)).(*CounterVec)
)
opts.Name = "request_duration_microseconds"
opts.Help = "The HTTP request latencies in microseconds."
reqDur := MustRegisterOrGet(NewSummaryVec(opts, instLabels)).(*SummaryVec)
reqDur := NewSummaryVec(opts, instLabels)
opts.Name = "request_size_bytes"
opts.Help = "The HTTP request sizes in bytes."
reqSz := MustRegisterOrGet(NewSummaryVec(opts, instLabels)).(*SummaryVec)
opts.Name = "response_size_bytes"
opts.Help = "The HTTP response sizes in bytes."
resSz := MustRegisterOrGet(NewSummaryVec(opts, instLabels)).(*SummaryVec)
reqCnt.Reset()
reqDur.Reset()
reqSz.Reset()
resSz.Reset()
resp := httptest.NewRecorder()
req := &http.Request{
Method: "GET",
reg, err := NewRegistry(reqCnt, reqDur)
if err != nil {
t.Fatalf("got err: %v", err)
}
resp := httptest.NewRecorder()
req := &http.Request{Method: "GET"}
hndlr := InstrumentHandler("test-handler", reg, respBody)
hndlr.ServeHTTP(resp, req)
if resp.Code != http.StatusTeapot {

View File

@ -125,6 +125,10 @@ type Registry interface {
// makes more sense.
Register(Collector) (Collector, error)
// MustRegister works like Register but panics where Register would have
// returned an error.
MustRegister(Collector) Collector
// RegisterOrGet works like Register but does not return an error if a Collector
// is registered that equals a previously registered Collector. (Two Collectors
// are considered equal if their Describe method yields the same set of
@ -140,6 +144,10 @@ type Registry interface {
// makes more sense.
RegisterOrGet(Collector) (Collector, error)
// MustRegisterOrGet works like Register but panics where RegisterOrGet would
// have returned an error.
MustRegisterOrGet(Collector) Collector
// Unregister unregisters the Collector that equals the Collector passed in as
// an argument. (Two Collectors are considered equal if their Describe method
// yields the same set of descriptors.) The function returns whether a Collector
@ -268,11 +276,7 @@ func Register(m Collector) (Collector, error) {
// MustRegister works like Register but panics where Register would have
// returned an error.
func MustRegister(m Collector) Collector {
m, err := Register(m)
if err != nil {
panic(err)
}
return m
return DefaultRegistry.MustRegister(m)
}
// RegisterOrGet works like Register but does not return an error if a Collector
@ -378,7 +382,7 @@ type registry struct {
}
func (r *registry) Handler() http.Handler {
return InstrumentHandler("prometheus", r.UninstrumentedHandler())
return InstrumentHandler("prometheus", r, r.UninstrumentedHandler())
}
func (r *registry) UninstrumentedHandler() http.Handler {
@ -462,6 +466,14 @@ func (r *registry) Register(c Collector) (Collector, error) {
return c, nil
}
func (r *registry) MustRegister(m Collector) Collector {
m, err := r.Register(m)
if err != nil {
panic(err)
}
return m
}
func (r *registry) RegisterOrGet(m Collector) (Collector, error) {
existing, err := r.Register(m)
if err != nil && err != errAlreadyReg {
@ -470,6 +482,14 @@ func (r *registry) RegisterOrGet(m Collector) (Collector, error) {
return existing, nil
}
func (r *registry) MustRegisterOrGet(m Collector) Collector {
m, err := r.RegisterOrGet(m)
if err != nil {
panic(err)
}
return m
}
func (r *registry) Unregister(c Collector) bool {
descChan := make(chan *Desc, capDescChan)
go func() {