summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/prometheus/client_golang/prometheus/promhttp
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/prometheus/client_golang/prometheus/promhttp')
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_7.go35
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_8.go70
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go29
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/http_test.go6
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go95
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client_1_8.go142
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client_1_8_test.go195
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go473
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server_test.go164
9 files changed, 19 insertions, 1190 deletions
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_7.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_7.go
deleted file mode 100644
index 5e38c7ca4..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_7.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !go1.8
-
-package promhttp
-
-import (
- "io"
- "net/http"
-)
-
-func newDelegator(w http.ResponseWriter) delegator {
- d := &responseWriterDelegator{ResponseWriter: w}
-
- _, cn := w.(http.CloseNotifier)
- _, fl := w.(http.Flusher)
- _, hj := w.(http.Hijacker)
- _, rf := w.(io.ReaderFrom)
- if cn && fl && hj && rf {
- return &fancyDelegator{d}
- }
-
- return d
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_8.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_8.go
deleted file mode 100644
index 98b565096..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_8.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build go1.8
-
-package promhttp
-
-import (
- "io"
- "net/http"
-)
-
-// newDelegator handles the four different methods of upgrading a
-// http.ResponseWriter to delegator.
-func newDelegator(w http.ResponseWriter) delegator {
- d := &responseWriterDelegator{ResponseWriter: w}
-
- _, cn := w.(http.CloseNotifier)
- _, fl := w.(http.Flusher)
- _, hj := w.(http.Hijacker)
- _, ps := w.(http.Pusher)
- _, rf := w.(io.ReaderFrom)
-
- // Check for the four most common combination of interfaces a
- // http.ResponseWriter might implement.
- switch {
- case cn && fl && hj && rf && ps:
- // All interfaces.
- return &fancyPushDelegator{
- fancyDelegator: &fancyDelegator{d},
- p: &pushDelegator{d},
- }
- case cn && fl && hj && rf:
- // All interfaces, except http.Pusher.
- return &fancyDelegator{d}
- case ps:
- // Just http.Pusher.
- return &pushDelegator{d}
- }
-
- return d
-}
-
-type fancyPushDelegator struct {
- p *pushDelegator
-
- *fancyDelegator
-}
-
-func (f *fancyPushDelegator) Push(target string, opts *http.PushOptions) error {
- return f.p.Push(target, opts)
-}
-
-type pushDelegator struct {
- *responseWriterDelegator
-}
-
-func (f *pushDelegator) Push(target string, opts *http.PushOptions) error {
- return f.ResponseWriter.(http.Pusher).Push(target, opts)
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
index 4c70a7af6..b6dd5a266 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
@@ -11,24 +11,21 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// Package promhttp provides tooling around HTTP servers and clients.
+// Copyright (c) 2013, The Prometheus Authors
+// All rights reserved.
//
-// First, the package allows the creation of http.Handler instances to expose
-// Prometheus metrics via HTTP. promhttp.Handler acts on the
-// prometheus.DefaultGatherer. With HandlerFor, you can create a handler for a
-// custom registry or anything that implements the Gatherer interface. It also
-// allows the creation of handlers that act differently on errors or allow to
-// log errors.
-//
-// Second, the package provides tooling to instrument instances of http.Handler
-// via middleware. Middleware wrappers follow the naming scheme
-// InstrumentHandlerX, where X describes the intended use of the middleware.
-// See each function's doc comment for specific details.
+// Use of this source code is governed by a BSD-style license that can be found
+// in the LICENSE file.
+
+// Package promhttp contains functions to create http.Handler instances to
+// expose Prometheus metrics via HTTP. In later versions of this package, it
+// will also contain tooling to instrument instances of http.Handler and
+// http.RoundTripper.
//
-// Finally, the package allows for an http.RoundTripper to be instrumented via
-// middleware. Middleware wrappers follow the naming scheme
-// InstrumentRoundTripperX, where X describes the intended use of the
-// middleware. See each function's doc comment for specific details.
+// promhttp.Handler acts on the prometheus.DefaultGatherer. With HandlerFor,
+// you can create a handler for a custom registry or anything that implements
+// the Gatherer interface. It also allows to create handlers that act
+// differently on errors or allow to log errors.
package promhttp
import (
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http_test.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http_test.go
index 413ff7baa..d4a7d4a7b 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http_test.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http_test.go
@@ -11,6 +11,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+// Copyright (c) 2013, The Prometheus Authors
+// All rights reserved.
+//
+// Use of this source code is governed by a BSD-style license that can be found
+// in the LICENSE file.
+
package promhttp
import (
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
deleted file mode 100644
index 1cf21f217..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package promhttp
-
-import (
- "net/http"
- "time"
-
- "github.com/prometheus/client_golang/prometheus"
-)
-
-// The RoundTripperFunc type is an adapter to allow the use of ordinary
-// functions as RoundTrippers. If f is a function with the appropriate
-// signature, RountTripperFunc(f) is a RoundTripper that calls f.
-type RoundTripperFunc func(req *http.Request) (*http.Response, error)
-
-// RoundTrip implements the RoundTripper interface.
-func (rt RoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) {
- return rt(r)
-}
-
-// InstrumentRoundTripperInFlight is a middleware that wraps the provided
-// http.RoundTripper. It sets the provided prometheus.Gauge to the number of
-// requests currently handled by the wrapped http.RoundTripper.
-//
-// See the example for ExampleInstrumentRoundTripperDuration for example usage.
-func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripper) RoundTripperFunc {
- return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
- gauge.Inc()
- defer gauge.Dec()
- return next.RoundTrip(r)
- })
-}
-
-// InstrumentRoundTripperCounter is a middleware that wraps the provided
-// http.RoundTripper to observe the request result with the provided CounterVec.
-// The CounterVec must have zero, one, or two labels. The only allowed label
-// names are "code" and "method". The function panics if any other instance
-// labels are provided. Partitioning of the CounterVec happens by HTTP status
-// code and/or HTTP method if the respective instance label names are present
-// in the CounterVec. For unpartitioned counting, use a CounterVec with
-// zero labels.
-//
-// If the wrapped RoundTripper panics or returns a non-nil error, the Counter
-// is not incremented.
-//
-// See the example for ExampleInstrumentRoundTripperDuration for example usage.
-func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.RoundTripper) RoundTripperFunc {
- code, method := checkLabels(counter)
-
- return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
- resp, err := next.RoundTrip(r)
- if err == nil {
- counter.With(labels(code, method, r.Method, resp.StatusCode)).Inc()
- }
- return resp, err
- })
-}
-
-// InstrumentRoundTripperDuration is a middleware that wraps the provided
-// http.RoundTripper to observe the request duration with the provided ObserverVec.
-// The ObserverVec must have zero, one, or two labels. The only allowed label
-// names are "code" and "method". The function panics if any other instance
-// labels are provided. The Observe method of the Observer in the ObserverVec
-// is called with the request duration in seconds. Partitioning happens by HTTP
-// status code and/or HTTP method if the respective instance label names are
-// present in the ObserverVec. For unpartitioned observations, use an
-// ObserverVec with zero labels. Note that partitioning of Histograms is
-// expensive and should be used judiciously.
-//
-// If the wrapped RoundTripper panics or returns a non-nil error, no values are
-// reported.
-func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundTripper) RoundTripperFunc {
- code, method := checkLabels(obs)
-
- return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
- start := time.Now()
- resp, err := next.RoundTrip(r)
- if err == nil {
- obs.With(labels(code, method, r.Method, resp.StatusCode)).Observe(time.Since(start).Seconds())
- }
- return resp, err
- })
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client_1_8.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client_1_8.go
deleted file mode 100644
index b51d91052..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client_1_8.go
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build go1.8
-
-package promhttp
-
-import (
- "context"
- "crypto/tls"
- "net/http"
- "net/http/httptrace"
- "time"
-)
-
-// InstrumentTrace is used to offer flexibility in instrumenting the available
-// httptrace.ClientTrace hook functions. Each function is passed a float64
-// representing the time in seconds since the start of the http request. A user
-// may choose to use separately buckets Histograms, or implement custom
-// instance labels on a per function basis.
-type InstrumentTrace struct {
- GotConn func(float64)
- PutIdleConn func(float64)
- GotFirstResponseByte func(float64)
- Got100Continue func(float64)
- DNSStart func(float64)
- DNSDone func(float64)
- ConnectStart func(float64)
- ConnectDone func(float64)
- TLSHandshakeStart func(float64)
- TLSHandshakeDone func(float64)
- WroteHeaders func(float64)
- Wait100Continue func(float64)
- WroteRequest func(float64)
-}
-
-// InstrumentRoundTripperTrace is a middleware that wraps the provided
-// RoundTripper and reports times to hook functions provided in the
-// InstrumentTrace struct. Hook functions that are not present in the provided
-// InstrumentTrace struct are ignored. Times reported to the hook functions are
-// time since the start of the request. Note that partitioning of Histograms
-// is expensive and should be used judiciously.
-//
-// For hook functions that receive an error as an argument, no observations are
-// made in the event of a non-nil error value.
-//
-// See the example for ExampleInstrumentRoundTripperDuration for example usage.
-func InstrumentRoundTripperTrace(it *InstrumentTrace, next http.RoundTripper) RoundTripperFunc {
- return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
- start := time.Now()
-
- trace := &httptrace.ClientTrace{
- GotConn: func(_ httptrace.GotConnInfo) {
- if it.GotConn != nil {
- it.GotConn(time.Since(start).Seconds())
- }
- },
- PutIdleConn: func(err error) {
- if err != nil {
- return
- }
- if it.PutIdleConn != nil {
- it.PutIdleConn(time.Since(start).Seconds())
- }
- },
- DNSStart: func(_ httptrace.DNSStartInfo) {
- if it.DNSStart != nil {
- it.DNSStart(time.Since(start).Seconds())
- }
- },
- DNSDone: func(_ httptrace.DNSDoneInfo) {
- if it.DNSStart != nil {
- it.DNSStart(time.Since(start).Seconds())
- }
- },
- ConnectStart: func(_, _ string) {
- if it.ConnectStart != nil {
- it.ConnectStart(time.Since(start).Seconds())
- }
- },
- ConnectDone: func(_, _ string, err error) {
- if err != nil {
- return
- }
- if it.ConnectDone != nil {
- it.ConnectDone(time.Since(start).Seconds())
- }
- },
- GotFirstResponseByte: func() {
- if it.GotFirstResponseByte != nil {
- it.GotFirstResponseByte(time.Since(start).Seconds())
- }
- },
- Got100Continue: func() {
- if it.Got100Continue != nil {
- it.Got100Continue(time.Since(start).Seconds())
- }
- },
- TLSHandshakeStart: func() {
- if it.TLSHandshakeStart != nil {
- it.TLSHandshakeStart(time.Since(start).Seconds())
- }
- },
- TLSHandshakeDone: func(_ tls.ConnectionState, err error) {
- if err != nil {
- return
- }
- if it.TLSHandshakeDone != nil {
- it.TLSHandshakeDone(time.Since(start).Seconds())
- }
- },
- WroteHeaders: func() {
- if it.WroteHeaders != nil {
- it.WroteHeaders(time.Since(start).Seconds())
- }
- },
- Wait100Continue: func() {
- if it.Wait100Continue != nil {
- it.Wait100Continue(time.Since(start).Seconds())
- }
- },
- WroteRequest: func(_ httptrace.WroteRequestInfo) {
- if it.WroteRequest != nil {
- it.WroteRequest(time.Since(start).Seconds())
- }
- },
- }
- r = r.WithContext(httptrace.WithClientTrace(context.Background(), trace))
-
- return next.RoundTrip(r)
- })
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client_1_8_test.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client_1_8_test.go
deleted file mode 100644
index 7e3f5229f..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client_1_8_test.go
+++ /dev/null
@@ -1,195 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build go1.8
-
-package promhttp
-
-import (
- "log"
- "net/http"
- "testing"
- "time"
-
- "github.com/prometheus/client_golang/prometheus"
-)
-
-func TestClientMiddlewareAPI(t *testing.T) {
- client := http.DefaultClient
- client.Timeout = 1 * time.Second
-
- reg := prometheus.NewRegistry()
-
- inFlightGauge := prometheus.NewGauge(prometheus.GaugeOpts{
- Name: "client_in_flight_requests",
- Help: "A gauge of in-flight requests for the wrapped client.",
- })
-
- counter := prometheus.NewCounterVec(
- prometheus.CounterOpts{
- Name: "client_api_requests_total",
- Help: "A counter for requests from the wrapped client.",
- },
- []string{"code", "method"},
- )
-
- dnsLatencyVec := prometheus.NewHistogramVec(
- prometheus.HistogramOpts{
- Name: "dns_duration_seconds",
- Help: "Trace dns latency histogram.",
- Buckets: []float64{.005, .01, .025, .05},
- },
- []string{"event"},
- )
-
- tlsLatencyVec := prometheus.NewHistogramVec(
- prometheus.HistogramOpts{
- Name: "tls_duration_seconds",
- Help: "Trace tls latency histogram.",
- Buckets: []float64{.05, .1, .25, .5},
- },
- []string{"event"},
- )
-
- histVec := prometheus.NewHistogramVec(
- prometheus.HistogramOpts{
- Name: "request_duration_seconds",
- Help: "A histogram of request latencies.",
- Buckets: prometheus.DefBuckets,
- },
- []string{"method"},
- )
-
- reg.MustRegister(counter, tlsLatencyVec, dnsLatencyVec, histVec, inFlightGauge)
-
- trace := &InstrumentTrace{
- DNSStart: func(t float64) {
- dnsLatencyVec.WithLabelValues("dns_start")
- },
- DNSDone: func(t float64) {
- dnsLatencyVec.WithLabelValues("dns_done")
- },
- TLSHandshakeStart: func(t float64) {
- tlsLatencyVec.WithLabelValues("tls_handshake_start")
- },
- TLSHandshakeDone: func(t float64) {
- tlsLatencyVec.WithLabelValues("tls_handshake_done")
- },
- }
-
- client.Transport = InstrumentRoundTripperInFlight(inFlightGauge,
- InstrumentRoundTripperCounter(counter,
- InstrumentRoundTripperTrace(trace,
- InstrumentRoundTripperDuration(histVec, http.DefaultTransport),
- ),
- ),
- )
-
- resp, err := client.Get("http://google.com")
- if err != nil {
- t.Fatalf("%v", err)
- }
- defer resp.Body.Close()
-}
-
-func ExampleInstrumentRoundTripperDuration() {
- client := http.DefaultClient
- client.Timeout = 1 * time.Second
-
- inFlightGauge := prometheus.NewGauge(prometheus.GaugeOpts{
- Name: "client_in_flight_requests",
- Help: "A gauge of in-flight requests for the wrapped client.",
- })
-
- counter := prometheus.NewCounterVec(
- prometheus.CounterOpts{
- Name: "client_api_requests_total",
- Help: "A counter for requests from the wrapped client.",
- },
- []string{"code", "method"},
- )
-
- // dnsLatencyVec uses custom buckets based on expected dns durations.
- // It has an instance label "event", which is set in the
- // DNSStart and DNSDonehook functions defined in the
- // InstrumentTrace struct below.
- dnsLatencyVec := prometheus.NewHistogramVec(
- prometheus.HistogramOpts{
- Name: "dns_duration_seconds",
- Help: "Trace dns latency histogram.",
- Buckets: []float64{.005, .01, .025, .05},
- },
- []string{"event"},
- )
-
- // tlsLatencyVec uses custom buckets based on expected tls durations.
- // It has an instance label "event", which is set in the
- // TLSHandshakeStart and TLSHandshakeDone hook functions defined in the
- // InstrumentTrace struct below.
- tlsLatencyVec := prometheus.NewHistogramVec(
- prometheus.HistogramOpts{
- Name: "tls_duration_seconds",
- Help: "Trace tls latency histogram.",
- Buckets: []float64{.05, .1, .25, .5},
- },
- []string{"event"},
- )
-
- // histVec has no labels, making it a zero-dimensional ObserverVec.
- histVec := prometheus.NewHistogramVec(
- prometheus.HistogramOpts{
- Name: "request_duration_seconds",
- Help: "A histogram of request latencies.",
- Buckets: prometheus.DefBuckets,
- },
- []string{},
- )
-
- // Register all of the metrics in the standard registry.
- prometheus.MustRegister(counter, tlsLatencyVec, dnsLatencyVec, histVec, inFlightGauge)
-
- // Define functions for the available httptrace.ClientTrace hook
- // functions that we want to instrument.
- trace := &InstrumentTrace{
- DNSStart: func(t float64) {
- dnsLatencyVec.WithLabelValues("dns_start")
- },
- DNSDone: func(t float64) {
- dnsLatencyVec.WithLabelValues("dns_done")
- },
- TLSHandshakeStart: func(t float64) {
- tlsLatencyVec.WithLabelValues("tls_handshake_start")
- },
- TLSHandshakeDone: func(t float64) {
- tlsLatencyVec.WithLabelValues("tls_handshake_done")
- },
- }
-
- // Wrap the default RoundTripper with middleware.
- roundTripper := InstrumentRoundTripperInFlight(inFlightGauge,
- InstrumentRoundTripperCounter(counter,
- InstrumentRoundTripperTrace(trace,
- InstrumentRoundTripperDuration(histVec, http.DefaultTransport),
- ),
- ),
- )
-
- // Set the RoundTripper on our client.
- client.Transport = roundTripper
-
- resp, err := client.Get("http://google.com")
- if err != nil {
- log.Printf("error: %v", err)
- }
- defer resp.Body.Close()
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
deleted file mode 100644
index 1beab4b42..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
+++ /dev/null
@@ -1,473 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package promhttp
-
-import (
- "bufio"
- "io"
- "net"
- "net/http"
- "strconv"
- "strings"
- "time"
-
- dto "github.com/prometheus/client_model/go"
-
- "github.com/prometheus/client_golang/prometheus"
-)
-
-// magicString is used for the hacky label test in checkLabels. Remove once fixed.
-const magicString = "zZgWfBxLqvG8kc8IMv3POi2Bb0tZI3vAnBx+gBaFi9FyPzB/CzKUer1yufDa"
-
-// InstrumentHandlerInFlight is a middleware that wraps the provided
-// http.Handler. It sets the provided prometheus.Gauge to the number of
-// requests currently handled by the wrapped http.Handler.
-//
-// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- g.Inc()
- defer g.Dec()
- next.ServeHTTP(w, r)
- })
-}
-
-// InstrumentHandlerDuration is a middleware that wraps the provided
-// http.Handler to observe the request duration with the provided ObserverVec.
-// The ObserverVec must have zero, one, or two labels. The only allowed label
-// names are "code" and "method". The function panics if any other instance
-// labels are provided. The Observe method of the Observer in the ObserverVec
-// is called with the request duration in seconds. Partitioning happens by HTTP
-// status code and/or HTTP method if the respective instance label names are
-// present in the ObserverVec. For unpartitioned observations, use an
-// ObserverVec with zero labels. Note that partitioning of Histograms is
-// expensive and should be used judiciously.
-//
-// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
-//
-// If the wrapped Handler panics, no values are reported.
-func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
- code, method := checkLabels(obs)
-
- if code {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- now := time.Now()
- d := newDelegator(w)
- next.ServeHTTP(d, r)
-
- obs.With(labels(code, method, r.Method, d.Status())).Observe(time.Since(now).Seconds())
- })
- }
-
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- now := time.Now()
- next.ServeHTTP(w, r)
- obs.With(labels(code, method, r.Method, 0)).Observe(time.Since(now).Seconds())
- })
-}
-
-// InstrumentHandlerCounter is a middleware that wraps the provided
-// http.Handler to observe the request result with the provided CounterVec.
-// The CounterVec must have zero, one, or two labels. The only allowed label
-// names are "code" and "method". The function panics if any other instance
-// labels are provided. Partitioning of the CounterVec happens by HTTP status
-// code and/or HTTP method if the respective instance label names are present
-// in the CounterVec. For unpartitioned counting, use a CounterVec with
-// zero labels.
-//
-// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
-//
-// If the wrapped Handler panics, the Counter is not incremented.
-//
-// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler) http.HandlerFunc {
- code, method := checkLabels(counter)
-
- if code {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- d := newDelegator(w)
- next.ServeHTTP(d, r)
- counter.With(labels(code, method, r.Method, d.Status())).Inc()
- })
- }
-
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- next.ServeHTTP(w, r)
- counter.With(labels(code, method, r.Method, 0)).Inc()
- })
-}
-
-// InstrumentHandlerRequestSize is a middleware that wraps the provided
-// http.Handler to observe the request size with the provided ObserverVec.
-// The ObserverVec must have zero, one, or two labels. The only allowed label
-// names are "code" and "method". The function panics if any other instance
-// labels are provided. The Observe method of the Observer in the ObserverVec
-// is called with the request size in bytes. Partitioning happens by HTTP
-// status code and/or HTTP method if the respective instance label names are
-// present in the ObserverVec. For unpartitioned observations, use an
-// ObserverVec with zero labels. Note that partitioning of Histograms is
-// expensive and should be used judiciously.
-//
-// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
-//
-// If the wrapped Handler panics, no values are reported.
-//
-// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
- code, method := checkLabels(obs)
-
- if code {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- d := newDelegator(w)
- next.ServeHTTP(d, r)
- size := computeApproximateRequestSize(r)
- obs.With(labels(code, method, r.Method, d.Status())).Observe(float64(size))
- })
- }
-
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- next.ServeHTTP(w, r)
- size := computeApproximateRequestSize(r)
- obs.With(labels(code, method, r.Method, 0)).Observe(float64(size))
- })
-}
-
-// InstrumentHandlerResponseSize is a middleware that wraps the provided
-// http.Handler to observe the response size with the provided ObserverVec.
-// The ObserverVec must have zero, one, or two labels. The only allowed label
-// names are "code" and "method". The function panics if any other instance
-// labels are provided. The Observe method of the Observer in the ObserverVec
-// is called with the response size in bytes. Partitioning happens by HTTP
-// status code and/or HTTP method if the respective instance label names are
-// present in the ObserverVec. For unpartitioned observations, use an
-// ObserverVec with zero labels. Note that partitioning of Histograms is
-// expensive and should be used judiciously.
-//
-// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
-//
-// If the wrapped Handler panics, no values are reported.
-//
-// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler) http.Handler {
- code, method := checkLabels(obs)
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- d := newDelegator(w)
- next.ServeHTTP(d, r)
- obs.With(labels(code, method, r.Method, d.Status())).Observe(float64(d.Written()))
- })
-}
-
-func checkLabels(c prometheus.Collector) (code bool, method bool) {
- // TODO(beorn7): Remove this hacky way to check for instance labels
- // once Descriptors can have their dimensionality queried.
- var (
- desc *prometheus.Desc
- pm dto.Metric
- )
-
- descc := make(chan *prometheus.Desc, 1)
- c.Describe(descc)
-
- select {
- case desc = <-descc:
- default:
- panic("no description provided by collector")
- }
- select {
- case <-descc:
- panic("more than one description provided by collector")
- default:
- }
-
- close(descc)
-
- if _, err := prometheus.NewConstMetric(desc, prometheus.UntypedValue, 0); err == nil {
- return
- }
- if m, err := prometheus.NewConstMetric(desc, prometheus.UntypedValue, 0, magicString); err == nil {
- if err := m.Write(&pm); err != nil {
- panic("error checking metric for labels")
- }
- for _, label := range pm.Label {
- name, value := label.GetName(), label.GetValue()
- if value != magicString {
- continue
- }
- switch name {
- case "code":
- code = true
- case "method":
- method = true
- default:
- panic("metric partitioned with non-supported labels")
- }
- return
- }
- panic("previously set label not found – this must never happen")
- }
- if m, err := prometheus.NewConstMetric(desc, prometheus.UntypedValue, 0, magicString, magicString); err == nil {
- if err := m.Write(&pm); err != nil {
- panic("error checking metric for labels")
- }
- for _, label := range pm.Label {
- name, value := label.GetName(), label.GetValue()
- if value != magicString {
- continue
- }
- if name == "code" || name == "method" {
- continue
- }
- panic("metric partitioned with non-supported labels")
- }
- code = true
- method = true
- return
- }
- panic("metric partitioned with non-supported labels")
-}
-
-// emptyLabels is a one-time allocation for non-partitioned metrics to avoid
-// unnecessary allocations on each request.
-var emptyLabels = prometheus.Labels{}
-
-func labels(code, method bool, reqMethod string, status int) prometheus.Labels {
- if !(code || method) {
- return emptyLabels
- }
- labels := prometheus.Labels{}
-
- if code {
- labels["code"] = sanitizeCode(status)
- }
- if method {
- labels["method"] = sanitizeMethod(reqMethod)
- }
-
- return labels
-}
-
-func computeApproximateRequestSize(r *http.Request) int {
- s := 0
- if r.URL != nil {
- s += len(r.URL.String())
- }
-
- s += len(r.Method)
- s += len(r.Proto)
- for name, values := range r.Header {
- s += len(name)
- for _, value := range values {
- s += len(value)
- }
- }
- s += len(r.Host)
-
- // N.B. r.Form and r.MultipartForm are assumed to be included in r.URL.
-
- if r.ContentLength != -1 {
- s += int(r.ContentLength)
- }
- return s
-}
-
-func sanitizeMethod(m string) string {
- switch m {
- case "GET", "get":
- return "get"
- case "PUT", "put":
- return "put"
- case "HEAD", "head":
- return "head"
- case "POST", "post":
- return "post"
- case "DELETE", "delete":
- return "delete"
- case "CONNECT", "connect":
- return "connect"
- case "OPTIONS", "options":
- return "options"
- case "NOTIFY", "notify":
- return "notify"
- default:
- return strings.ToLower(m)
- }
-}
-
-// If the wrapped http.Handler has not set a status code, i.e. the value is
-// currently 0, santizeCode will return 200, for consistency with behavior in
-// the stdlib.
-func sanitizeCode(s int) string {
- switch s {
- case 100:
- return "100"
- case 101:
- return "101"
-
- case 200, 0:
- return "200"
- case 201:
- return "201"
- case 202:
- return "202"
- case 203:
- return "203"
- case 204:
- return "204"
- case 205:
- return "205"
- case 206:
- return "206"
-
- case 300:
- return "300"
- case 301:
- return "301"
- case 302:
- return "302"
- case 304:
- return "304"
- case 305:
- return "305"
- case 307:
- return "307"
-
- case 400:
- return "400"
- case 401:
- return "401"
- case 402:
- return "402"
- case 403:
- return "403"
- case 404:
- return "404"
- case 405:
- return "405"
- case 406:
- return "406"
- case 407:
- return "407"
- case 408:
- return "408"
- case 409:
- return "409"
- case 410:
- return "410"
- case 411:
- return "411"
- case 412:
- return "412"
- case 413:
- return "413"
- case 414:
- return "414"
- case 415:
- return "415"
- case 416:
- return "416"
- case 417:
- return "417"
- case 418:
- return "418"
-
- case 500:
- return "500"
- case 501:
- return "501"
- case 502:
- return "502"
- case 503:
- return "503"
- case 504:
- return "504"
- case 505:
- return "505"
-
- case 428:
- return "428"
- case 429:
- return "429"
- case 431:
- return "431"
- case 511:
- return "511"
-
- default:
- return strconv.Itoa(s)
- }
-}
-
-type delegator interface {
- Status() int
- Written() int64
-
- http.ResponseWriter
-}
-
-type responseWriterDelegator struct {
- http.ResponseWriter
-
- handler, method string
- status int
- written int64
- wroteHeader bool
-}
-
-func (r *responseWriterDelegator) Status() int {
- return r.status
-}
-
-func (r *responseWriterDelegator) Written() int64 {
- return r.written
-}
-
-func (r *responseWriterDelegator) WriteHeader(code int) {
- r.status = code
- r.wroteHeader = true
- r.ResponseWriter.WriteHeader(code)
-}
-
-func (r *responseWriterDelegator) Write(b []byte) (int, error) {
- if !r.wroteHeader {
- r.WriteHeader(http.StatusOK)
- }
- n, err := r.ResponseWriter.Write(b)
- r.written += int64(n)
- return n, err
-}
-
-type fancyDelegator struct {
- *responseWriterDelegator
-}
-
-func (r *fancyDelegator) CloseNotify() <-chan bool {
- return r.ResponseWriter.(http.CloseNotifier).CloseNotify()
-}
-
-func (r *fancyDelegator) Hijack() (net.Conn, *bufio.ReadWriter, error) {
- return r.ResponseWriter.(http.Hijacker).Hijack()
-}
-
-func (r *fancyDelegator) Flush() {
- r.ResponseWriter.(http.Flusher).Flush()
-}
-
-func (r *fancyDelegator) ReadFrom(re io.Reader) (int64, error) {
- if !r.wroteHeader {
- r.WriteHeader(http.StatusOK)
- }
- n, err := r.ResponseWriter.(io.ReaderFrom).ReadFrom(re)
- r.written += n
- return n, err
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server_test.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server_test.go
deleted file mode 100644
index ca9f4bf3c..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server_test.go
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package promhttp
-
-import (
- "log"
- "net/http"
- "net/http/httptest"
- "testing"
-
- "github.com/prometheus/client_golang/prometheus"
-)
-
-func TestMiddlewareAPI(t *testing.T) {
- reg := prometheus.NewRegistry()
-
- inFlightGauge := prometheus.NewGauge(prometheus.GaugeOpts{
- Name: "in_flight_requests",
- Help: "A gauge of requests currently being served by the wrapped handler.",
- })
-
- counter := prometheus.NewCounterVec(
- prometheus.CounterOpts{
- Name: "api_requests_total",
- Help: "A counter for requests to the wrapped handler.",
- },
- []string{"code", "method"},
- )
-
- histVec := prometheus.NewHistogramVec(
- prometheus.HistogramOpts{
- Name: "response_duration_seconds",
- Help: "A histogram of request latencies.",
- Buckets: prometheus.DefBuckets,
- ConstLabels: prometheus.Labels{"handler": "api"},
- },
- []string{"method"},
- )
-
- responseSize := prometheus.NewHistogramVec(
- prometheus.HistogramOpts{
- Name: "push_request_size_bytes",
- Help: "A histogram of request sizes for requests.",
- Buckets: []float64{200, 500, 900, 1500},
- },
- []string{},
- )
-
- handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Write([]byte("OK"))
- })
-
- reg.MustRegister(inFlightGauge, counter, histVec, responseSize)
-
- chain := InstrumentHandlerInFlight(inFlightGauge,
- InstrumentHandlerCounter(counter,
- InstrumentHandlerDuration(histVec,
- InstrumentHandlerResponseSize(responseSize, handler),
- ),
- ),
- )
-
- r, _ := http.NewRequest("GET", "www.example.com", nil)
- w := httptest.NewRecorder()
- chain.ServeHTTP(w, r)
-}
-
-func ExampleInstrumentHandlerDuration() {
- inFlightGauge := prometheus.NewGauge(prometheus.GaugeOpts{
- Name: "in_flight_requests",
- Help: "A gauge of requests currently being served by the wrapped handler.",
- })
-
- counter := prometheus.NewCounterVec(
- prometheus.CounterOpts{
- Name: "api_requests_total",
- Help: "A counter for requests to the wrapped handler.",
- },
- []string{"code", "method"},
- )
-
- // pushVec and pullVec are partitioned by the HTTP method and use custom
- // buckets based on the expected request duration. ConstLabels are used
- // to set a handler label to mark pushVec as tracking the durations for
- // pushes and pullVec as tracking the durations for pulls. Note that
- // Name, Help, and Buckets need to be the same for consistency, so we
- // use the same HistogramOpts after just modifying the ConstLabels.
- histogramOpts := prometheus.HistogramOpts{
- Name: "request_duration_seconds",
- Help: "A histogram of latencies for requests.",
- Buckets: []float64{.25, .5, 1, 2.5, 5, 10},
- ConstLabels: prometheus.Labels{"handler": "push"},
- }
- pushVec := prometheus.NewHistogramVec(
- histogramOpts,
- []string{"method"},
- )
- histogramOpts.ConstLabels = prometheus.Labels{"handler": "pull"}
- pullVec := prometheus.NewHistogramVec(
- histogramOpts,
- []string{"method"},
- )
-
- // responseSize has no labels, making it a zero-dimensional
- // ObserverVec.
- responseSize := prometheus.NewHistogramVec(
- prometheus.HistogramOpts{
- Name: "response_size_bytes",
- Help: "A histogram of response sizes for requests.",
- Buckets: []float64{200, 500, 900, 1500},
- },
- []string{},
- )
-
- // Create the handlers that will be wrapped by the middleware.
- pushHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Write([]byte("Push"))
- })
- pullHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Write([]byte("Pull"))
- })
-
- // Register all of the metrics in the standard registry.
- prometheus.MustRegister(inFlightGauge, counter, pullVec, pushVec, responseSize)
-
- // Wrap the pushHandler with our shared middleware, but use the
- // endpoint-specific pushVec with InstrumentHandlerDuration.
- pushChain := InstrumentHandlerInFlight(inFlightGauge,
- InstrumentHandlerCounter(counter,
- InstrumentHandlerDuration(pushVec,
- InstrumentHandlerResponseSize(responseSize, pushHandler),
- ),
- ),
- )
-
- // Wrap the pushHandler with the shared middleware, but use the
- // endpoint-specific pullVec with InstrumentHandlerDuration.
- pullChain := InstrumentHandlerInFlight(inFlightGauge,
- InstrumentHandlerCounter(counter,
- InstrumentHandlerDuration(pullVec,
- InstrumentHandlerResponseSize(responseSize, pullHandler),
- ),
- ),
- )
-
- http.Handle("/metrics", Handler())
- http.Handle("/push", pushChain)
- http.Handle("/pull", pullChain)
-
- if err := http.ListenAndServe(":3000", nil); err != nil {
- log.Fatal(err)
- }
-}