Improve timer examples

This commit is contained in:
beorn7 2016-11-17 12:56:06 +01:00
parent 89ca0458cb
commit bc365741ee
4 changed files with 47 additions and 55 deletions

View File

@ -1,48 +0,0 @@
// Copyright 2014 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 prometheus_test
import (
"time"
"github.com/prometheus/client_golang/prometheus"
)
var (
// For periodic or batch processes that run much less frequently than
// the Prometheus scrape, it makes sense to use a Gauge to observe the
// duration.
// See https://prometheus.io/docs/practices/instrumentation/#batch-jobs
batchDuration = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "example_batch_duration_seconds",
Help: "Duration of the last batch run.",
})
)
func performBatch() {
// The Set method of the Gauge is used to observe the duration.
timer := prometheus.NewTimer(prometheus.ObserverFunc(batchDuration.Set))
defer timer.ObserveDuration()
// Actually perform the batch of work.
// ...
}
func ExampleTimer_batch() {
// 10m is much longer than the usual scrape interval of Prometheus.
c := time.Tick(10 * time.Minute)
for _ = range c {
performBatch()
}
}

View File

@ -29,7 +29,9 @@ var (
// even larger amount of time series. Request counters partitioned by // even larger amount of time series. Request counters partitioned by
// status code are usually OK as each counter only creates one time // status code are usually OK as each counter only creates one time
// series. Histograms are way more expensive, so partition with care and // series. Histograms are way more expensive, so partition with care and
// only where you really need separate latency tracking. // only where you really need separate latency tracking. Partitioning by
// status class is only an example. In concrete cases, other partitions
// might make more sense.
apiRequestDuration = prometheus.NewHistogramVec( apiRequestDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{ prometheus.HistogramOpts{
Name: "api_request_duration_seconds", Name: "api_request_duration_seconds",
@ -46,15 +48,15 @@ func handler(w http.ResponseWriter, r *http.Request) {
// decides wich Histogram's Observe method is called. // decides wich Histogram's Observe method is called.
timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) { timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
switch { switch {
case status >= http.StatusInternalServerError: case status >= 500: // Server error.
apiRequestDuration.WithLabelValues("5xx").Observe(v) apiRequestDuration.WithLabelValues("5xx").Observe(v)
case status >= http.StatusBadRequest: case status >= 400: // Client error.
apiRequestDuration.WithLabelValues("4xx").Observe(v) apiRequestDuration.WithLabelValues("4xx").Observe(v)
case status >= http.StatusMultipleChoices: case status >= 300: // Redirection.
apiRequestDuration.WithLabelValues("3xx").Observe(v) apiRequestDuration.WithLabelValues("3xx").Observe(v)
case status >= http.StatusOK: case status >= 200: // Success.
apiRequestDuration.WithLabelValues("2xx").Observe(v) apiRequestDuration.WithLabelValues("2xx").Observe(v)
default: default: // Informational.
apiRequestDuration.WithLabelValues("1xx").Observe(v) apiRequestDuration.WithLabelValues("1xx").Observe(v)
} }
})) }))

View File

@ -0,0 +1,38 @@
// Copyright 2014 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 prometheus_test
import "github.com/prometheus/client_golang/prometheus"
var (
// If a function is called rarely (i.e. not more often than scrapes
// happen) or ideally only once (like in a batch job), it can make sense
// to use a Gauge for timing the function call. For timing a batch job
// and pushing the result to a Pushgateway, see also the comprehensive
// example in the push package.
funcDuration = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "example_function_duration_seconds",
Help: "Duration of the last call of an example function.",
})
)
func ExampleTimer_gauge() error {
// The Set method of the Gauge is used to observe the duration.
timer := prometheus.NewTimer(prometheus.ObserverFunc(funcDuration.Set))
defer timer.ObserveDuration()
// Do something. Return errors as encountered. The use of 'defer' above
// makes sure the function is still timed properly.
return nil
}

View File

@ -29,7 +29,7 @@ type Observer interface {
// two general use cases: // two general use cases:
// //
// The most common one is to use a Gauge as the Observer for a Timer. // The most common one is to use a Gauge as the Observer for a Timer.
// See the "Batch" Timer example. // See the "Gauge" Timer example.
// //
// The more advanced use case is to create a function that dynamically decides // The more advanced use case is to create a function that dynamically decides
// which Observer to use for observing the duration. See the "Complex" Timer // which Observer to use for observing the duration. See the "Complex" Timer