blob: 537e2e966832bb731f24e8977ef0281f950af34f [file] [log] [blame]
// Copyright 2018 The Kubernetes 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 metrics
import (
"time"
"github.com/prometheus/client_golang/prometheus"
)
// BucketsForScrapeDuration calculates a variant of the prometheus default histogram
// buckets that includes relevant buckets around out scrape timeout.
func BucketsForScrapeDuration(scrapeTimeout time.Duration) []float64 {
// set up some buckets that include our scrape timeout,
// so that we can easily pinpoint scrape timeout issues.
// The default buckets provide a sane starting point for
// the smaller numbers.
buckets := append([]float64(nil), prometheus.DefBuckets...)
maxBucket := buckets[len(buckets)-1]
timeoutSeconds := float64(scrapeTimeout) / float64(time.Second)
if timeoutSeconds > maxBucket {
// [defaults, (scrapeTimeout + (scrapeTimeout - maxBucket)/ 2), scrapeTimeout, scrapeTimeout*1.5, scrapeTimeout*2]
halfwayToScrapeTimeout := maxBucket + (timeoutSeconds-maxBucket)/2
buckets = append(buckets, halfwayToScrapeTimeout, timeoutSeconds, timeoutSeconds*1.5, timeoutSeconds*2.0)
} else if timeoutSeconds < maxBucket {
var i int
var bucket float64
for i, bucket = range buckets {
if bucket > timeoutSeconds {
break
}
}
if bucket-timeoutSeconds < buckets[0] || (i > 0 && timeoutSeconds-buckets[i-1] < buckets[0]) {
// if we're sufficiently close to another bucket, just skip this
return buckets
}
// likely that our scrape timeout is close to another bucket, so don't bother injecting more than just our scrape timeout
oldRest := append([]float64(nil), buckets[i:]...) // make a copy so we don't overwrite it
buckets = append(buckets[:i], timeoutSeconds)
buckets = append(buckets, oldRest...)
}
return buckets
}