Rearrange file and package per convention.
WIP - Please review but do not merge.
This commit is contained in:
parent
a087e013a5
commit
f320d28a6c
|
@ -1,8 +1,4 @@
|
||||||
language: go
|
language: go
|
||||||
|
|
||||||
before_script:
|
|
||||||
- go get -v github.com/prometheus/client_golang
|
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- go build -a -v github.com/prometheus/client_golang/...
|
- make -f Makefile.TRAVIS
|
||||||
- go test -v github.com/prometheus/client_golang/...
|
|
||||||
|
|
4
LICENSE
4
LICENSE
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2012, Matt T. Proud
|
Copyright (c) 2013, Prometheus Team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -19,4 +19,4 @@ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
16
Makefile
16
Makefile
|
@ -16,17 +16,20 @@ MAKE_ARTIFACTS = search_index
|
||||||
all: test
|
all: test
|
||||||
|
|
||||||
build:
|
build:
|
||||||
go build ./...
|
$(MAKE) -C prometheus build
|
||||||
|
$(MAKE) -C examples build
|
||||||
|
|
||||||
test: build
|
test: build
|
||||||
go test ./... $(GO_TEST_FLAGS)
|
$(MAKE) -C prometheus test
|
||||||
|
$(MAKE) -C examples test
|
||||||
|
|
||||||
|
advice: test
|
||||||
|
$(MAKE) -C prometheus advice
|
||||||
|
$(MAKE) -C examples advice
|
||||||
|
|
||||||
format:
|
format:
|
||||||
find . -iname '*.go' -exec gofmt -w -s=true '{}' ';'
|
find . -iname '*.go' -exec gofmt -w -s=true '{}' ';'
|
||||||
|
|
||||||
advice:
|
|
||||||
go tool vet .
|
|
||||||
|
|
||||||
search_index:
|
search_index:
|
||||||
godoc -index -write_index -index_files='search_index'
|
godoc -index -write_index -index_files='search_index'
|
||||||
|
|
||||||
|
@ -34,6 +37,9 @@ documentation: search_index
|
||||||
godoc -http=:6060 -index -index_files='search_index'
|
godoc -http=:6060 -index -index_files='search_index'
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
$(MAKE) -C examples clean
|
||||||
rm -f $(MAKE_ARTIFACTS)
|
rm -f $(MAKE_ARTIFACTS)
|
||||||
|
find . -iname '*~' -exec rm -f '{}' ';'
|
||||||
|
find . -iname '*#' -exec rm -f '{}' ';'
|
||||||
|
|
||||||
.PHONY: advice build clean documentation format test
|
.PHONY: advice build clean documentation format test
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Copyright 2013 Prometheus Team
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
PROMETHEUS_TARGET := "${GOPATH}/src/github.com/prometheus"
|
||||||
|
|
||||||
|
all: test
|
||||||
|
|
||||||
|
preparation:
|
||||||
|
mkdir -vp $(PROMETHEUS_TARGET)
|
||||||
|
ln -sf "$(PWD)" $(PROMETHEUS_TARGET)
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
go get github.com/matttproud/gocheck
|
||||||
|
|
||||||
|
test: dependencies preparation
|
||||||
|
$(MAKE) test
|
||||||
|
|
||||||
|
.PHONY: dependencies preparation test
|
3
TODO
3
TODO
|
@ -1,5 +1,2 @@
|
||||||
- Validate repository for Go code fluency and idiomatic adherence.
|
- Validate repository for Go code fluency and idiomatic adherence.
|
||||||
- Decouple HTTP report handler from our project and incorporate into this
|
|
||||||
repository.
|
|
||||||
- Implement labeled metric support.
|
|
||||||
- Evaluate using atomic types versus locks.
|
- Evaluate using atomic types versus locks.
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be found
|
|
||||||
// in the LICENSE file.
|
|
||||||
|
|
||||||
// registry.go provides a container for centralized exposition of metrics to
|
|
||||||
// their prospective consumers.
|
|
||||||
//
|
|
||||||
// registry.Register("human_readable_metric_name", "metric docstring", map[string]string{"baseLabel": "baseLabelValue"}, metric)
|
|
||||||
package registry
|
|
|
@ -1,8 +1,49 @@
|
||||||
// Copyright (c) 2013, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style license that can be found
|
// Use of this source code is governed by a BSD-style license that can be found
|
||||||
// in the LICENSE file.
|
// in the LICENSE file.
|
||||||
|
|
||||||
// A repository of various Prometheus client documentation and advice.
|
// A repository of various Prometheus client documentation and advice.
|
||||||
|
//
|
||||||
|
// Please try to observe the following rules when naming metrics:
|
||||||
|
//
|
||||||
|
// - Use underbars "_" to separate words.
|
||||||
|
//
|
||||||
|
// - Have the metric name start from generality and work toward specificity
|
||||||
|
// toward the end. For example, when working with multiple caching subsystems,
|
||||||
|
// consider using the following structure "cache" + "user_credentials" →
|
||||||
|
// "cache_user_credentials" and "cache" + "value_transformations" →
|
||||||
|
// "cache_value_transformations".
|
||||||
|
//
|
||||||
|
// - Have whatever is being measured follow the system and subsystem names cited
|
||||||
|
// supra. For instance, with "insertions", "deletions", "evictions",
|
||||||
|
// "replacements" of the above cache, they should be named as
|
||||||
|
// "cache_user_credentials_insertions" and "cache_user_credentials_deletions"
|
||||||
|
// and "cache_user_credentials_deletions" and
|
||||||
|
// "cache_user_credentials_evictions".
|
||||||
|
//
|
||||||
|
// - If what is being measured has a standardized unit around it, consider
|
||||||
|
// providing a unit for it.
|
||||||
|
//
|
||||||
|
// - Consider adding an additional suffix that designates what the value
|
||||||
|
// represents such as a "total" or "size"---e.g.,
|
||||||
|
// "cache_user_credentials_size_kb" or
|
||||||
|
// "cache_user_credentials_insertions_total".
|
||||||
|
//
|
||||||
|
// - Give heed to how future-proof the names are. Things may depend on these
|
||||||
|
// names; and as your service evolves, the calculated values may take on
|
||||||
|
// different meanings, which can be difficult to reflect if deployed code
|
||||||
|
// depends on antique names.
|
||||||
|
//
|
||||||
|
// Further considerations:
|
||||||
|
//
|
||||||
|
// - The Registry's exposition mechanism is not backed by authorization and
|
||||||
|
// authentication. This is something that will need to be addressed for
|
||||||
|
// production services that are directly exposed to the outside world.
|
||||||
|
//
|
||||||
|
// - Engage in as little in-process processing of values as possible. The job
|
||||||
|
// of processing and aggregation of these values belongs in a separate
|
||||||
|
// post-processing job. The same goes for archiving. I will need to evaluate
|
||||||
|
// hooks into something like OpenTSBD.
|
||||||
package documentation
|
package documentation
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
// Copyright (c) 2013, Matt T. Proud
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be found
|
|
||||||
// in the LICENSE file.
|
|
||||||
|
|
||||||
// Please try to observe the following rules when naming metrics:
|
|
||||||
//
|
|
||||||
// - Use underbars "_" to separate words.
|
|
||||||
//
|
|
||||||
// - Have the metric name start from generality and work toward specificity
|
|
||||||
// toward the end. For example, when working with multiple caching subsystems,
|
|
||||||
// consider using the following structure "cache" + "user_credentials" →
|
|
||||||
// "cache_user_credentials" and "cache" + "value_transformations" →
|
|
||||||
// "cache_value_transformations".
|
|
||||||
//
|
|
||||||
// - Have whatever is being measured follow the system and subsystem names cited
|
|
||||||
// supra. For instance, with "insertions", "deletions", "evictions",
|
|
||||||
// "replacements" of the above cache, they should be named as
|
|
||||||
// "cache_user_credentials_insertions" and "cache_user_credentials_deletions"
|
|
||||||
// and "cache_user_credentials_deletions" and
|
|
||||||
// "cache_user_credentials_evictions".
|
|
||||||
//
|
|
||||||
// - If what is being measured has a standardized unit around it, consider
|
|
||||||
// providing a unit for it.
|
|
||||||
//
|
|
||||||
// - Consider adding an additional suffix that designates what the value
|
|
||||||
// represents such as a "total" or "size"---e.g.,
|
|
||||||
// "cache_user_credentials_size_kb" or
|
|
||||||
// "cache_user_credentials_insertions_total".
|
|
||||||
//
|
|
||||||
// - Give heed to how future-proof the names are. Things may depend on these
|
|
||||||
// names; and as your service evolves, the calculated values may take on
|
|
||||||
// different meanings, which can be difficult to reflect if deployed code
|
|
||||||
// depends on antique names.
|
|
||||||
//
|
|
||||||
// Further considerations:
|
|
||||||
//
|
|
||||||
// - The Registry's exposition mechanism is not backed by authorization and
|
|
||||||
// authentication. This is something that will need to be addressed for
|
|
||||||
// production services that are directly exposed to the outside world.
|
|
||||||
//
|
|
||||||
// - Engage in as little in-process processing of values as possible. The job
|
|
||||||
// of processing and aggregation of these values belongs in a separate
|
|
||||||
// post-processing job. The same goes for archiving. I will need to evaluate
|
|
||||||
// hooks into something like OpenTSBD.
|
|
||||||
|
|
||||||
package documentation
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
# Copyright 2013 Prometheus Team
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
all: test
|
||||||
|
|
||||||
|
build:
|
||||||
|
$(MAKE) -C delegator build
|
||||||
|
$(MAKE) -C random build
|
||||||
|
$(MAKE) -C simple build
|
||||||
|
|
||||||
|
test: build
|
||||||
|
$(MAKE) -C delegator test
|
||||||
|
$(MAKE) -C random test
|
||||||
|
$(MAKE) -C simple test
|
||||||
|
|
||||||
|
advice: test
|
||||||
|
$(MAKE) -C delegator advice
|
||||||
|
$(MAKE) -C random advice
|
||||||
|
$(MAKE) -C simple advice
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(MAKE) -C delegator clean
|
||||||
|
$(MAKE) -C random clean
|
||||||
|
$(MAKE) -C simple clean
|
||||||
|
|
||||||
|
.PHONY: advice build clean test
|
|
@ -0,0 +1 @@
|
||||||
|
delegator
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Copyright 2013 Prometheus Team
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
MAKE_ARTIFACTS = delegator
|
||||||
|
|
||||||
|
all: test
|
||||||
|
|
||||||
|
build: delegator
|
||||||
|
|
||||||
|
delegator:
|
||||||
|
go build .
|
||||||
|
|
||||||
|
test: build
|
||||||
|
go test . $(GO_TEST_FLAGS)
|
||||||
|
|
||||||
|
advice:
|
||||||
|
go tool vet .
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(MAKE_ARTIFACTS)
|
||||||
|
|
||||||
|
.PHONY: advice build clean test
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
|
@ -10,8 +10,8 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"github.com/prometheus/client_golang"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/exp"
|
"github.com/prometheus/client_golang/prometheus/exp"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ func main() {
|
||||||
exp.HandleFunc("/hello", helloHandler)
|
exp.HandleFunc("/hello", helloHandler)
|
||||||
exp.HandleFunc("/goodbye", goodbyeHandler)
|
exp.HandleFunc("/goodbye", goodbyeHandler)
|
||||||
exp.HandleFunc("/teapot", teapotHandler)
|
exp.HandleFunc("/teapot", teapotHandler)
|
||||||
exp.Handle(registry.ExpositionResource, registry.DefaultHandler)
|
exp.Handle(prometheus.ExpositionResource, prometheus.DefaultHandler)
|
||||||
|
|
||||||
http.ListenAndServe(*listeningAddress, exp.DefaultCoarseMux)
|
http.ListenAndServe(*listeningAddress, exp.DefaultCoarseMux)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be found
|
|
||||||
// in the LICENSE file.
|
|
||||||
|
|
||||||
// Various Prometheus client examples.
|
|
||||||
package examples
|
|
|
@ -0,0 +1 @@
|
||||||
|
random
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Copyright 2013 Prometheus Team
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
MAKE_ARTIFACTS = random
|
||||||
|
|
||||||
|
all: test
|
||||||
|
|
||||||
|
build: random
|
||||||
|
|
||||||
|
random:
|
||||||
|
go build .
|
||||||
|
|
||||||
|
test: build
|
||||||
|
go test . $(GO_TEST_FLAGS)
|
||||||
|
|
||||||
|
advice:
|
||||||
|
go tool vet .
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(MAKE_ARTIFACTS)
|
||||||
|
|
||||||
|
.PHONY: advice clean build test
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
|
@ -13,9 +13,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"github.com/prometheus/client_golang"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/maths"
|
|
||||||
"github.com/prometheus/client_golang/metrics"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
@ -28,27 +26,27 @@ var (
|
||||||
|
|
||||||
// Create a histogram to track fictitious interservice RPC latency for three
|
// Create a histogram to track fictitious interservice RPC latency for three
|
||||||
// distinct services.
|
// distinct services.
|
||||||
rpcLatency = metrics.NewHistogram(&metrics.HistogramSpecification{
|
rpcLatency = prometheus.NewHistogram(&prometheus.HistogramSpecification{
|
||||||
// Four distinct histogram buckets for values:
|
// Four distinct histogram buckets for values:
|
||||||
// - equally-sized,
|
// - equally-sized,
|
||||||
// - 0 to 50, 50 to 100, 100 to 150, and 150 to 200.
|
// - 0 to 50, 50 to 100, 100 to 150, and 150 to 200.
|
||||||
Starts: metrics.EquallySizedBucketsFor(0, 200, 4),
|
Starts: prometheus.EquallySizedBucketsFor(0, 200, 4),
|
||||||
// Create histogram buckets using an accumulating bucket, a bucket that
|
// Create histogram buckets using an accumulating bucket, a bucket that
|
||||||
// holds sample values subject to an eviction policy:
|
// holds sample values subject to an eviction policy:
|
||||||
// - 50 elements are allowed per bucket.
|
// - 50 elements are allowed per bucket.
|
||||||
// - Once 50 have been reached, the bucket empties 10 elements, averages the
|
// - Once 50 have been reached, the bucket empties 10 elements, averages the
|
||||||
// evicted elements, and re-appends that back to the bucket.
|
// evicted elements, and re-appends that back to the bucket.
|
||||||
BucketBuilder: metrics.AccumulatingBucketBuilder(metrics.EvictAndReplaceWith(10, maths.Average), 50),
|
BucketBuilder: prometheus.AccumulatingBucketBuilder(prometheus.EvictAndReplaceWith(10, prometheus.AverageReducer), 50),
|
||||||
// The histogram reports percentiles 1, 5, 50, 90, and 99.
|
// The histogram reports percentiles 1, 5, 50, 90, and 99.
|
||||||
ReportablePercentiles: []float64{0.01, 0.05, 0.5, 0.90, 0.99},
|
ReportablePercentiles: []float64{0.01, 0.05, 0.5, 0.90, 0.99},
|
||||||
})
|
})
|
||||||
|
|
||||||
rpcCalls = metrics.NewCounter()
|
rpcCalls = prometheus.NewCounter()
|
||||||
|
|
||||||
// If for whatever reason you are resistant to the idea of having a static
|
// If for whatever reason you are resistant to the idea of having a static
|
||||||
// registry for metrics, which is a really bad idea when using Prometheus-
|
// registry for metrics, which is a really bad idea when using Prometheus-
|
||||||
// enabled library code, you can create your own.
|
// enabled library code, you can create your own.
|
||||||
customRegistry = registry.NewRegistry()
|
customRegistry = prometheus.NewRegistry()
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -69,13 +67,13 @@ func main() {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
http.Handle(registry.ExpositionResource, customRegistry.Handler())
|
http.Handle(prometheus.ExpositionResource, customRegistry.Handler())
|
||||||
http.ListenAndServe(*listeningAddress, nil)
|
http.ListenAndServe(*listeningAddress, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
customRegistry.Register("rpc_latency_microseconds", "RPC latency.", registry.NilLabels, rpcLatency)
|
customRegistry.Register("rpc_latency_microseconds", "RPC latency.", prometheus.NilLabels, rpcLatency)
|
||||||
customRegistry.Register("rpc_calls_total", "RPC calls.", registry.NilLabels, rpcCalls)
|
customRegistry.Register("rpc_calls_total", "RPC calls.", prometheus.NilLabels, rpcCalls)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
simple
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Copyright 2013 Prometheus Team
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
MAKE_ARTIFACTS = simple
|
||||||
|
|
||||||
|
all: test
|
||||||
|
|
||||||
|
build: simple
|
||||||
|
|
||||||
|
simple:
|
||||||
|
go build .
|
||||||
|
|
||||||
|
test: build
|
||||||
|
go test . $(GO_TEST_FLAGS)
|
||||||
|
|
||||||
|
advice:
|
||||||
|
go tool vet .
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(MAKE_ARTIFACTS)
|
||||||
|
|
||||||
|
.PHONY: advice build clean test
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
|
@ -10,14 +10,14 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"github.com/prometheus/client_golang"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
http.Handle(registry.ExpositionResource, registry.DefaultHandler)
|
http.Handle(prometheus.ExpositionResource, prometheus.DefaultHandler)
|
||||||
http.ListenAndServe(*listeningAddress, nil)
|
http.ListenAndServe(*listeningAddress, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// The maths package provides a number of mathematical-related helpers:
|
|
||||||
//
|
|
||||||
// distributions.go provides basic distribution-generating functions that are
|
|
||||||
// used primarily in testing contexts.
|
|
||||||
//
|
|
||||||
// helpers_for_testing.go provides a testing assistents for this package and its
|
|
||||||
// dependents.
|
|
||||||
//
|
|
||||||
// maths_test.go provides a test suite for all tests in the maths package
|
|
||||||
// hierarchy. It employs the gocheck framework for test scaffolding.
|
|
||||||
//
|
|
||||||
// statistics.go provides basic summary statistics functions for the purpose of
|
|
||||||
// metrics aggregation.
|
|
||||||
//
|
|
||||||
// statistics_test.go provides a test complement for the statistics.go module.
|
|
||||||
package maths
|
|
|
@ -1,20 +0,0 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package maths
|
|
||||||
|
|
||||||
import (
|
|
||||||
. "github.com/matttproud/gocheck"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
type S struct{}
|
|
||||||
|
|
||||||
var _ = Suite(&S{})
|
|
||||||
|
|
||||||
func TestMaths(t *testing.T) {
|
|
||||||
TestingT(t)
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// constants.go provides package-level constants for metrics.
|
|
||||||
package metrics
|
|
||||||
|
|
||||||
const (
|
|
||||||
counterTypeValue = "counter"
|
|
||||||
floatBitCount = 64
|
|
||||||
floatFormat = 'f'
|
|
||||||
floatPrecision = 6
|
|
||||||
gaugeTypeValue = "gauge"
|
|
||||||
histogramTypeValue = "histogram"
|
|
||||||
typeKey = "type"
|
|
||||||
valueKey = "value"
|
|
||||||
labelsKey = "labels"
|
|
||||||
)
|
|
|
@ -1,48 +0,0 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// The metrics package provides general descriptors for the concept of
|
|
||||||
// exportable metrics.
|
|
||||||
|
|
||||||
// accumulating_bucket.go provides a histogram bucket type that accumulates
|
|
||||||
// elements until a given capacity and enacts a given eviction policy upon
|
|
||||||
// such a condition.
|
|
||||||
|
|
||||||
// accumulating_bucket_test.go provides a test complement for the
|
|
||||||
// accumulating_bucket_go module.
|
|
||||||
|
|
||||||
// eviction.go provides several histogram bucket eviction strategies.
|
|
||||||
|
|
||||||
// eviction_test.go provides a test complement for the eviction.go module.
|
|
||||||
|
|
||||||
// gauge.go provides a scalar metric that one can monitor. It is useful for
|
|
||||||
// certain cases, such as instantaneous temperature.
|
|
||||||
|
|
||||||
// gauge_test.go provides a test complement for the gauge.go module.
|
|
||||||
|
|
||||||
// histogram.go provides a basic histogram metric, which can accumulate scalar
|
|
||||||
// event values or samples. The underlying histogram implementation is designed
|
|
||||||
// to be performant in that it accepts tolerable inaccuracies.
|
|
||||||
|
|
||||||
// histogram_test.go provides a test complement for the histogram.go module.
|
|
||||||
|
|
||||||
// metric.go provides fundamental interface expectations for the various
|
|
||||||
// metrics.
|
|
||||||
|
|
||||||
// metrics_test.go provides a test suite for all tests in the metrics package
|
|
||||||
// hierarchy. It employs the gocheck framework for test scaffolding.
|
|
||||||
|
|
||||||
// tallying_bucket.go provides a histogram bucket type that aggregates tallies
|
|
||||||
// of events that fall into its ranges versus a summary of the values
|
|
||||||
// themselves.
|
|
||||||
|
|
||||||
// tallying_bucket_test.go provides a test complement for the
|
|
||||||
// tallying_bucket.go module.
|
|
||||||
|
|
||||||
// timer.go provides a scalar metric that times how long a given event takes.
|
|
||||||
|
|
||||||
// timer_test.go provides a test complement for the timer.go module.
|
|
||||||
package metrics
|
|
|
@ -1,179 +0,0 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package metrics
|
|
||||||
|
|
||||||
import (
|
|
||||||
"container/heap"
|
|
||||||
. "github.com/matttproud/gocheck"
|
|
||||||
"github.com/prometheus/client_golang/maths"
|
|
||||||
"github.com/prometheus/client_golang/utility"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s *S) TestEvictOldest(c *C) {
|
|
||||||
q := make(utility.PriorityQueue, 0, 10)
|
|
||||||
heap.Init(&q)
|
|
||||||
var e EvictionPolicy = EvictOldest(5)
|
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
|
||||||
var item utility.Item = utility.Item{
|
|
||||||
Priority: int64(i),
|
|
||||||
Value: float64(i),
|
|
||||||
}
|
|
||||||
|
|
||||||
heap.Push(&q, &item)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Check(q, HasLen, 10)
|
|
||||||
|
|
||||||
e(&q)
|
|
||||||
|
|
||||||
c.Check(q, HasLen, 5)
|
|
||||||
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 4.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 3.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 2.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 1.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 0.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *S) TestEvictAndReplaceWithAverage(c *C) {
|
|
||||||
q := make(utility.PriorityQueue, 0, 10)
|
|
||||||
heap.Init(&q)
|
|
||||||
var e EvictionPolicy = EvictAndReplaceWith(5, maths.Average)
|
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
|
||||||
var item utility.Item = utility.Item{
|
|
||||||
Priority: int64(i),
|
|
||||||
Value: float64(i),
|
|
||||||
}
|
|
||||||
|
|
||||||
heap.Push(&q, &item)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Check(q, HasLen, 10)
|
|
||||||
|
|
||||||
e(&q)
|
|
||||||
|
|
||||||
c.Check(q, HasLen, 6)
|
|
||||||
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 4.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 3.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 2.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 1.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 0.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 7.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *S) TestEvictAndReplaceWithMedian(c *C) {
|
|
||||||
q := make(utility.PriorityQueue, 0, 10)
|
|
||||||
heap.Init(&q)
|
|
||||||
var e EvictionPolicy = EvictAndReplaceWith(5, maths.Median)
|
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
|
||||||
var item utility.Item = utility.Item{
|
|
||||||
Priority: int64(i),
|
|
||||||
Value: float64(i),
|
|
||||||
}
|
|
||||||
|
|
||||||
heap.Push(&q, &item)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Check(q, HasLen, 10)
|
|
||||||
|
|
||||||
e(&q)
|
|
||||||
|
|
||||||
c.Check(q, HasLen, 6)
|
|
||||||
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 4.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 3.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 2.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 1.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 0.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 7.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *S) TestEvictAndReplaceWithFirstMode(c *C) {
|
|
||||||
q := make(utility.PriorityQueue, 0, 10)
|
|
||||||
heap.Init(&q)
|
|
||||||
e := EvictAndReplaceWith(5, maths.FirstMode)
|
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
|
||||||
heap.Push(&q, &utility.Item{
|
|
||||||
Priority: int64(i),
|
|
||||||
Value: float64(i),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Check(q, HasLen, 10)
|
|
||||||
|
|
||||||
e(&q)
|
|
||||||
|
|
||||||
c.Check(q, HasLen, 6)
|
|
||||||
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 4.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 3.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 2.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 1.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 0.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 9.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *S) TestEvictAndReplaceWithMinimum(c *C) {
|
|
||||||
q := make(utility.PriorityQueue, 0, 10)
|
|
||||||
heap.Init(&q)
|
|
||||||
var e EvictionPolicy = EvictAndReplaceWith(5, maths.Minimum)
|
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
|
||||||
var item utility.Item = utility.Item{
|
|
||||||
Priority: int64(i),
|
|
||||||
Value: float64(i),
|
|
||||||
}
|
|
||||||
|
|
||||||
heap.Push(&q, &item)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Check(q, HasLen, 10)
|
|
||||||
|
|
||||||
e(&q)
|
|
||||||
|
|
||||||
c.Check(q, HasLen, 6)
|
|
||||||
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 4.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 3.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 2.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 1.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 0.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 5.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *S) TestEvictAndReplaceWithMaximum(c *C) {
|
|
||||||
q := make(utility.PriorityQueue, 0, 10)
|
|
||||||
heap.Init(&q)
|
|
||||||
var e EvictionPolicy = EvictAndReplaceWith(5, maths.Maximum)
|
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
|
||||||
var item utility.Item = utility.Item{
|
|
||||||
Priority: int64(i),
|
|
||||||
Value: float64(i),
|
|
||||||
}
|
|
||||||
|
|
||||||
heap.Push(&q, &item)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Check(q, HasLen, 10)
|
|
||||||
|
|
||||||
e(&q)
|
|
||||||
|
|
||||||
c.Check(q, HasLen, 6)
|
|
||||||
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 4.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 3.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 2.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 1.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 0.0)
|
|
||||||
c.Check(heap.Pop(&q), utility.ValueEquals, 9.0)
|
|
||||||
}
|
|
|
@ -0,0 +1 @@
|
||||||
|
command-line-arguments.test
|
|
@ -0,0 +1,25 @@
|
||||||
|
# Copyright 2013 Prometheus Team
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
all: test
|
||||||
|
|
||||||
|
build:
|
||||||
|
go build ./...
|
||||||
|
|
||||||
|
test: build
|
||||||
|
go test ./... $(GO_TEST_FLAGS)
|
||||||
|
|
||||||
|
advice:
|
||||||
|
go tool vet .
|
||||||
|
|
||||||
|
.PHONY: advice build test
|
|
@ -1,16 +1,15 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package metrics
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"container/heap"
|
"container/heap"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/prometheus/client_golang/utility"
|
|
||||||
"math"
|
"math"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -18,7 +17,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type AccumulatingBucket struct {
|
type AccumulatingBucket struct {
|
||||||
elements utility.PriorityQueue
|
elements priorityQueue
|
||||||
evictionPolicy EvictionPolicy
|
evictionPolicy EvictionPolicy
|
||||||
maximumSize int
|
maximumSize int
|
||||||
mutex sync.RWMutex
|
mutex sync.RWMutex
|
||||||
|
@ -31,7 +30,7 @@ type AccumulatingBucket struct {
|
||||||
func AccumulatingBucketBuilder(evictionPolicy EvictionPolicy, maximumSize int) BucketBuilder {
|
func AccumulatingBucketBuilder(evictionPolicy EvictionPolicy, maximumSize int) BucketBuilder {
|
||||||
return func() Bucket {
|
return func() Bucket {
|
||||||
return &AccumulatingBucket{
|
return &AccumulatingBucket{
|
||||||
elements: make(utility.PriorityQueue, 0, maximumSize),
|
elements: make(priorityQueue, 0, maximumSize),
|
||||||
evictionPolicy: evictionPolicy,
|
evictionPolicy: evictionPolicy,
|
||||||
maximumSize: maximumSize,
|
maximumSize: maximumSize,
|
||||||
}
|
}
|
||||||
|
@ -47,7 +46,7 @@ func (b *AccumulatingBucket) Add(value float64) {
|
||||||
b.observations++
|
b.observations++
|
||||||
size := len(b.elements)
|
size := len(b.elements)
|
||||||
|
|
||||||
v := utility.Item{
|
v := item{
|
||||||
Priority: -1 * time.Now().UnixNano(),
|
Priority: -1 * time.Now().UnixNano(),
|
||||||
Value: value,
|
Value: value,
|
||||||
}
|
}
|
|
@ -1,15 +1,13 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package metrics
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
. "github.com/matttproud/gocheck"
|
. "github.com/matttproud/gocheck"
|
||||||
"github.com/prometheus/client_golang/maths"
|
|
||||||
"github.com/prometheus/client_golang/utility"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -51,7 +49,7 @@ func (s *S) TestAccumulatingBucketBuilderWithEvictOldest(c *C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *S) TestAccumulatingBucketBuilderWithEvictAndReplaceWithAverage(c *C) {
|
func (s *S) TestAccumulatingBucketBuilderWithEvictAndReplaceWithAverage(c *C) {
|
||||||
var evictAndReplaceWithAverage EvictionPolicy = EvictAndReplaceWith(3, maths.Average)
|
var evictAndReplaceWithAverage EvictionPolicy = EvictAndReplaceWith(3, AverageReducer)
|
||||||
|
|
||||||
c.Assert(evictAndReplaceWithAverage, Not(IsNil))
|
c.Assert(evictAndReplaceWithAverage, Not(IsNil))
|
||||||
|
|
||||||
|
@ -86,7 +84,7 @@ func (s *S) TestAccumulatingBucketBuilderWithEvictAndReplaceWithAverage(c *C) {
|
||||||
|
|
||||||
func (s *S) TestAccumulatingBucket(c *C) {
|
func (s *S) TestAccumulatingBucket(c *C) {
|
||||||
var b AccumulatingBucket = AccumulatingBucket{
|
var b AccumulatingBucket = AccumulatingBucket{
|
||||||
elements: make(utility.PriorityQueue, 0, 10),
|
elements: make(priorityQueue, 0, 10),
|
||||||
maximumSize: 5,
|
maximumSize: 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,13 +110,13 @@ func (s *S) TestAccumulatingBucket(c *C) {
|
||||||
|
|
||||||
func (s *S) TestAccumulatingBucketValueForIndex(c *C) {
|
func (s *S) TestAccumulatingBucketValueForIndex(c *C) {
|
||||||
var b AccumulatingBucket = AccumulatingBucket{
|
var b AccumulatingBucket = AccumulatingBucket{
|
||||||
elements: make(utility.PriorityQueue, 0, 100),
|
elements: make(priorityQueue, 0, 100),
|
||||||
maximumSize: 100,
|
maximumSize: 100,
|
||||||
evictionPolicy: EvictOldest(50),
|
evictionPolicy: EvictOldest(50),
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i <= 100; i++ {
|
for i := 0; i <= 100; i++ {
|
||||||
c.Assert(b.ValueForIndex(i), maths.IsNaN)
|
c.Assert(b.ValueForIndex(i), IsNaN)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The bucket has only observed one item and contains now one item.
|
// The bucket has only observed one item and contains now one item.
|
|
@ -1,12 +1,10 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// bucket.go provides fundamental interface expectations for various bucket
|
package prometheus
|
||||||
// types.
|
|
||||||
package metrics
|
|
||||||
|
|
||||||
// The Histogram class and associated types build buckets on their own.
|
// The Histogram class and associated types build buckets on their own.
|
||||||
type BucketBuilder func() Bucket
|
type BucketBuilder func() Bucket
|
|
@ -1,10 +1,10 @@
|
||||||
// Copyright (c) 2013, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style license that can be found
|
// Use of this source code is governed by a BSD-style license that can be found
|
||||||
// in the LICENSE file.
|
// in the LICENSE file.
|
||||||
|
|
||||||
package registry
|
package prometheus
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// NilLabels is a nil set of labels merely for end-user convenience.
|
// NilLabels is a nil set of labels merely for end-user convenience.
|
||||||
|
@ -14,8 +14,7 @@ var (
|
||||||
// interface.
|
// interface.
|
||||||
DefaultHandler = DefaultRegistry.Handler()
|
DefaultHandler = DefaultRegistry.Handler()
|
||||||
|
|
||||||
// This is the default registry with which Metric objects are associated. It
|
// This is the default registry with which Metric objects are associated.
|
||||||
// is primarily a read-only object after server instantiation.
|
|
||||||
DefaultRegistry = NewRegistry()
|
DefaultRegistry = NewRegistry()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -39,4 +38,14 @@ const (
|
||||||
docstringKey = "docstring"
|
docstringKey = "docstring"
|
||||||
metricKey = "metric"
|
metricKey = "metric"
|
||||||
nameLabel = "name"
|
nameLabel = "name"
|
||||||
|
|
||||||
|
counterTypeValue = "counter"
|
||||||
|
floatBitCount = 64
|
||||||
|
floatFormat = 'f'
|
||||||
|
floatPrecision = 6
|
||||||
|
gaugeTypeValue = "gauge"
|
||||||
|
histogramTypeValue = "histogram"
|
||||||
|
typeKey = "type"
|
||||||
|
valueKey = "value"
|
||||||
|
labelsKey = "labels"
|
||||||
)
|
)
|
|
@ -1,14 +1,13 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package metrics
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/prometheus/client_golang/utility"
|
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -49,7 +48,7 @@ func (metric *counter) Set(labels map[string]string, value float64) float64 {
|
||||||
labels = map[string]string{}
|
labels = map[string]string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
signature := utility.LabelsToSignature(labels)
|
signature := labelsToSignature(labels)
|
||||||
if original, ok := metric.values[signature]; ok {
|
if original, ok := metric.values[signature]; ok {
|
||||||
original.value = value
|
original.value = value
|
||||||
} else {
|
} else {
|
||||||
|
@ -91,7 +90,7 @@ func (metric *counter) IncrementBy(labels map[string]string, value float64) floa
|
||||||
labels = map[string]string{}
|
labels = map[string]string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
signature := utility.LabelsToSignature(labels)
|
signature := labelsToSignature(labels)
|
||||||
if original, ok := metric.values[signature]; ok {
|
if original, ok := metric.values[signature]; ok {
|
||||||
original.value += value
|
original.value += value
|
||||||
} else {
|
} else {
|
||||||
|
@ -116,7 +115,7 @@ func (metric *counter) DecrementBy(labels map[string]string, value float64) floa
|
||||||
labels = map[string]string{}
|
labels = map[string]string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
signature := utility.LabelsToSignature(labels)
|
signature := labelsToSignature(labels)
|
||||||
if original, ok := metric.values[signature]; ok {
|
if original, ok := metric.values[signature]; ok {
|
||||||
original.value -= value
|
original.value -= value
|
||||||
} else {
|
} else {
|
|
@ -1,18 +1,17 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package metrics
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/prometheus/client_golang/utility/test"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testCounter(t test.Tester) {
|
func testCounter(t tester) {
|
||||||
type input struct {
|
type input struct {
|
||||||
steps []func(g Counter)
|
steps []func(g Counter)
|
||||||
}
|
}
|
|
@ -1,17 +1,17 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package maths
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Go's standard library does not offer a factorial function.
|
// Go's standard library does not offer a factorial function.
|
||||||
func Factorial(of int) int64 {
|
func factorial(of int) int64 {
|
||||||
if of <= 0 {
|
if of <= 0 {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,8 @@ func Factorial(of int) int64 {
|
||||||
// Calculate the value of a probability density for a given binomial statistic,
|
// Calculate the value of a probability density for a given binomial statistic,
|
||||||
// where k is the target count of true cases, n is the number of subjects, and
|
// where k is the target count of true cases, n is the number of subjects, and
|
||||||
// p is the probability.
|
// p is the probability.
|
||||||
func BinomialPDF(k, n int, p float64) float64 {
|
func binomialPDF(k, n int, p float64) float64 {
|
||||||
binomialCoefficient := float64(Factorial(n)) / float64(Factorial(k)*Factorial(n-k))
|
binomialCoefficient := float64(factorial(n)) / float64(factorial(k)*factorial(n-k))
|
||||||
intermediate := math.Pow(p, float64(k)) * math.Pow(1-p, float64(n-k))
|
intermediate := math.Pow(p, float64(k)) * math.Pow(1-p, float64(n-k))
|
||||||
|
|
||||||
return binomialCoefficient * intermediate
|
return binomialCoefficient * intermediate
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright (c) 2013, Prometheus Team
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be found
|
||||||
|
// in the LICENSE file.
|
||||||
|
|
||||||
|
// Prometheus' client side metric primitives and telemetry exposition framework.
|
||||||
|
//
|
||||||
|
// This package provides both metric primitives and tools for their exposition
|
||||||
|
// to the Prometheus time series collection and computation framework.
|
||||||
|
//
|
||||||
|
// prometheus.Register("human_readable_metric_name", "metric docstring", map[string]string{"baseLabel": "baseLabelValue"}, metric)
|
||||||
|
//
|
||||||
|
// The examples under github.com/prometheus/client_golang/examples should be
|
||||||
|
// consulted.
|
||||||
|
package prometheus
|
|
@ -1,15 +1,13 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package metrics
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"container/heap"
|
"container/heap"
|
||||||
"github.com/prometheus/client_golang/maths"
|
|
||||||
"github.com/prometheus/client_golang/utility"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -29,17 +27,17 @@ func EvictOldest(count int) EvictionPolicy {
|
||||||
|
|
||||||
// This factory produces an EvictionPolicy that applies some standardized
|
// This factory produces an EvictionPolicy that applies some standardized
|
||||||
// reduction methodology on the to-be-terminated values.
|
// reduction methodology on the to-be-terminated values.
|
||||||
func EvictAndReplaceWith(count int, reducer maths.ReductionMethod) EvictionPolicy {
|
func EvictAndReplaceWith(count int, reducer ReductionMethod) EvictionPolicy {
|
||||||
return func(h heap.Interface) {
|
return func(h heap.Interface) {
|
||||||
oldValues := make([]float64, count)
|
oldValues := make([]float64, count)
|
||||||
|
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
oldValues[i] = heap.Pop(h).(*utility.Item).Value.(float64)
|
oldValues[i] = heap.Pop(h).(*item).Value.(float64)
|
||||||
}
|
}
|
||||||
|
|
||||||
reduced := reducer(oldValues)
|
reduced := reducer(oldValues)
|
||||||
|
|
||||||
heap.Push(h, &utility.Item{
|
heap.Push(h, &item{
|
||||||
Value: reduced,
|
Value: reduced,
|
||||||
// TODO(mtp): Parameterize the priority generation since these tools are
|
// TODO(mtp): Parameterize the priority generation since these tools are
|
||||||
// useful.
|
// useful.
|
|
@ -0,0 +1,177 @@
|
||||||
|
// Copyright (c) 2013, Prometheus Team
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package prometheus
|
||||||
|
|
||||||
|
import (
|
||||||
|
"container/heap"
|
||||||
|
. "github.com/matttproud/gocheck"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *S) TestEvictOldest(c *C) {
|
||||||
|
q := make(priorityQueue, 0, 10)
|
||||||
|
heap.Init(&q)
|
||||||
|
var e EvictionPolicy = EvictOldest(5)
|
||||||
|
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
var item item = item{
|
||||||
|
Priority: int64(i),
|
||||||
|
Value: float64(i),
|
||||||
|
}
|
||||||
|
|
||||||
|
heap.Push(&q, &item)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Check(q, HasLen, 10)
|
||||||
|
|
||||||
|
e(&q)
|
||||||
|
|
||||||
|
c.Check(q, HasLen, 5)
|
||||||
|
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 4.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 3.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 2.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 1.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *S) TestEvictAndReplaceWithAverage(c *C) {
|
||||||
|
q := make(priorityQueue, 0, 10)
|
||||||
|
heap.Init(&q)
|
||||||
|
var e EvictionPolicy = EvictAndReplaceWith(5, AverageReducer)
|
||||||
|
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
var item item = item{
|
||||||
|
Priority: int64(i),
|
||||||
|
Value: float64(i),
|
||||||
|
}
|
||||||
|
|
||||||
|
heap.Push(&q, &item)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Check(q, HasLen, 10)
|
||||||
|
|
||||||
|
e(&q)
|
||||||
|
|
||||||
|
c.Check(q, HasLen, 6)
|
||||||
|
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 4.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 3.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 2.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 1.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 0.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 7.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *S) TestEvictAndReplaceWithMedian(c *C) {
|
||||||
|
q := make(priorityQueue, 0, 10)
|
||||||
|
heap.Init(&q)
|
||||||
|
var e EvictionPolicy = EvictAndReplaceWith(5, MedianReducer)
|
||||||
|
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
var item item = item{
|
||||||
|
Priority: int64(i),
|
||||||
|
Value: float64(i),
|
||||||
|
}
|
||||||
|
|
||||||
|
heap.Push(&q, &item)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Check(q, HasLen, 10)
|
||||||
|
|
||||||
|
e(&q)
|
||||||
|
|
||||||
|
c.Check(q, HasLen, 6)
|
||||||
|
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 4.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 3.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 2.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 1.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 0.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 7.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *S) TestEvictAndReplaceWithFirstMode(c *C) {
|
||||||
|
q := make(priorityQueue, 0, 10)
|
||||||
|
heap.Init(&q)
|
||||||
|
e := EvictAndReplaceWith(5, FirstModeReducer)
|
||||||
|
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
heap.Push(&q, &item{
|
||||||
|
Priority: int64(i),
|
||||||
|
Value: float64(i),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Check(q, HasLen, 10)
|
||||||
|
|
||||||
|
e(&q)
|
||||||
|
|
||||||
|
c.Check(q, HasLen, 6)
|
||||||
|
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 4.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 3.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 2.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 1.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 0.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 9.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *S) TestEvictAndReplaceWithMinimum(c *C) {
|
||||||
|
q := make(priorityQueue, 0, 10)
|
||||||
|
heap.Init(&q)
|
||||||
|
var e EvictionPolicy = EvictAndReplaceWith(5, MinimumReducer)
|
||||||
|
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
var item item = item{
|
||||||
|
Priority: int64(i),
|
||||||
|
Value: float64(i),
|
||||||
|
}
|
||||||
|
|
||||||
|
heap.Push(&q, &item)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Check(q, HasLen, 10)
|
||||||
|
|
||||||
|
e(&q)
|
||||||
|
|
||||||
|
c.Check(q, HasLen, 6)
|
||||||
|
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 4.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 3.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 2.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 1.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 0.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 5.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *S) TestEvictAndReplaceWithMaximum(c *C) {
|
||||||
|
q := make(priorityQueue, 0, 10)
|
||||||
|
heap.Init(&q)
|
||||||
|
var e EvictionPolicy = EvictAndReplaceWith(5, MaximumReducer)
|
||||||
|
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
var item item = item{
|
||||||
|
Priority: int64(i),
|
||||||
|
Value: float64(i),
|
||||||
|
}
|
||||||
|
|
||||||
|
heap.Push(&q, &item)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Check(q, HasLen, 10)
|
||||||
|
|
||||||
|
e(&q)
|
||||||
|
|
||||||
|
c.Check(q, HasLen, 6)
|
||||||
|
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 4.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 3.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 2.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 1.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 0.0)
|
||||||
|
c.Check(heap.Pop(&q), ValueEquals, 9.0)
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style license that can be found in
|
// Use of this source code is governed by a BSD-style license that can be found in
|
||||||
|
@ -8,8 +8,7 @@ package exp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/prometheus/client_golang"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/metrics"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -33,11 +32,11 @@ type (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
requestCounts = metrics.NewCounter()
|
requestCounts = prometheus.NewCounter()
|
||||||
requestDuration = metrics.NewCounter()
|
requestDuration = prometheus.NewCounter()
|
||||||
requestDurations = metrics.NewDefaultHistogram()
|
requestDurations = prometheus.NewDefaultHistogram()
|
||||||
requestBytes = metrics.NewCounter()
|
requestBytes = prometheus.NewCounter()
|
||||||
responseBytes = metrics.NewCounter()
|
responseBytes = prometheus.NewCounter()
|
||||||
|
|
||||||
// DefaultCoarseMux is a drop-in replacement for http.DefaultServeMux that
|
// DefaultCoarseMux is a drop-in replacement for http.DefaultServeMux that
|
||||||
// provides standardized telemetry for Go's standard HTTP handler registration
|
// provides standardized telemetry for Go's standard HTTP handler registration
|
||||||
|
@ -103,9 +102,9 @@ func HandleFunc(pattern string, handler http.HandlerFunc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
registry.Register("http_requests_total", "A counter of the total number of HTTP requests made against the default multiplexor.", registry.NilLabels, requestCounts)
|
prometheus.Register("http_requests_total", "A counter of the total number of HTTP requests made against the default multiplexor.", prometheus.NilLabels, requestCounts)
|
||||||
registry.Register("http_request_durations_total_microseconds", "The total amount of time the default multiplexor has spent answering HTTP requests (microseconds).", registry.NilLabels, requestDuration)
|
prometheus.Register("http_request_durations_total_microseconds", "The total amount of time the default multiplexor has spent answering HTTP requests (microseconds).", prometheus.NilLabels, requestDuration)
|
||||||
registry.Register("http_request_durations_microseconds", "The amounts of time the default multiplexor has spent answering HTTP requests (microseconds).", registry.NilLabels, requestDurations)
|
prometheus.Register("http_request_durations_microseconds", "The amounts of time the default multiplexor has spent answering HTTP requests (microseconds).", prometheus.NilLabels, requestDurations)
|
||||||
registry.Register("http_request_bytes_total", "The total volume of content body sizes received (bytes).", registry.NilLabels, requestBytes)
|
prometheus.Register("http_request_bytes_total", "The total volume of content body sizes received (bytes).", prometheus.NilLabels, requestBytes)
|
||||||
registry.Register("http_response_bytes_total", "The total volume of response payloads emitted (bytes).", registry.NilLabels, responseBytes)
|
prometheus.Register("http_response_bytes_total", "The total volume of response payloads emitted (bytes).", prometheus.NilLabels, responseBytes)
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style license that can be found in
|
// Use of this source code is governed by a BSD-style license that can be found in
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style license that can be found in
|
// Use of this source code is governed by a BSD-style license that can be found in
|
|
@ -1,14 +1,13 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package metrics
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/prometheus/client_golang/utility"
|
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -56,7 +55,7 @@ func (metric *gauge) Set(labels map[string]string, value float64) float64 {
|
||||||
labels = map[string]string{}
|
labels = map[string]string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
signature := utility.LabelsToSignature(labels)
|
signature := labelsToSignature(labels)
|
||||||
|
|
||||||
if original, ok := metric.values[signature]; ok {
|
if original, ok := metric.values[signature]; ok {
|
||||||
original.value = value
|
original.value = value
|
|
@ -1,18 +1,17 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package metrics
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/prometheus/client_golang/utility/test"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testGauge(t test.Tester) {
|
func testGauge(t tester) {
|
||||||
type input struct {
|
type input struct {
|
||||||
steps []func(g Gauge)
|
steps []func(g Gauge)
|
||||||
}
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package maths
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
. "github.com/matttproud/gocheck"
|
. "github.com/matttproud/gocheck"
|
|
@ -1,16 +1,14 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package metrics
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/prometheus/client_golang/maths"
|
|
||||||
"github.com/prometheus/client_golang/utility"
|
|
||||||
"math"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -96,7 +94,7 @@ func (h *histogram) Add(labels map[string]string, value float64) {
|
||||||
labels = map[string]string{}
|
labels = map[string]string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
signature := utility.LabelsToSignature(labels)
|
signature := labelsToSignature(labels)
|
||||||
var histogram *histogramVector = nil
|
var histogram *histogramVector = nil
|
||||||
if original, ok := h.values[signature]; ok {
|
if original, ok := h.values[signature]; ok {
|
||||||
histogram = original
|
histogram = original
|
||||||
|
@ -298,7 +296,7 @@ func NewDefaultHistogram() Histogram {
|
||||||
return NewHistogram(
|
return NewHistogram(
|
||||||
&HistogramSpecification{
|
&HistogramSpecification{
|
||||||
Starts: LogarithmicSizedBucketsFor(0, 4096),
|
Starts: LogarithmicSizedBucketsFor(0, 4096),
|
||||||
BucketBuilder: AccumulatingBucketBuilder(EvictAndReplaceWith(10, maths.Average), 50),
|
BucketBuilder: AccumulatingBucketBuilder(EvictAndReplaceWith(10, AverageReducer), 50),
|
||||||
ReportablePercentiles: []float64{0.01, 0.05, 0.5, 0.90, 0.99},
|
ReportablePercentiles: []float64{0.01, 0.05, 0.5, 0.90, 0.99},
|
||||||
},
|
},
|
||||||
)
|
)
|
|
@ -1,9 +1,9 @@
|
||||||
// Copyright (c) 2013, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package metrics
|
package prometheus
|
||||||
|
|
||||||
// TODO(matt): Re-Add tests for this type.
|
// TODO(matt): Re-Add tests for this type.
|
|
@ -1,12 +1,12 @@
|
||||||
// Copyright (c) 2013, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package test
|
package prometheus
|
||||||
|
|
||||||
type Tester interface {
|
type tester interface {
|
||||||
Error(args ...interface{})
|
Error(args ...interface{})
|
||||||
Errorf(format string, args ...interface{})
|
Errorf(format string, args ...interface{})
|
||||||
Fatal(args ...interface{})
|
Fatal(args ...interface{})
|
|
@ -1,10 +1,10 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package metrics
|
package prometheus
|
||||||
|
|
||||||
// A Metric is something that can be exposed via the registry framework.
|
// A Metric is something that can be exposed via the registry framework.
|
||||||
type Metric interface {
|
type Metric interface {
|
|
@ -1,44 +1,44 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
|
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package utility
|
package prometheus
|
||||||
|
|
||||||
type Item struct {
|
type item struct {
|
||||||
Priority int64
|
Priority int64
|
||||||
Value interface{}
|
Value interface{}
|
||||||
index int
|
index int
|
||||||
}
|
}
|
||||||
|
|
||||||
type PriorityQueue []*Item
|
type priorityQueue []*item
|
||||||
|
|
||||||
func (q PriorityQueue) Len() int {
|
func (q priorityQueue) Len() int {
|
||||||
return len(q)
|
return len(q)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q PriorityQueue) Less(i, j int) bool {
|
func (q priorityQueue) Less(i, j int) bool {
|
||||||
return q[i].Priority > q[j].Priority
|
return q[i].Priority > q[j].Priority
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q PriorityQueue) Swap(i, j int) {
|
func (q priorityQueue) Swap(i, j int) {
|
||||||
q[i], q[j] = q[j], q[i]
|
q[i], q[j] = q[j], q[i]
|
||||||
q[i].index = i
|
q[i].index = i
|
||||||
q[j].index = j
|
q[j].index = j
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *PriorityQueue) Push(x interface{}) {
|
func (q *priorityQueue) Push(x interface{}) {
|
||||||
queue := *q
|
queue := *q
|
||||||
size := len(queue)
|
size := len(queue)
|
||||||
queue = queue[0 : size+1]
|
queue = queue[0 : size+1]
|
||||||
item := x.(*Item)
|
item := x.(*item)
|
||||||
item.index = size
|
item.index = size
|
||||||
queue[size] = item
|
queue[size] = item
|
||||||
*q = queue
|
*q = queue
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *PriorityQueue) Pop() interface{} {
|
func (q *priorityQueue) Pop() interface{} {
|
||||||
queue := *q
|
queue := *q
|
||||||
size := len(queue)
|
size := len(queue)
|
||||||
item := queue[size-1]
|
item := queue[size-1]
|
|
@ -1,10 +1,10 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package utility
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"container/heap"
|
"container/heap"
|
||||||
|
@ -12,16 +12,16 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *S) TestPriorityQueueSort(c *C) {
|
func (s *S) TestPriorityQueueSort(c *C) {
|
||||||
q := make(PriorityQueue, 0, 6)
|
q := make(priorityQueue, 0, 6)
|
||||||
|
|
||||||
c.Check(len(q), Equals, 0)
|
c.Check(len(q), Equals, 0)
|
||||||
|
|
||||||
heap.Push(&q, &Item{Value: "newest", Priority: -100})
|
heap.Push(&q, &item{Value: "newest", Priority: -100})
|
||||||
heap.Push(&q, &Item{Value: "older", Priority: 90})
|
heap.Push(&q, &item{Value: "older", Priority: 90})
|
||||||
heap.Push(&q, &Item{Value: "oldest", Priority: 100})
|
heap.Push(&q, &item{Value: "oldest", Priority: 100})
|
||||||
heap.Push(&q, &Item{Value: "newer", Priority: -90})
|
heap.Push(&q, &item{Value: "newer", Priority: -90})
|
||||||
heap.Push(&q, &Item{Value: "new", Priority: -80})
|
heap.Push(&q, &item{Value: "new", Priority: -80})
|
||||||
heap.Push(&q, &Item{Value: "old", Priority: 80})
|
heap.Push(&q, &item{Value: "old", Priority: 80})
|
||||||
|
|
||||||
c.Check(len(q), Equals, 6)
|
c.Check(len(q), Equals, 6)
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package metrics
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
. "github.com/matttproud/gocheck"
|
. "github.com/matttproud/gocheck"
|
||||||
|
@ -15,6 +15,6 @@ type S struct{}
|
||||||
|
|
||||||
var _ = Suite(&S{})
|
var _ = Suite(&S{})
|
||||||
|
|
||||||
func TestMetrics(t *testing.T) {
|
func TestPrometheus(t *testing.T) {
|
||||||
TestingT(t)
|
TestingT(t)
|
||||||
}
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style license that can be found
|
// Use of this source code is governed by a BSD-style license that can be found
|
||||||
// in the LICENSE file.
|
// in the LICENSE file.
|
||||||
|
|
||||||
package registry
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
|
@ -12,8 +12,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/prometheus/client_golang/metrics"
|
|
||||||
"github.com/prometheus/client_golang/utility"
|
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -46,7 +44,7 @@ var (
|
||||||
type container struct {
|
type container struct {
|
||||||
baseLabels map[string]string
|
baseLabels map[string]string
|
||||||
docstring string
|
docstring string
|
||||||
metric metrics.Metric
|
metric Metric
|
||||||
name string
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +59,7 @@ type registry struct {
|
||||||
// own.
|
// own.
|
||||||
type Registry interface {
|
type Registry interface {
|
||||||
// Register a metric with a given name. Name should be globally unique.
|
// Register a metric with a given name. Name should be globally unique.
|
||||||
Register(name, docstring string, baseLabels map[string]string, metric metrics.Metric) error
|
Register(name, docstring string, baseLabels map[string]string, metric Metric) error
|
||||||
// Create a http.HandlerFunc that is tied to a Registry such that requests
|
// Create a http.HandlerFunc that is tied to a Registry such that requests
|
||||||
// against it generate a representation of the housed metrics.
|
// against it generate a representation of the housed metrics.
|
||||||
Handler() http.HandlerFunc
|
Handler() http.HandlerFunc
|
||||||
|
@ -79,7 +77,7 @@ func NewRegistry() Registry {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Associate a Metric with the DefaultRegistry.
|
// Associate a Metric with the DefaultRegistry.
|
||||||
func Register(name, docstring string, baseLabels map[string]string, metric metrics.Metric) error {
|
func Register(name, docstring string, baseLabels map[string]string, metric Metric) error {
|
||||||
return DefaultRegistry.Register(name, docstring, baseLabels, metric)
|
return DefaultRegistry.Register(name, docstring, baseLabels, metric)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +108,7 @@ func (r registry) isValidCandidate(name string, baseLabels map[string]string) (s
|
||||||
}
|
}
|
||||||
|
|
||||||
baseLabels[nameLabel] = name
|
baseLabels[nameLabel] = name
|
||||||
signature = utility.LabelsToSignature(baseLabels)
|
signature = labelsToSignature(baseLabels)
|
||||||
|
|
||||||
if _, contains := r.signatureContainers[signature]; contains {
|
if _, contains := r.signatureContainers[signature]; contains {
|
||||||
err = fmt.Errorf("metric named %s with baseLabels %s is already registered", name, baseLabels)
|
err = fmt.Errorf("metric named %s with baseLabels %s is already registered", name, baseLabels)
|
||||||
|
@ -141,7 +139,7 @@ func (r registry) isValidCandidate(name string, baseLabels map[string]string) (s
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r registry) Register(name, docstring string, baseLabels map[string]string, metric metrics.Metric) (err error) {
|
func (r registry) Register(name, docstring string, baseLabels map[string]string, metric Metric) (err error) {
|
||||||
r.mutex.Lock()
|
r.mutex.Lock()
|
||||||
defer r.mutex.Unlock()
|
defer r.mutex.Unlock()
|
||||||
|
|
||||||
|
@ -271,7 +269,7 @@ func (registry registry) YieldExporter() http.HandlerFunc {
|
||||||
|
|
||||||
func (registry registry) Handler() http.HandlerFunc {
|
func (registry registry) Handler() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
var instrumentable metrics.InstrumentableCall = func() {
|
var instrumentable InstrumentableCall = func() {
|
||||||
requestCount.Increment(nil)
|
requestCount.Increment(nil)
|
||||||
url := r.URL
|
url := r.URL
|
||||||
|
|
||||||
|
@ -293,7 +291,7 @@ func (registry registry) Handler() http.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
metrics.InstrumentCall(instrumentable, requestLatencyAccumulator)
|
InstrumentCall(instrumentable, requestLatencyAccumulator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,20 @@
|
||||||
// Copyright (c) 2013, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style license that can be found
|
// Use of this source code is governed by a BSD-style license that can be found
|
||||||
// in the LICENSE file.
|
// in the LICENSE file.
|
||||||
|
|
||||||
package registry
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/prometheus/client_golang/metrics"
|
|
||||||
"github.com/prometheus/client_golang/utility/test"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testRegister(t test.Tester) {
|
func testRegister(t tester) {
|
||||||
var oldState = struct {
|
var oldState = struct {
|
||||||
abortOnMisuse bool
|
abortOnMisuse bool
|
||||||
debugRegistration bool
|
debugRegistration bool
|
||||||
|
@ -181,7 +179,7 @@ func (r *fakeResponseWriter) Write(d []byte) (l int, err error) {
|
||||||
func (r *fakeResponseWriter) WriteHeader(c int) {
|
func (r *fakeResponseWriter) WriteHeader(c int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDecorateWriter(t test.Tester) {
|
func testDecorateWriter(t tester) {
|
||||||
type input struct {
|
type input struct {
|
||||||
headers map[string]string
|
headers map[string]string
|
||||||
body []byte
|
body []byte
|
||||||
|
@ -266,9 +264,9 @@ func BenchmarkDecorateWriter(b *testing.B) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDumpToWriter(t test.Tester) {
|
func testDumpToWriter(t tester) {
|
||||||
type input struct {
|
type input struct {
|
||||||
metrics map[string]metrics.Metric
|
metrics map[string]Metric
|
||||||
}
|
}
|
||||||
|
|
||||||
var scenarios = []struct {
|
var scenarios = []struct {
|
||||||
|
@ -280,17 +278,17 @@ func testDumpToWriter(t test.Tester) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
in: input{
|
in: input{
|
||||||
metrics: map[string]metrics.Metric{
|
metrics: map[string]Metric{
|
||||||
"foo": metrics.NewCounter(),
|
"foo": NewCounter(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
out: []byte("[{\"baseLabels\":{\"label_foo\":\"foo\",\"name\":\"foo\"},\"docstring\":\"metric foo\",\"metric\":{\"type\":\"counter\",\"value\":[]}}]"),
|
out: []byte("[{\"baseLabels\":{\"label_foo\":\"foo\",\"name\":\"foo\"},\"docstring\":\"metric foo\",\"metric\":{\"type\":\"counter\",\"value\":[]}}]"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
in: input{
|
in: input{
|
||||||
metrics: map[string]metrics.Metric{
|
metrics: map[string]Metric{
|
||||||
"foo": metrics.NewCounter(),
|
"foo": NewCounter(),
|
||||||
"bar": metrics.NewCounter(),
|
"bar": NewCounter(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
out: []byte("[{\"baseLabels\":{\"label_bar\":\"bar\",\"name\":\"bar\"},\"docstring\":\"metric bar\",\"metric\":{\"type\":\"counter\",\"value\":[]}},{\"baseLabels\":{\"label_foo\":\"foo\",\"name\":\"foo\"},\"docstring\":\"metric foo\",\"metric\":{\"type\":\"counter\",\"value\":[]}}]"),
|
out: []byte("[{\"baseLabels\":{\"label_bar\":\"bar\",\"name\":\"bar\"},\"docstring\":\"metric bar\",\"metric\":{\"type\":\"counter\",\"value\":[]}},{\"baseLabels\":{\"label_foo\":\"foo\",\"name\":\"foo\"},\"docstring\":\"metric foo\",\"metric\":{\"type\":\"counter\",\"value\":[]}}]"),
|
|
@ -1,10 +1,10 @@
|
||||||
// Copyright (c) 2013, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package utility
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -17,7 +17,7 @@ const (
|
||||||
|
|
||||||
// LabelsToSignature provides a way of building a unique signature
|
// LabelsToSignature provides a way of building a unique signature
|
||||||
// (i.e., fingerprint) for a given label set sequence.
|
// (i.e., fingerprint) for a given label set sequence.
|
||||||
func LabelsToSignature(labels map[string]string) string {
|
func labelsToSignature(labels map[string]string) string {
|
||||||
// TODO(matt): This is a wart, and we'll want to validate that collisions
|
// TODO(matt): This is a wart, and we'll want to validate that collisions
|
||||||
// do not occur in less-than-diligent environments.
|
// do not occur in less-than-diligent environments.
|
||||||
cardinality := len(labels)
|
cardinality := len(labels)
|
|
@ -1,17 +1,16 @@
|
||||||
// Copyright (c) 2013, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package utility
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/prometheus/client_golang/utility/test"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testLabelsToSignature(t test.Tester) {
|
func testLabelsToSignature(t tester) {
|
||||||
var scenarios = []struct {
|
var scenarios = []struct {
|
||||||
in map[string]string
|
in map[string]string
|
||||||
out string
|
out string
|
||||||
|
@ -24,7 +23,7 @@ func testLabelsToSignature(t test.Tester) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, scenario := range scenarios {
|
for i, scenario := range scenarios {
|
||||||
actual := LabelsToSignature(scenario.in)
|
actual := labelsToSignature(scenario.in)
|
||||||
|
|
||||||
if actual != scenario.out {
|
if actual != scenario.out {
|
||||||
t.Errorf("%d. expected %s, got %s", i, scenario.out, actual)
|
t.Errorf("%d. expected %s, got %s", i, scenario.out, actual)
|
|
@ -1,10 +1,10 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package maths
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
@ -14,11 +14,32 @@ import (
|
||||||
// TODO(mtp): Split this out into a summary statistics file once moving/rolling
|
// TODO(mtp): Split this out into a summary statistics file once moving/rolling
|
||||||
// averages are calculated.
|
// averages are calculated.
|
||||||
|
|
||||||
// ReductionMethod provides a method for reducing metrics into a given scalar
|
// ReductionMethod provides a method for reducing metrics into a scalar value.
|
||||||
// value.
|
|
||||||
type ReductionMethod func([]float64) float64
|
type ReductionMethod func([]float64) float64
|
||||||
|
|
||||||
var Average ReductionMethod = func(input []float64) float64 {
|
var (
|
||||||
|
medianReducer = NearestRankReducer(50)
|
||||||
|
)
|
||||||
|
|
||||||
|
// These are the canned ReductionMethods.
|
||||||
|
var (
|
||||||
|
// Reduce to the average of the set.
|
||||||
|
AverageReducer = averageReducer
|
||||||
|
|
||||||
|
// Extract the first modal value.
|
||||||
|
FirstModeReducer = firstModeReducer
|
||||||
|
|
||||||
|
// Reduce to the maximum of the set.
|
||||||
|
MaximumReducer = maximumReducer
|
||||||
|
|
||||||
|
// Reduce to the median of the set.
|
||||||
|
MedianReducer = medianReducer
|
||||||
|
|
||||||
|
// Reduce to the minimum of the set.
|
||||||
|
MinimumReducer = minimumReducer
|
||||||
|
)
|
||||||
|
|
||||||
|
func averageReducer(input []float64) float64 {
|
||||||
count := 0.0
|
count := 0.0
|
||||||
sum := 0.0
|
sum := 0.0
|
||||||
|
|
||||||
|
@ -34,11 +55,10 @@ var Average ReductionMethod = func(input []float64) float64 {
|
||||||
return sum / count
|
return sum / count
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract the first modal value.
|
func firstModeReducer(input []float64) float64 {
|
||||||
var FirstMode ReductionMethod = func(input []float64) float64 {
|
|
||||||
valuesToFrequency := map[float64]int64{}
|
valuesToFrequency := map[float64]int64{}
|
||||||
var largestTally int64 = math.MinInt64
|
largestTally := int64(math.MinInt64)
|
||||||
var largestTallyValue float64 = math.NaN()
|
largestTallyValue := math.NaN()
|
||||||
|
|
||||||
for _, v := range input {
|
for _, v := range input {
|
||||||
presentCount, _ := valuesToFrequency[v]
|
presentCount, _ := valuesToFrequency[v]
|
||||||
|
@ -56,7 +76,7 @@ var FirstMode ReductionMethod = func(input []float64) float64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the percentile by choosing the nearest neighboring value.
|
// Calculate the percentile by choosing the nearest neighboring value.
|
||||||
func NearestRank(input []float64, percentile float64) float64 {
|
func nearestRank(input []float64, percentile float64) float64 {
|
||||||
inputSize := len(input)
|
inputSize := len(input)
|
||||||
|
|
||||||
if inputSize == 0 {
|
if inputSize == 0 {
|
||||||
|
@ -81,14 +101,12 @@ func NearestRank(input []float64, percentile float64) float64 {
|
||||||
// Generate a ReductionMethod based off of extracting a given percentile value.
|
// Generate a ReductionMethod based off of extracting a given percentile value.
|
||||||
func NearestRankReducer(percentile float64) ReductionMethod {
|
func NearestRankReducer(percentile float64) ReductionMethod {
|
||||||
return func(input []float64) float64 {
|
return func(input []float64) float64 {
|
||||||
return NearestRank(input, percentile)
|
return nearestRank(input, percentile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var Median ReductionMethod = NearestRankReducer(50)
|
func minimumReducer(input []float64) float64 {
|
||||||
|
minimum := math.MaxFloat64
|
||||||
var Minimum ReductionMethod = func(input []float64) float64 {
|
|
||||||
var minimum float64 = math.MaxFloat64
|
|
||||||
|
|
||||||
for _, v := range input {
|
for _, v := range input {
|
||||||
minimum = math.Min(minimum, v)
|
minimum = math.Min(minimum, v)
|
||||||
|
@ -97,8 +115,8 @@ var Minimum ReductionMethod = func(input []float64) float64 {
|
||||||
return minimum
|
return minimum
|
||||||
}
|
}
|
||||||
|
|
||||||
var Maximum ReductionMethod = func(input []float64) float64 {
|
func maximumReducer(input []float64) float64 {
|
||||||
var maximum float64 = math.SmallestNonzeroFloat64
|
maximum := math.SmallestNonzeroFloat64
|
||||||
|
|
||||||
for _, v := range input {
|
for _, v := range input {
|
||||||
maximum = math.Max(maximum, v)
|
maximum = math.Max(maximum, v)
|
|
@ -1,10 +1,10 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package maths
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
. "github.com/matttproud/gocheck"
|
. "github.com/matttproud/gocheck"
|
||||||
|
@ -12,42 +12,42 @@ import (
|
||||||
|
|
||||||
func (s *S) TestAverageOnEmpty(c *C) {
|
func (s *S) TestAverageOnEmpty(c *C) {
|
||||||
empty := []float64{}
|
empty := []float64{}
|
||||||
var v float64 = Average(empty)
|
var v float64 = AverageReducer(empty)
|
||||||
|
|
||||||
c.Assert(v, IsNaN)
|
c.Assert(v, IsNaN)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *S) TestAverageForSingleton(c *C) {
|
func (s *S) TestAverageForSingleton(c *C) {
|
||||||
input := []float64{5}
|
input := []float64{5}
|
||||||
var v float64 = Average(input)
|
var v float64 = AverageReducer(input)
|
||||||
|
|
||||||
c.Check(v, Equals, 5.0)
|
c.Check(v, Equals, 5.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *S) TestAverage(c *C) {
|
func (s *S) TestAverage(c *C) {
|
||||||
input := []float64{5, 15}
|
input := []float64{5, 15}
|
||||||
var v float64 = Average(input)
|
var v float64 = AverageReducer(input)
|
||||||
|
|
||||||
c.Check(v, Equals, 10.0)
|
c.Check(v, Equals, 10.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *S) TestFirstModeOnEmpty(c *C) {
|
func (s *S) TestFirstModeOnEmpty(c *C) {
|
||||||
input := []float64{}
|
input := []float64{}
|
||||||
var v float64 = FirstMode(input)
|
var v float64 = FirstModeReducer(input)
|
||||||
|
|
||||||
c.Assert(v, IsNaN)
|
c.Assert(v, IsNaN)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *S) TestFirstModeForSingleton(c *C) {
|
func (s *S) TestFirstModeForSingleton(c *C) {
|
||||||
input := []float64{5}
|
input := []float64{5}
|
||||||
var v float64 = FirstMode(input)
|
var v float64 = FirstModeReducer(input)
|
||||||
|
|
||||||
c.Check(v, Equals, 5.0)
|
c.Check(v, Equals, 5.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *S) TestFirstModeForUnimodal(c *C) {
|
func (s *S) TestFirstModeForUnimodal(c *C) {
|
||||||
input := []float64{1, 2, 3, 4, 3}
|
input := []float64{1, 2, 3, 4, 3}
|
||||||
var v float64 = FirstMode(input)
|
var v float64 = FirstModeReducer(input)
|
||||||
|
|
||||||
c.Check(v, Equals, 3.0)
|
c.Check(v, Equals, 3.0)
|
||||||
}
|
}
|
||||||
|
@ -55,25 +55,25 @@ func (s *S) TestFirstModeForUnimodal(c *C) {
|
||||||
func (s *S) TestNearestRankForEmpty(c *C) {
|
func (s *S) TestNearestRankForEmpty(c *C) {
|
||||||
input := []float64{}
|
input := []float64{}
|
||||||
|
|
||||||
c.Assert(NearestRank(input, 0), IsNaN)
|
c.Assert(nearestRank(input, 0), IsNaN)
|
||||||
c.Assert(NearestRank(input, 50), IsNaN)
|
c.Assert(nearestRank(input, 50), IsNaN)
|
||||||
c.Assert(NearestRank(input, 100), IsNaN)
|
c.Assert(nearestRank(input, 100), IsNaN)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *S) TestNearestRankForSingleton(c *C) {
|
func (s *S) TestNearestRankForSingleton(c *C) {
|
||||||
input := []float64{5}
|
input := []float64{5}
|
||||||
|
|
||||||
c.Check(NearestRank(input, 0), Equals, 5.0)
|
c.Check(nearestRank(input, 0), Equals, 5.0)
|
||||||
c.Check(NearestRank(input, 50), Equals, 5.0)
|
c.Check(nearestRank(input, 50), Equals, 5.0)
|
||||||
c.Check(NearestRank(input, 100), Equals, 5.0)
|
c.Check(nearestRank(input, 100), Equals, 5.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *S) TestNearestRankForDouble(c *C) {
|
func (s *S) TestNearestRankForDouble(c *C) {
|
||||||
input := []float64{5, 5}
|
input := []float64{5, 5}
|
||||||
|
|
||||||
c.Check(NearestRank(input, 0), Equals, 5.0)
|
c.Check(nearestRank(input, 0), Equals, 5.0)
|
||||||
c.Check(NearestRank(input, 50), Equals, 5.0)
|
c.Check(nearestRank(input, 50), Equals, 5.0)
|
||||||
c.Check(NearestRank(input, 100), Equals, 5.0)
|
c.Check(nearestRank(input, 100), Equals, 5.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *S) TestNearestRankFor100(c *C) {
|
func (s *S) TestNearestRankFor100(c *C) {
|
||||||
|
@ -83,9 +83,9 @@ func (s *S) TestNearestRankFor100(c *C) {
|
||||||
input[i] = float64(i + 1)
|
input[i] = float64(i + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Check(NearestRank(input, 0), Equals, 1.0)
|
c.Check(nearestRank(input, 0), Equals, 1.0)
|
||||||
c.Check(NearestRank(input, 50), Equals, 51.0)
|
c.Check(nearestRank(input, 50), Equals, 51.0)
|
||||||
c.Check(NearestRank(input, 100), Equals, 100.0)
|
c.Check(nearestRank(input, 100), Equals, 100.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *S) TestNearestRankFor101(c *C) {
|
func (s *S) TestNearestRankFor101(c *C) {
|
||||||
|
@ -95,25 +95,25 @@ func (s *S) TestNearestRankFor101(c *C) {
|
||||||
input[i] = float64(i + 1)
|
input[i] = float64(i + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Check(NearestRank(input, 0), Equals, 1.0)
|
c.Check(nearestRank(input, 0), Equals, 1.0)
|
||||||
c.Check(NearestRank(input, 50), Equals, 51.0)
|
c.Check(nearestRank(input, 50), Equals, 51.0)
|
||||||
c.Check(NearestRank(input, 100), Equals, 101.0)
|
c.Check(nearestRank(input, 100), Equals, 101.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *S) TestMedianReducer(c *C) {
|
func (s *S) TestMedianReducer(c *C) {
|
||||||
input := []float64{1, 2, 3}
|
input := []float64{1, 2, 3}
|
||||||
|
|
||||||
c.Check(Median(input), Equals, 2.0)
|
c.Check(MedianReducer(input), Equals, 2.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *S) TestMinimum(c *C) {
|
func (s *S) TestMinimum(c *C) {
|
||||||
input := []float64{5, 1, 10, 1.1, 4}
|
input := []float64{5, 1, 10, 1.1, 4}
|
||||||
|
|
||||||
c.Check(Minimum(input), Equals, 1.0)
|
c.Check(MinimumReducer(input), Equals, 1.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *S) TestMaximum(c *C) {
|
func (s *S) TestMaximum(c *C) {
|
||||||
input := []float64{5, 1, 10, 1.1, 4}
|
input := []float64{5, 1, 10, 1.1, 4}
|
||||||
|
|
||||||
c.Check(Maximum(input), Equals, 10.0)
|
c.Check(MaximumReducer(input), Equals, 10.0)
|
||||||
}
|
}
|
|
@ -1,14 +1,13 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package metrics
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/prometheus/client_golang/maths"
|
|
||||||
"math"
|
"math"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
@ -35,38 +34,49 @@ func emptyFilter(e TallyingIndexEstimator) TallyingIndexEstimator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report the smallest observed value in the bucket.
|
var (
|
||||||
var Minimum TallyingIndexEstimator = emptyFilter(func(minimum, maximum float64, _, observations int) float64 {
|
minimumEstimator = emptyFilter(func(minimum, maximum float64, _, observations int) float64 {
|
||||||
return minimum
|
|
||||||
})
|
|
||||||
|
|
||||||
// Report the largest observed value in the bucket.
|
|
||||||
var Maximum TallyingIndexEstimator = emptyFilter(func(minimum, maximum float64, _, observations int) float64 {
|
|
||||||
return maximum
|
|
||||||
})
|
|
||||||
|
|
||||||
// Report the average of the extrema.
|
|
||||||
var Average TallyingIndexEstimator = emptyFilter(func(minimum, maximum float64, _, observations int) float64 {
|
|
||||||
return maths.Average([]float64{minimum, maximum})
|
|
||||||
})
|
|
||||||
|
|
||||||
// Report the minimum value of the index is in the lower-third of observations,
|
|
||||||
// the average if in the middle-third, and the maximum if in the largest third.
|
|
||||||
var Uniform TallyingIndexEstimator = emptyFilter(func(minimum, maximum float64, index, observations int) float64 {
|
|
||||||
if observations == 1 {
|
|
||||||
return minimum
|
return minimum
|
||||||
}
|
})
|
||||||
|
|
||||||
location := float64(index) / float64(observations)
|
maximumEstimator = emptyFilter(func(minimum, maximum float64, _, observations int) float64 {
|
||||||
|
|
||||||
if location > upperThird {
|
|
||||||
return maximum
|
return maximum
|
||||||
} else if location < lowerThird {
|
})
|
||||||
return minimum
|
|
||||||
}
|
|
||||||
|
|
||||||
return maths.Average([]float64{minimum, maximum})
|
averageEstimator = emptyFilter(func(minimum, maximum float64, _, observations int) float64 {
|
||||||
})
|
return AverageReducer([]float64{minimum, maximum})
|
||||||
|
})
|
||||||
|
|
||||||
|
uniformEstimator = emptyFilter(func(minimum, maximum float64, index, observations int) float64 {
|
||||||
|
if observations == 1 {
|
||||||
|
return minimum
|
||||||
|
}
|
||||||
|
|
||||||
|
location := float64(index) / float64(observations)
|
||||||
|
|
||||||
|
if location > upperThird {
|
||||||
|
return maximum
|
||||||
|
} else if location < lowerThird {
|
||||||
|
return minimum
|
||||||
|
}
|
||||||
|
|
||||||
|
return AverageReducer([]float64{minimum, maximum})
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
// These are the canned TallyingIndexEstimators.
|
||||||
|
var (
|
||||||
|
// Report the smallest observed value in the bucket.
|
||||||
|
MinimumEstimator = minimumEstimator
|
||||||
|
// Report the largest observed value in the bucket.
|
||||||
|
MaximumEstimator = maximumEstimator
|
||||||
|
// Report the average of the extrema.
|
||||||
|
AverageEstimator = averageEstimator
|
||||||
|
// Report the minimum value of the index if it is in the lower-third of
|
||||||
|
// observations, the average if in the middle-third, and the maximum if in
|
||||||
|
// the largest third
|
||||||
|
UniformEstimator = uniformEstimator
|
||||||
|
)
|
||||||
|
|
||||||
// A TallyingBucket is a Bucket that tallies when an object is added to it.
|
// A TallyingBucket is a Bucket that tallies when an object is added to it.
|
||||||
// Upon insertion, an object is compared against collected extrema and noted
|
// Upon insertion, an object is compared against collected extrema and noted
|
||||||
|
@ -127,7 +137,7 @@ func (b *TallyingBucket) Reset() {
|
||||||
// Produce a TallyingBucket with sane defaults.
|
// Produce a TallyingBucket with sane defaults.
|
||||||
func DefaultTallyingBucket() TallyingBucket {
|
func DefaultTallyingBucket() TallyingBucket {
|
||||||
return TallyingBucket{
|
return TallyingBucket{
|
||||||
estimator: Minimum,
|
estimator: MinimumEstimator,
|
||||||
largestObserved: math.SmallestNonzeroFloat64,
|
largestObserved: math.SmallestNonzeroFloat64,
|
||||||
smallestObserved: math.MaxFloat64,
|
smallestObserved: math.MaxFloat64,
|
||||||
}
|
}
|
|
@ -1,40 +1,39 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package metrics
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
. "github.com/matttproud/gocheck"
|
. "github.com/matttproud/gocheck"
|
||||||
"github.com/prometheus/client_golang/maths"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *S) TestTallyingPercentileEstimatorMinimum(c *C) {
|
func (s *S) TestTallyingPercentileEstimatorMinimum(c *C) {
|
||||||
c.Assert(Minimum(-2, -1, 0, 0), maths.IsNaN)
|
c.Assert(MinimumEstimator(-2, -1, 0, 0), IsNaN)
|
||||||
c.Check(Minimum(-2, -1, 0, 1), Equals, -2.0)
|
c.Check(MinimumEstimator(-2, -1, 0, 1), Equals, -2.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *S) TestTallyingPercentileEstimatorMaximum(c *C) {
|
func (s *S) TestTallyingPercentileEstimatorMaximum(c *C) {
|
||||||
c.Assert(Maximum(-2, -1, 0, 0), maths.IsNaN)
|
c.Assert(MaximumEstimator(-2, -1, 0, 0), IsNaN)
|
||||||
c.Check(Maximum(-2, -1, 0, 1), Equals, -1.0)
|
c.Check(MaximumEstimator(-2, -1, 0, 1), Equals, -1.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *S) TestTallyingPercentilesEstimatorAverage(c *C) {
|
func (s *S) TestTallyingPercentilesEstimatorAverage(c *C) {
|
||||||
c.Assert(Average(-2, -1, 0, 0), maths.IsNaN)
|
c.Assert(AverageEstimator(-2, -1, 0, 0), IsNaN)
|
||||||
c.Check(Average(-2, -2, 0, 1), Equals, -2.0)
|
c.Check(AverageEstimator(-2, -2, 0, 1), Equals, -2.0)
|
||||||
c.Check(Average(-1, -1, 0, 1), Equals, -1.0)
|
c.Check(AverageEstimator(-1, -1, 0, 1), Equals, -1.0)
|
||||||
c.Check(Average(1, 1, 0, 2), Equals, 1.0)
|
c.Check(AverageEstimator(1, 1, 0, 2), Equals, 1.0)
|
||||||
c.Check(Average(2, 1, 0, 2), Equals, 1.5)
|
c.Check(AverageEstimator(2, 1, 0, 2), Equals, 1.5)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *S) TestTallyingPercentilesEstimatorUniform(c *C) {
|
func (s *S) TestTallyingPercentilesEstimatorUniform(c *C) {
|
||||||
c.Assert(Uniform(-5, 5, 0, 0), maths.IsNaN)
|
c.Assert(UniformEstimator(-5, 5, 0, 0), IsNaN)
|
||||||
|
|
||||||
c.Check(Uniform(-5, 5, 0, 2), Equals, -5.0)
|
c.Check(UniformEstimator(-5, 5, 0, 2), Equals, -5.0)
|
||||||
c.Check(Uniform(-5, 5, 1, 2), Equals, 0.0)
|
c.Check(UniformEstimator(-5, 5, 1, 2), Equals, 0.0)
|
||||||
c.Check(Uniform(-5, 5, 2, 2), Equals, 5.0)
|
c.Check(UniformEstimator(-5, 5, 2, 2), Equals, 5.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *S) TestTallyingBucketBuilder(c *C) {
|
func (s *S) TestTallyingBucketBuilder(c *C) {
|
|
@ -1,15 +1,13 @@
|
||||||
// Copyright (c) 2013, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style license that can be found
|
// Use of this source code is governed by a BSD-style license that can be found
|
||||||
// in the LICENSE file.
|
// in the LICENSE file.
|
||||||
//
|
//
|
||||||
|
|
||||||
package registry
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/prometheus/client_golang/maths"
|
|
||||||
"github.com/prometheus/client_golang/metrics"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,18 +15,18 @@ import (
|
||||||
// exposed if the DefaultRegistry's exporter is hooked into the HTTP request
|
// exposed if the DefaultRegistry's exporter is hooked into the HTTP request
|
||||||
// handler.
|
// handler.
|
||||||
var (
|
var (
|
||||||
marshalErrorCount = metrics.NewCounter()
|
marshalErrorCount = NewCounter()
|
||||||
dumpErrorCount = metrics.NewCounter()
|
dumpErrorCount = NewCounter()
|
||||||
|
|
||||||
requestCount = metrics.NewCounter()
|
requestCount = NewCounter()
|
||||||
requestLatencyBuckets = metrics.LogarithmicSizedBucketsFor(0, 1000)
|
requestLatencyBuckets = LogarithmicSizedBucketsFor(0, 1000)
|
||||||
requestLatency = metrics.NewHistogram(&metrics.HistogramSpecification{
|
requestLatency = NewHistogram(&HistogramSpecification{
|
||||||
Starts: requestLatencyBuckets,
|
Starts: requestLatencyBuckets,
|
||||||
BucketBuilder: metrics.AccumulatingBucketBuilder(metrics.EvictAndReplaceWith(50, maths.Average), 1000),
|
BucketBuilder: AccumulatingBucketBuilder(EvictAndReplaceWith(50, AverageReducer), 1000),
|
||||||
ReportablePercentiles: []float64{0.01, 0.05, 0.5, 0.9, 0.99},
|
ReportablePercentiles: []float64{0.01, 0.05, 0.5, 0.9, 0.99},
|
||||||
})
|
})
|
||||||
|
|
||||||
startTime = metrics.NewGauge()
|
startTime = NewGauge()
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -42,7 +40,7 @@ func init() {
|
||||||
|
|
||||||
// This callback accumulates the microsecond duration of the reporting
|
// This callback accumulates the microsecond duration of the reporting
|
||||||
// framework's overhead such that it can be reported.
|
// framework's overhead such that it can be reported.
|
||||||
var requestLatencyAccumulator metrics.CompletionCallback = func(duration time.Duration) {
|
var requestLatencyAccumulator CompletionCallback = func(duration time.Duration) {
|
||||||
microseconds := float64(duration / time.Microsecond)
|
microseconds := float64(duration / time.Microsecond)
|
||||||
|
|
||||||
requestLatency.Add(nil, microseconds)
|
requestLatency.Add(nil, microseconds)
|
|
@ -1,10 +1,10 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package utility
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
. "github.com/matttproud/gocheck"
|
. "github.com/matttproud/gocheck"
|
||||||
|
@ -19,7 +19,7 @@ var ValueEquals Checker = &valueEqualsChecker{
|
||||||
}
|
}
|
||||||
|
|
||||||
func (checker *valueEqualsChecker) Check(params []interface{}, names []string) (result bool, error string) {
|
func (checker *valueEqualsChecker) Check(params []interface{}, names []string) (result bool, error string) {
|
||||||
actual := params[0].(*Item).Value
|
actual := params[0].(*item).Value
|
||||||
expected := params[1]
|
expected := params[1]
|
||||||
|
|
||||||
return actual == expected, ""
|
return actual == expected, ""
|
|
@ -1,10 +1,10 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package metrics
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
|
@ -1,10 +1,10 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
// Copyright (c) 2013, Prometheus Team
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package metrics
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
. "github.com/matttproud/gocheck"
|
. "github.com/matttproud/gocheck"
|
|
@ -1,20 +0,0 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
|
||||||
// All rights reserved.
|
|
||||||
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
//
|
|
||||||
// The utility package provides general purpose helpers to assist with this
|
|
||||||
// library.
|
|
||||||
//
|
|
||||||
// priority_queue.go provides a simple priority queue.
|
|
||||||
//
|
|
||||||
// priority_queue_test.go provides a test complement for the priority_queue.go
|
|
||||||
// module.
|
|
||||||
//
|
|
||||||
// test_helper.go provides a testing assistents for this package and its
|
|
||||||
// dependents.
|
|
||||||
//
|
|
||||||
// utility_test.go provides a test suite for all tests in the utility package
|
|
||||||
// hierarchy. It employs the gocheck framework for test scaffolding.
|
|
||||||
package documentation
|
|
|
@ -1,20 +0,0 @@
|
||||||
// Copyright (c) 2012, Matt T. Proud
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package utility
|
|
||||||
|
|
||||||
import (
|
|
||||||
. "github.com/matttproud/gocheck"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
type S struct{}
|
|
||||||
|
|
||||||
var _ = Suite(&S{})
|
|
||||||
|
|
||||||
func TestUtility(t *testing.T) {
|
|
||||||
TestingT(t)
|
|
||||||
}
|
|
Loading…
Reference in New Issue