From f320d28a6c6e75ea844f2880fcea76ccbe62541e Mon Sep 17 00:00:00 2001 From: "Matt T. Proud" Date: Wed, 3 Apr 2013 18:33:32 +0200 Subject: [PATCH] Rearrange file and package per convention. WIP - Please review but do not merge. --- .travis.yml | 6 +- LICENSE | 4 +- Makefile | 16 +- Makefile.TRAVIS | 28 +++ TODO | 3 - documentation.go | 11 -- documentation/documentation.go | 43 ++++- documentation/styleguide.go | 48 ----- examples/Makefile | 36 ++++ examples/delegator/.gitignore | 1 + examples/delegator/Makefile | 32 ++++ examples/delegator/main.go | 8 +- examples/documentation.go | 8 - examples/random/.gitignore | 1 + examples/random/Makefile | 32 ++++ examples/random/main.go | 22 +-- examples/simple/.gitignore | 1 + examples/simple/Makefile | 32 ++++ examples/simple/main.go | 6 +- maths/documentation.go | 22 --- maths/maths_test.go | 20 -- metrics/constants.go | 20 -- metrics/documentation.go | 48 ----- metrics/eviction_test.go | 179 ------------------ prometheus/.gitignore | 1 + prometheus/Makefile | 25 +++ .../accumulating_bucket.go | 11 +- .../accumulating_bucket_test.go | 14 +- {metrics => prometheus}/bucket.go | 6 +- constants.go => prometheus/constants.go | 17 +- {metrics => prometheus}/counter.go | 11 +- {metrics => prometheus}/counter_test.go | 7 +- {maths => prometheus}/distributions.go | 10 +- prometheus/documentation.go | 16 ++ {metrics => prometheus}/eviction.go | 12 +- prometheus/eviction_test.go | 177 +++++++++++++++++ {exp => prometheus/exp}/coarsemux.go | 25 ++- {exp => prometheus/exp}/documentation.go | 2 +- .../exp}/responsewriter_delegator.go | 2 +- {metrics => prometheus}/gauge.go | 7 +- {metrics => prometheus}/gauge_test.go | 7 +- {maths => prometheus}/helpers_for_testing.go | 4 +- {metrics => prometheus}/histogram.go | 10 +- {metrics => prometheus}/histogram_test.go | 4 +- {utility/test => prometheus}/interface.go | 6 +- {metrics => prometheus}/metric.go | 4 +- {utility => prometheus}/priority_queue.go | 20 +- .../priority_queue_test.go | 18 +- .../prometheus_test.go | 6 +- registry.go => prometheus/registry.go | 20 +- .../registry_test.go | 24 ++- {utility => prometheus}/signature.go | 6 +- {utility => prometheus}/signature_test.go | 9 +- {maths => prometheus}/statistics.go | 52 +++-- {maths => prometheus}/statistics_test.go | 52 ++--- {metrics => prometheus}/tallying_bucket.go | 74 ++++---- .../tallying_bucket_test.go | 31 ++- telemetry.go => prometheus/telemetry.go | 22 +-- {utility => prometheus}/test_helper.go | 6 +- {metrics => prometheus}/timer.go | 4 +- {metrics => prometheus}/timer_test.go | 4 +- utility/documentation.go | 20 -- utility/utility_test.go | 20 -- 63 files changed, 716 insertions(+), 677 deletions(-) create mode 100644 Makefile.TRAVIS delete mode 100644 documentation.go delete mode 100644 documentation/styleguide.go create mode 100644 examples/Makefile create mode 100644 examples/delegator/.gitignore create mode 100644 examples/delegator/Makefile delete mode 100644 examples/documentation.go create mode 100644 examples/random/.gitignore create mode 100644 examples/random/Makefile create mode 100644 examples/simple/.gitignore create mode 100644 examples/simple/Makefile delete mode 100644 maths/documentation.go delete mode 100644 maths/maths_test.go delete mode 100644 metrics/constants.go delete mode 100644 metrics/documentation.go delete mode 100644 metrics/eviction_test.go create mode 100644 prometheus/.gitignore create mode 100644 prometheus/Makefile rename {metrics => prometheus}/accumulating_bucket.go (91%) rename {metrics => prometheus}/accumulating_bucket_test.go (93%) rename {metrics => prometheus}/bucket.go (88%) rename constants.go => prometheus/constants.go (78%) rename {metrics => prometheus}/counter.go (92%) rename {metrics => prometheus}/counter_test.go (96%) rename {maths => prometheus}/distributions.go (74%) create mode 100644 prometheus/documentation.go rename {metrics => prometheus}/eviction.go (76%) create mode 100644 prometheus/eviction_test.go rename {exp => prometheus/exp}/coarsemux.go (67%) rename {exp => prometheus/exp}/documentation.go (91%) rename {exp => prometheus/exp}/responsewriter_delegator.go (98%) rename {metrics => prometheus}/gauge.go (93%) rename {metrics => prometheus}/gauge_test.go (94%) rename {maths => prometheus}/helpers_for_testing.go (93%) rename {metrics => prometheus}/histogram.go (97%) rename {metrics => prometheus}/histogram_test.go (75%) rename {utility/test => prometheus}/interface.go (77%) rename {metrics => prometheus}/metric.go (89%) rename {utility => prometheus}/priority_queue.go (61%) rename {utility => prometheus}/priority_queue_test.go (58%) rename metrics/metrics_test.go => prometheus/prometheus_test.go (72%) rename registry.go => prometheus/registry.go (94%) rename registry_test.go => prometheus/registry_test.go (92%) rename {utility => prometheus}/signature.go (87%) rename {utility => prometheus}/signature_test.go (75%) rename {maths => prometheus}/statistics.go (63%) rename {maths => prometheus}/statistics_test.go (56%) rename {metrics => prometheus}/tallying_bucket.go (68%) rename {metrics => prometheus}/tallying_bucket_test.go (62%) rename telemetry.go => prometheus/telemetry.go (64%) rename {utility => prometheus}/test_helper.go (84%) rename {metrics => prometheus}/timer.go (96%) rename {metrics => prometheus}/timer_test.go (95%) delete mode 100644 utility/documentation.go delete mode 100644 utility/utility_test.go diff --git a/.travis.yml b/.travis.yml index c28cb48..60e95ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,4 @@ language: go -before_script: - - go get -v github.com/prometheus/client_golang - script: - - go build -a -v github.com/prometheus/client_golang/... - - go test -v github.com/prometheus/client_golang/... + - make -f Makefile.TRAVIS diff --git a/LICENSE b/LICENSE index 22a717f..fe2fbf5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2012, Matt T. Proud +Copyright (c) 2013, Prometheus Team All rights reserved. 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 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 -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Makefile b/Makefile index 5527b63..c43f4c3 100644 --- a/Makefile +++ b/Makefile @@ -16,17 +16,20 @@ MAKE_ARTIFACTS = search_index all: test build: - go build ./... + $(MAKE) -C prometheus build + $(MAKE) -C examples 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: find . -iname '*.go' -exec gofmt -w -s=true '{}' ';' -advice: - go tool vet . - 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' clean: + $(MAKE) -C examples clean rm -f $(MAKE_ARTIFACTS) + find . -iname '*~' -exec rm -f '{}' ';' + find . -iname '*#' -exec rm -f '{}' ';' .PHONY: advice build clean documentation format test diff --git a/Makefile.TRAVIS b/Makefile.TRAVIS new file mode 100644 index 0000000..78a3a68 --- /dev/null +++ b/Makefile.TRAVIS @@ -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 diff --git a/TODO b/TODO index faa56e9..34f3b6d 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,2 @@ - 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. diff --git a/documentation.go b/documentation.go deleted file mode 100644 index 87f3504..0000000 --- a/documentation.go +++ /dev/null @@ -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 diff --git a/documentation/documentation.go b/documentation/documentation.go index 32265ae..9e556ab 100644 --- a/documentation/documentation.go +++ b/documentation/documentation.go @@ -1,8 +1,49 @@ -// Copyright (c) 2013, Matt T. Proud +// 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. // 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 diff --git a/documentation/styleguide.go b/documentation/styleguide.go deleted file mode 100644 index dfed6b0..0000000 --- a/documentation/styleguide.go +++ /dev/null @@ -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 diff --git a/examples/Makefile b/examples/Makefile new file mode 100644 index 0000000..2493ff3 --- /dev/null +++ b/examples/Makefile @@ -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 diff --git a/examples/delegator/.gitignore b/examples/delegator/.gitignore new file mode 100644 index 0000000..8d83f4b --- /dev/null +++ b/examples/delegator/.gitignore @@ -0,0 +1 @@ +delegator \ No newline at end of file diff --git a/examples/delegator/Makefile b/examples/delegator/Makefile new file mode 100644 index 0000000..c60b94c --- /dev/null +++ b/examples/delegator/Makefile @@ -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 diff --git a/examples/delegator/main.go b/examples/delegator/main.go index 87258b1..4ff59ed 100644 --- a/examples/delegator/main.go +++ b/examples/delegator/main.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012, Matt T. Proud +// Copyright (c) 2013, Prometheus Team // All rights reserved. // // Use of this source code is governed by a BSD-style @@ -10,8 +10,8 @@ package main import ( "flag" - "github.com/prometheus/client_golang" - "github.com/prometheus/client_golang/exp" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/exp" "net/http" ) @@ -48,7 +48,7 @@ func main() { exp.HandleFunc("/hello", helloHandler) exp.HandleFunc("/goodbye", goodbyeHandler) exp.HandleFunc("/teapot", teapotHandler) - exp.Handle(registry.ExpositionResource, registry.DefaultHandler) + exp.Handle(prometheus.ExpositionResource, prometheus.DefaultHandler) http.ListenAndServe(*listeningAddress, exp.DefaultCoarseMux) } diff --git a/examples/documentation.go b/examples/documentation.go deleted file mode 100644 index e7586b9..0000000 --- a/examples/documentation.go +++ /dev/null @@ -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 diff --git a/examples/random/.gitignore b/examples/random/.gitignore new file mode 100644 index 0000000..19cec5d --- /dev/null +++ b/examples/random/.gitignore @@ -0,0 +1 @@ +random \ No newline at end of file diff --git a/examples/random/Makefile b/examples/random/Makefile new file mode 100644 index 0000000..c54b305 --- /dev/null +++ b/examples/random/Makefile @@ -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 diff --git a/examples/random/main.go b/examples/random/main.go index f3bc001..dd41e2e 100644 --- a/examples/random/main.go +++ b/examples/random/main.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012, Matt T. Proud +// Copyright (c) 2013, Prometheus Team // All rights reserved. // // Use of this source code is governed by a BSD-style @@ -13,9 +13,7 @@ package main import ( "flag" - "github.com/prometheus/client_golang" - "github.com/prometheus/client_golang/maths" - "github.com/prometheus/client_golang/metrics" + "github.com/prometheus/client_golang/prometheus" "math/rand" "net/http" "time" @@ -28,27 +26,27 @@ var ( // Create a histogram to track fictitious interservice RPC latency for three // distinct services. - rpcLatency = metrics.NewHistogram(&metrics.HistogramSpecification{ + rpcLatency = prometheus.NewHistogram(&prometheus.HistogramSpecification{ // Four distinct histogram buckets for values: // - equally-sized, // - 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 // holds sample values subject to an eviction policy: // - 50 elements are allowed per bucket. // - Once 50 have been reached, the bucket empties 10 elements, averages the // 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. 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 // registry for metrics, which is a really bad idea when using Prometheus- // enabled library code, you can create your own. - customRegistry = registry.NewRegistry() + customRegistry = prometheus.NewRegistry() ) func main() { @@ -69,13 +67,13 @@ func main() { } }() - http.Handle(registry.ExpositionResource, customRegistry.Handler()) + http.Handle(prometheus.ExpositionResource, customRegistry.Handler()) http.ListenAndServe(*listeningAddress, nil) } func init() { - customRegistry.Register("rpc_latency_microseconds", "RPC latency.", registry.NilLabels, rpcLatency) - customRegistry.Register("rpc_calls_total", "RPC calls.", registry.NilLabels, rpcCalls) + customRegistry.Register("rpc_latency_microseconds", "RPC latency.", prometheus.NilLabels, rpcLatency) + customRegistry.Register("rpc_calls_total", "RPC calls.", prometheus.NilLabels, rpcCalls) } var ( diff --git a/examples/simple/.gitignore b/examples/simple/.gitignore new file mode 100644 index 0000000..8fd3246 --- /dev/null +++ b/examples/simple/.gitignore @@ -0,0 +1 @@ +simple \ No newline at end of file diff --git a/examples/simple/Makefile b/examples/simple/Makefile new file mode 100644 index 0000000..dba8a98 --- /dev/null +++ b/examples/simple/Makefile @@ -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 diff --git a/examples/simple/main.go b/examples/simple/main.go index 0b4e9df..25d527d 100644 --- a/examples/simple/main.go +++ b/examples/simple/main.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012, Matt T. Proud +// Copyright (c) 2013, Prometheus Team // All rights reserved. // // Use of this source code is governed by a BSD-style @@ -10,14 +10,14 @@ package main import ( "flag" - "github.com/prometheus/client_golang" + "github.com/prometheus/client_golang/prometheus" "net/http" ) func main() { flag.Parse() - http.Handle(registry.ExpositionResource, registry.DefaultHandler) + http.Handle(prometheus.ExpositionResource, prometheus.DefaultHandler) http.ListenAndServe(*listeningAddress, nil) } diff --git a/maths/documentation.go b/maths/documentation.go deleted file mode 100644 index af7fbed..0000000 --- a/maths/documentation.go +++ /dev/null @@ -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 diff --git a/maths/maths_test.go b/maths/maths_test.go deleted file mode 100644 index 4e5ff10..0000000 --- a/maths/maths_test.go +++ /dev/null @@ -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) -} diff --git a/metrics/constants.go b/metrics/constants.go deleted file mode 100644 index 11c9a9b..0000000 --- a/metrics/constants.go +++ /dev/null @@ -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" -) diff --git a/metrics/documentation.go b/metrics/documentation.go deleted file mode 100644 index 8e60d61..0000000 --- a/metrics/documentation.go +++ /dev/null @@ -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 diff --git a/metrics/eviction_test.go b/metrics/eviction_test.go deleted file mode 100644 index efc3e73..0000000 --- a/metrics/eviction_test.go +++ /dev/null @@ -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) -} diff --git a/prometheus/.gitignore b/prometheus/.gitignore new file mode 100644 index 0000000..3460f03 --- /dev/null +++ b/prometheus/.gitignore @@ -0,0 +1 @@ +command-line-arguments.test diff --git a/prometheus/Makefile b/prometheus/Makefile new file mode 100644 index 0000000..85b7b46 --- /dev/null +++ b/prometheus/Makefile @@ -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 diff --git a/metrics/accumulating_bucket.go b/prometheus/accumulating_bucket.go similarity index 91% rename from metrics/accumulating_bucket.go rename to prometheus/accumulating_bucket.go index 7c219b7..73d8530 100644 --- a/metrics/accumulating_bucket.go +++ b/prometheus/accumulating_bucket.go @@ -1,16 +1,15 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 metrics +package prometheus import ( "bytes" "container/heap" "fmt" - "github.com/prometheus/client_golang/utility" "math" "sort" "sync" @@ -18,7 +17,7 @@ import ( ) type AccumulatingBucket struct { - elements utility.PriorityQueue + elements priorityQueue evictionPolicy EvictionPolicy maximumSize int mutex sync.RWMutex @@ -31,7 +30,7 @@ type AccumulatingBucket struct { func AccumulatingBucketBuilder(evictionPolicy EvictionPolicy, maximumSize int) BucketBuilder { return func() Bucket { return &AccumulatingBucket{ - elements: make(utility.PriorityQueue, 0, maximumSize), + elements: make(priorityQueue, 0, maximumSize), evictionPolicy: evictionPolicy, maximumSize: maximumSize, } @@ -47,7 +46,7 @@ func (b *AccumulatingBucket) Add(value float64) { b.observations++ size := len(b.elements) - v := utility.Item{ + v := item{ Priority: -1 * time.Now().UnixNano(), Value: value, } diff --git a/metrics/accumulating_bucket_test.go b/prometheus/accumulating_bucket_test.go similarity index 93% rename from metrics/accumulating_bucket_test.go rename to prometheus/accumulating_bucket_test.go index 789c682..b575ed3 100644 --- a/metrics/accumulating_bucket_test.go +++ b/prometheus/accumulating_bucket_test.go @@ -1,15 +1,13 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 metrics +package prometheus import ( . "github.com/matttproud/gocheck" - "github.com/prometheus/client_golang/maths" - "github.com/prometheus/client_golang/utility" "time" ) @@ -51,7 +49,7 @@ func (s *S) TestAccumulatingBucketBuilderWithEvictOldest(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)) @@ -86,7 +84,7 @@ func (s *S) TestAccumulatingBucketBuilderWithEvictAndReplaceWithAverage(c *C) { func (s *S) TestAccumulatingBucket(c *C) { var b AccumulatingBucket = AccumulatingBucket{ - elements: make(utility.PriorityQueue, 0, 10), + elements: make(priorityQueue, 0, 10), maximumSize: 5, } @@ -112,13 +110,13 @@ func (s *S) TestAccumulatingBucket(c *C) { func (s *S) TestAccumulatingBucketValueForIndex(c *C) { var b AccumulatingBucket = AccumulatingBucket{ - elements: make(utility.PriorityQueue, 0, 100), + elements: make(priorityQueue, 0, 100), maximumSize: 100, evictionPolicy: EvictOldest(50), } 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. diff --git a/metrics/bucket.go b/prometheus/bucket.go similarity index 88% rename from metrics/bucket.go rename to prometheus/bucket.go index d4a8414..fe5f42c 100644 --- a/metrics/bucket.go +++ b/prometheus/bucket.go @@ -1,12 +1,10 @@ -// Copyright (c) 2012, Matt T. Proud +// 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. -// bucket.go provides fundamental interface expectations for various bucket -// types. -package metrics +package prometheus // The Histogram class and associated types build buckets on their own. type BucketBuilder func() Bucket diff --git a/constants.go b/prometheus/constants.go similarity index 78% rename from constants.go rename to prometheus/constants.go index e992d5e..58dc855 100644 --- a/constants.go +++ b/prometheus/constants.go @@ -1,10 +1,10 @@ -// Copyright (c) 2013, Matt T. Proud +// 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 registry +package prometheus var ( // NilLabels is a nil set of labels merely for end-user convenience. @@ -14,8 +14,7 @@ var ( // interface. DefaultHandler = DefaultRegistry.Handler() - // This is the default registry with which Metric objects are associated. It - // is primarily a read-only object after server instantiation. + // This is the default registry with which Metric objects are associated. DefaultRegistry = NewRegistry() ) @@ -39,4 +38,14 @@ const ( docstringKey = "docstring" metricKey = "metric" nameLabel = "name" + + counterTypeValue = "counter" + floatBitCount = 64 + floatFormat = 'f' + floatPrecision = 6 + gaugeTypeValue = "gauge" + histogramTypeValue = "histogram" + typeKey = "type" + valueKey = "value" + labelsKey = "labels" ) diff --git a/metrics/counter.go b/prometheus/counter.go similarity index 92% rename from metrics/counter.go rename to prometheus/counter.go index 78bdce2..74b76dd 100644 --- a/metrics/counter.go +++ b/prometheus/counter.go @@ -1,14 +1,13 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 metrics +package prometheus import ( "fmt" - "github.com/prometheus/client_golang/utility" "sync" ) @@ -49,7 +48,7 @@ func (metric *counter) Set(labels map[string]string, value float64) float64 { labels = map[string]string{} } - signature := utility.LabelsToSignature(labels) + signature := labelsToSignature(labels) if original, ok := metric.values[signature]; ok { original.value = value } else { @@ -91,7 +90,7 @@ func (metric *counter) IncrementBy(labels map[string]string, value float64) floa labels = map[string]string{} } - signature := utility.LabelsToSignature(labels) + signature := labelsToSignature(labels) if original, ok := metric.values[signature]; ok { original.value += value } else { @@ -116,7 +115,7 @@ func (metric *counter) DecrementBy(labels map[string]string, value float64) floa labels = map[string]string{} } - signature := utility.LabelsToSignature(labels) + signature := labelsToSignature(labels) if original, ok := metric.values[signature]; ok { original.value -= value } else { diff --git a/metrics/counter_test.go b/prometheus/counter_test.go similarity index 96% rename from metrics/counter_test.go rename to prometheus/counter_test.go index aa489e5..b2023f0 100644 --- a/metrics/counter_test.go +++ b/prometheus/counter_test.go @@ -1,18 +1,17 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 metrics +package prometheus import ( "encoding/json" - "github.com/prometheus/client_golang/utility/test" "testing" ) -func testCounter(t test.Tester) { +func testCounter(t tester) { type input struct { steps []func(g Counter) } diff --git a/maths/distributions.go b/prometheus/distributions.go similarity index 74% rename from maths/distributions.go rename to prometheus/distributions.go index 50783c6..47874a1 100644 --- a/maths/distributions.go +++ b/prometheus/distributions.go @@ -1,17 +1,17 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 maths +package prometheus import ( "math" ) // Go's standard library does not offer a factorial function. -func Factorial(of int) int64 { +func factorial(of int) int64 { if of <= 0 { return 1 } @@ -28,8 +28,8 @@ func Factorial(of int) int64 { // 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 // p is the probability. -func BinomialPDF(k, n int, p float64) float64 { - binomialCoefficient := float64(Factorial(n)) / float64(Factorial(k)*Factorial(n-k)) +func binomialPDF(k, n int, p float64) float64 { + binomialCoefficient := float64(factorial(n)) / float64(factorial(k)*factorial(n-k)) intermediate := math.Pow(p, float64(k)) * math.Pow(1-p, float64(n-k)) return binomialCoefficient * intermediate diff --git a/prometheus/documentation.go b/prometheus/documentation.go new file mode 100644 index 0000000..6da5e45 --- /dev/null +++ b/prometheus/documentation.go @@ -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 diff --git a/metrics/eviction.go b/prometheus/eviction.go similarity index 76% rename from metrics/eviction.go rename to prometheus/eviction.go index 904d08b..425a4a1 100644 --- a/metrics/eviction.go +++ b/prometheus/eviction.go @@ -1,15 +1,13 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 metrics +package prometheus import ( "container/heap" - "github.com/prometheus/client_golang/maths" - "github.com/prometheus/client_golang/utility" "time" ) @@ -29,17 +27,17 @@ func EvictOldest(count int) EvictionPolicy { // This factory produces an EvictionPolicy that applies some standardized // 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) { oldValues := make([]float64, count) 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) - heap.Push(h, &utility.Item{ + heap.Push(h, &item{ Value: reduced, // TODO(mtp): Parameterize the priority generation since these tools are // useful. diff --git a/prometheus/eviction_test.go b/prometheus/eviction_test.go new file mode 100644 index 0000000..b782a0e --- /dev/null +++ b/prometheus/eviction_test.go @@ -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) +} diff --git a/exp/coarsemux.go b/prometheus/exp/coarsemux.go similarity index 67% rename from exp/coarsemux.go rename to prometheus/exp/coarsemux.go index 74af6d7..6c523da 100644 --- a/exp/coarsemux.go +++ b/prometheus/exp/coarsemux.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013, Matt T. Proud +// 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 @@ -8,8 +8,7 @@ package exp import ( "fmt" - "github.com/prometheus/client_golang" - "github.com/prometheus/client_golang/metrics" + "github.com/prometheus/client_golang/prometheus" "net/http" "strings" "time" @@ -33,11 +32,11 @@ type ( ) var ( - requestCounts = metrics.NewCounter() - requestDuration = metrics.NewCounter() - requestDurations = metrics.NewDefaultHistogram() - requestBytes = metrics.NewCounter() - responseBytes = metrics.NewCounter() + requestCounts = prometheus.NewCounter() + requestDuration = prometheus.NewCounter() + requestDurations = prometheus.NewDefaultHistogram() + requestBytes = prometheus.NewCounter() + responseBytes = prometheus.NewCounter() // DefaultCoarseMux is a drop-in replacement for http.DefaultServeMux that // provides standardized telemetry for Go's standard HTTP handler registration @@ -103,9 +102,9 @@ func HandleFunc(pattern string, handler http.HandlerFunc) { } func init() { - registry.Register("http_requests_total", "A counter of the total number of HTTP requests made against the default multiplexor.", registry.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) - registry.Register("http_request_durations_microseconds", "The amounts of time the default multiplexor has spent answering HTTP requests (microseconds).", registry.NilLabels, requestDurations) - registry.Register("http_request_bytes_total", "The total volume of content body sizes received (bytes).", registry.NilLabels, requestBytes) - registry.Register("http_response_bytes_total", "The total volume of response payloads emitted (bytes).", registry.NilLabels, responseBytes) + prometheus.Register("http_requests_total", "A counter of the total number of HTTP requests made against the default multiplexor.", prometheus.NilLabels, requestCounts) + prometheus.Register("http_request_durations_total_microseconds", "The total amount of time the default multiplexor has spent answering HTTP requests (microseconds).", prometheus.NilLabels, requestDuration) + prometheus.Register("http_request_durations_microseconds", "The amounts of time the default multiplexor has spent answering HTTP requests (microseconds).", prometheus.NilLabels, requestDurations) + prometheus.Register("http_request_bytes_total", "The total volume of content body sizes received (bytes).", prometheus.NilLabels, requestBytes) + prometheus.Register("http_response_bytes_total", "The total volume of response payloads emitted (bytes).", prometheus.NilLabels, responseBytes) } diff --git a/exp/documentation.go b/prometheus/exp/documentation.go similarity index 91% rename from exp/documentation.go rename to prometheus/exp/documentation.go index 7d358ca..9268a78 100644 --- a/exp/documentation.go +++ b/prometheus/exp/documentation.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013, Matt T. Proud +// 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 diff --git a/exp/responsewriter_delegator.go b/prometheus/exp/responsewriter_delegator.go similarity index 98% rename from exp/responsewriter_delegator.go rename to prometheus/exp/responsewriter_delegator.go index c92ec46..3f0b694 100644 --- a/exp/responsewriter_delegator.go +++ b/prometheus/exp/responsewriter_delegator.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013, Matt T. Proud +// 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 diff --git a/metrics/gauge.go b/prometheus/gauge.go similarity index 93% rename from metrics/gauge.go rename to prometheus/gauge.go index 7ea05c2..e5f6553 100644 --- a/metrics/gauge.go +++ b/prometheus/gauge.go @@ -1,14 +1,13 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 metrics +package prometheus import ( "fmt" - "github.com/prometheus/client_golang/utility" "sync" ) @@ -56,7 +55,7 @@ func (metric *gauge) Set(labels map[string]string, value float64) float64 { labels = map[string]string{} } - signature := utility.LabelsToSignature(labels) + signature := labelsToSignature(labels) if original, ok := metric.values[signature]; ok { original.value = value diff --git a/metrics/gauge_test.go b/prometheus/gauge_test.go similarity index 94% rename from metrics/gauge_test.go rename to prometheus/gauge_test.go index 5bc6c8f..8e7e5f1 100644 --- a/metrics/gauge_test.go +++ b/prometheus/gauge_test.go @@ -1,18 +1,17 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 metrics +package prometheus import ( "encoding/json" - "github.com/prometheus/client_golang/utility/test" "testing" ) -func testGauge(t test.Tester) { +func testGauge(t tester) { type input struct { steps []func(g Gauge) } diff --git a/maths/helpers_for_testing.go b/prometheus/helpers_for_testing.go similarity index 93% rename from maths/helpers_for_testing.go rename to prometheus/helpers_for_testing.go index aac7951..76dd5df 100644 --- a/maths/helpers_for_testing.go +++ b/prometheus/helpers_for_testing.go @@ -1,10 +1,10 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 maths +package prometheus import ( . "github.com/matttproud/gocheck" diff --git a/metrics/histogram.go b/prometheus/histogram.go similarity index 97% rename from metrics/histogram.go rename to prometheus/histogram.go index 8420998..ca3ce93 100644 --- a/metrics/histogram.go +++ b/prometheus/histogram.go @@ -1,16 +1,14 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 metrics +package prometheus import ( "bytes" "fmt" - "github.com/prometheus/client_golang/maths" - "github.com/prometheus/client_golang/utility" "math" "strconv" "sync" @@ -96,7 +94,7 @@ func (h *histogram) Add(labels map[string]string, value float64) { labels = map[string]string{} } - signature := utility.LabelsToSignature(labels) + signature := labelsToSignature(labels) var histogram *histogramVector = nil if original, ok := h.values[signature]; ok { histogram = original @@ -298,7 +296,7 @@ func NewDefaultHistogram() Histogram { return NewHistogram( &HistogramSpecification{ 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}, }, ) diff --git a/metrics/histogram_test.go b/prometheus/histogram_test.go similarity index 75% rename from metrics/histogram_test.go rename to prometheus/histogram_test.go index 5171059..acb3be3 100644 --- a/metrics/histogram_test.go +++ b/prometheus/histogram_test.go @@ -1,9 +1,9 @@ -// Copyright (c) 2013, Matt T. Proud +// 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 metrics +package prometheus // TODO(matt): Re-Add tests for this type. diff --git a/utility/test/interface.go b/prometheus/interface.go similarity index 77% rename from utility/test/interface.go rename to prometheus/interface.go index de30938..9b5de19 100644 --- a/utility/test/interface.go +++ b/prometheus/interface.go @@ -1,12 +1,12 @@ -// Copyright (c) 2013, Matt T. Proud +// 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 test +package prometheus -type Tester interface { +type tester interface { Error(args ...interface{}) Errorf(format string, args ...interface{}) Fatal(args ...interface{}) diff --git a/metrics/metric.go b/prometheus/metric.go similarity index 89% rename from metrics/metric.go rename to prometheus/metric.go index 65a1b6f..9753130 100644 --- a/metrics/metric.go +++ b/prometheus/metric.go @@ -1,10 +1,10 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 metrics +package prometheus // A Metric is something that can be exposed via the registry framework. type Metric interface { diff --git a/utility/priority_queue.go b/prometheus/priority_queue.go similarity index 61% rename from utility/priority_queue.go rename to prometheus/priority_queue.go index 36ebd64..0f43b68 100644 --- a/utility/priority_queue.go +++ b/prometheus/priority_queue.go @@ -1,44 +1,44 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 utility +package prometheus -type Item struct { +type item struct { Priority int64 Value interface{} index int } -type PriorityQueue []*Item +type priorityQueue []*item -func (q PriorityQueue) Len() int { +func (q priorityQueue) Len() int { 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 } -func (q PriorityQueue) Swap(i, j int) { +func (q priorityQueue) Swap(i, j int) { q[i], q[j] = q[j], q[i] q[i].index = i q[j].index = j } -func (q *PriorityQueue) Push(x interface{}) { +func (q *priorityQueue) Push(x interface{}) { queue := *q size := len(queue) queue = queue[0 : size+1] - item := x.(*Item) + item := x.(*item) item.index = size queue[size] = item *q = queue } -func (q *PriorityQueue) Pop() interface{} { +func (q *priorityQueue) Pop() interface{} { queue := *q size := len(queue) item := queue[size-1] diff --git a/utility/priority_queue_test.go b/prometheus/priority_queue_test.go similarity index 58% rename from utility/priority_queue_test.go rename to prometheus/priority_queue_test.go index 0f66a1a..63b5288 100644 --- a/utility/priority_queue_test.go +++ b/prometheus/priority_queue_test.go @@ -1,10 +1,10 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 utility +package prometheus import ( "container/heap" @@ -12,16 +12,16 @@ import ( ) func (s *S) TestPriorityQueueSort(c *C) { - q := make(PriorityQueue, 0, 6) + q := make(priorityQueue, 0, 6) c.Check(len(q), Equals, 0) - heap.Push(&q, &Item{Value: "newest", Priority: -100}) - heap.Push(&q, &Item{Value: "older", Priority: 90}) - heap.Push(&q, &Item{Value: "oldest", Priority: 100}) - heap.Push(&q, &Item{Value: "newer", Priority: -90}) - heap.Push(&q, &Item{Value: "new", Priority: -80}) - heap.Push(&q, &Item{Value: "old", Priority: 80}) + heap.Push(&q, &item{Value: "newest", Priority: -100}) + heap.Push(&q, &item{Value: "older", Priority: 90}) + heap.Push(&q, &item{Value: "oldest", Priority: 100}) + heap.Push(&q, &item{Value: "newer", Priority: -90}) + heap.Push(&q, &item{Value: "new", Priority: -80}) + heap.Push(&q, &item{Value: "old", Priority: 80}) c.Check(len(q), Equals, 6) diff --git a/metrics/metrics_test.go b/prometheus/prometheus_test.go similarity index 72% rename from metrics/metrics_test.go rename to prometheus/prometheus_test.go index a2a81ae..a5de18a 100644 --- a/metrics/metrics_test.go +++ b/prometheus/prometheus_test.go @@ -1,10 +1,10 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 metrics +package prometheus import ( . "github.com/matttproud/gocheck" @@ -15,6 +15,6 @@ type S struct{} var _ = Suite(&S{}) -func TestMetrics(t *testing.T) { +func TestPrometheus(t *testing.T) { TestingT(t) } diff --git a/registry.go b/prometheus/registry.go similarity index 94% rename from registry.go rename to prometheus/registry.go index 8c77310..28ab774 100644 --- a/registry.go +++ b/prometheus/registry.go @@ -1,10 +1,10 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 registry +package prometheus import ( "compress/gzip" @@ -12,8 +12,6 @@ import ( "encoding/json" "flag" "fmt" - "github.com/prometheus/client_golang/metrics" - "github.com/prometheus/client_golang/utility" "io" "log" "net/http" @@ -46,7 +44,7 @@ var ( type container struct { baseLabels map[string]string docstring string - metric metrics.Metric + metric Metric name string } @@ -61,7 +59,7 @@ type registry struct { // own. type Registry interface { // 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 // against it generate a representation of the housed metrics. Handler() http.HandlerFunc @@ -79,7 +77,7 @@ func NewRegistry() Registry { } // 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) } @@ -110,7 +108,7 @@ func (r registry) isValidCandidate(name string, baseLabels map[string]string) (s } baseLabels[nameLabel] = name - signature = utility.LabelsToSignature(baseLabels) + signature = labelsToSignature(baseLabels) if _, contains := r.signatureContainers[signature]; contains { 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 } -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() defer r.mutex.Unlock() @@ -271,7 +269,7 @@ func (registry registry) YieldExporter() http.HandlerFunc { func (registry registry) Handler() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var instrumentable metrics.InstrumentableCall = func() { + var instrumentable InstrumentableCall = func() { requestCount.Increment(nil) url := r.URL @@ -293,7 +291,7 @@ func (registry registry) Handler() http.HandlerFunc { } } - metrics.InstrumentCall(instrumentable, requestLatencyAccumulator) + InstrumentCall(instrumentable, requestLatencyAccumulator) } } diff --git a/registry_test.go b/prometheus/registry_test.go similarity index 92% rename from registry_test.go rename to prometheus/registry_test.go index 175c3a0..df0f1c2 100644 --- a/registry_test.go +++ b/prometheus/registry_test.go @@ -1,22 +1,20 @@ -// Copyright (c) 2013, Matt T. Proud +// 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 registry +package prometheus import ( "bytes" "fmt" - "github.com/prometheus/client_golang/metrics" - "github.com/prometheus/client_golang/utility/test" "io" "net/http" "testing" ) -func testRegister(t test.Tester) { +func testRegister(t tester) { var oldState = struct { abortOnMisuse bool debugRegistration bool @@ -181,7 +179,7 @@ func (r *fakeResponseWriter) Write(d []byte) (l int, err error) { func (r *fakeResponseWriter) WriteHeader(c int) { } -func testDecorateWriter(t test.Tester) { +func testDecorateWriter(t tester) { type input struct { headers map[string]string body []byte @@ -266,9 +264,9 @@ func BenchmarkDecorateWriter(b *testing.B) { } } -func testDumpToWriter(t test.Tester) { +func testDumpToWriter(t tester) { type input struct { - metrics map[string]metrics.Metric + metrics map[string]Metric } var scenarios = []struct { @@ -280,17 +278,17 @@ func testDumpToWriter(t test.Tester) { }, { in: input{ - metrics: map[string]metrics.Metric{ - "foo": metrics.NewCounter(), + metrics: map[string]Metric{ + "foo": NewCounter(), }, }, out: []byte("[{\"baseLabels\":{\"label_foo\":\"foo\",\"name\":\"foo\"},\"docstring\":\"metric foo\",\"metric\":{\"type\":\"counter\",\"value\":[]}}]"), }, { in: input{ - metrics: map[string]metrics.Metric{ - "foo": metrics.NewCounter(), - "bar": metrics.NewCounter(), + metrics: map[string]Metric{ + "foo": 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\":[]}}]"), diff --git a/utility/signature.go b/prometheus/signature.go similarity index 87% rename from utility/signature.go rename to prometheus/signature.go index 610af73..237170d 100644 --- a/utility/signature.go +++ b/prometheus/signature.go @@ -1,10 +1,10 @@ -// Copyright (c) 2013, Matt T. Proud +// 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 utility +package prometheus import ( "bytes" @@ -17,7 +17,7 @@ const ( // LabelsToSignature provides a way of building a unique signature // (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 // do not occur in less-than-diligent environments. cardinality := len(labels) diff --git a/utility/signature_test.go b/prometheus/signature_test.go similarity index 75% rename from utility/signature_test.go rename to prometheus/signature_test.go index 1f924fc..f544237 100644 --- a/utility/signature_test.go +++ b/prometheus/signature_test.go @@ -1,17 +1,16 @@ -// Copyright (c) 2013, Matt T. Proud +// 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 utility +package prometheus import ( - "github.com/prometheus/client_golang/utility/test" "testing" ) -func testLabelsToSignature(t test.Tester) { +func testLabelsToSignature(t tester) { var scenarios = []struct { in map[string]string out string @@ -24,7 +23,7 @@ func testLabelsToSignature(t test.Tester) { } for i, scenario := range scenarios { - actual := LabelsToSignature(scenario.in) + actual := labelsToSignature(scenario.in) if actual != scenario.out { t.Errorf("%d. expected %s, got %s", i, scenario.out, actual) diff --git a/maths/statistics.go b/prometheus/statistics.go similarity index 63% rename from maths/statistics.go rename to prometheus/statistics.go index 6e190c0..a419224 100644 --- a/maths/statistics.go +++ b/prometheus/statistics.go @@ -1,10 +1,10 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 maths +package prometheus import ( "math" @@ -14,11 +14,32 @@ import ( // TODO(mtp): Split this out into a summary statistics file once moving/rolling // averages are calculated. -// ReductionMethod provides a method for reducing metrics into a given scalar -// value. +// ReductionMethod provides a method for reducing metrics into a scalar value. 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 sum := 0.0 @@ -34,11 +55,10 @@ var Average ReductionMethod = func(input []float64) float64 { return sum / count } -// Extract the first modal value. -var FirstMode ReductionMethod = func(input []float64) float64 { +func firstModeReducer(input []float64) float64 { valuesToFrequency := map[float64]int64{} - var largestTally int64 = math.MinInt64 - var largestTallyValue float64 = math.NaN() + largestTally := int64(math.MinInt64) + largestTallyValue := math.NaN() for _, v := range input { presentCount, _ := valuesToFrequency[v] @@ -56,7 +76,7 @@ var FirstMode ReductionMethod = func(input []float64) float64 { } // 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) 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. func NearestRankReducer(percentile float64) ReductionMethod { return func(input []float64) float64 { - return NearestRank(input, percentile) + return nearestRank(input, percentile) } } -var Median ReductionMethod = NearestRankReducer(50) - -var Minimum ReductionMethod = func(input []float64) float64 { - var minimum float64 = math.MaxFloat64 +func minimumReducer(input []float64) float64 { + minimum := math.MaxFloat64 for _, v := range input { minimum = math.Min(minimum, v) @@ -97,8 +115,8 @@ var Minimum ReductionMethod = func(input []float64) float64 { return minimum } -var Maximum ReductionMethod = func(input []float64) float64 { - var maximum float64 = math.SmallestNonzeroFloat64 +func maximumReducer(input []float64) float64 { + maximum := math.SmallestNonzeroFloat64 for _, v := range input { maximum = math.Max(maximum, v) diff --git a/maths/statistics_test.go b/prometheus/statistics_test.go similarity index 56% rename from maths/statistics_test.go rename to prometheus/statistics_test.go index b17e980..8b64ce0 100644 --- a/maths/statistics_test.go +++ b/prometheus/statistics_test.go @@ -1,10 +1,10 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 maths +package prometheus import ( . "github.com/matttproud/gocheck" @@ -12,42 +12,42 @@ import ( func (s *S) TestAverageOnEmpty(c *C) { empty := []float64{} - var v float64 = Average(empty) + var v float64 = AverageReducer(empty) c.Assert(v, IsNaN) } func (s *S) TestAverageForSingleton(c *C) { input := []float64{5} - var v float64 = Average(input) + var v float64 = AverageReducer(input) c.Check(v, Equals, 5.0) } func (s *S) TestAverage(c *C) { input := []float64{5, 15} - var v float64 = Average(input) + var v float64 = AverageReducer(input) c.Check(v, Equals, 10.0) } func (s *S) TestFirstModeOnEmpty(c *C) { input := []float64{} - var v float64 = FirstMode(input) + var v float64 = FirstModeReducer(input) c.Assert(v, IsNaN) } func (s *S) TestFirstModeForSingleton(c *C) { input := []float64{5} - var v float64 = FirstMode(input) + var v float64 = FirstModeReducer(input) c.Check(v, Equals, 5.0) } func (s *S) TestFirstModeForUnimodal(c *C) { input := []float64{1, 2, 3, 4, 3} - var v float64 = FirstMode(input) + var v float64 = FirstModeReducer(input) c.Check(v, Equals, 3.0) } @@ -55,25 +55,25 @@ func (s *S) TestFirstModeForUnimodal(c *C) { func (s *S) TestNearestRankForEmpty(c *C) { input := []float64{} - c.Assert(NearestRank(input, 0), IsNaN) - c.Assert(NearestRank(input, 50), IsNaN) - c.Assert(NearestRank(input, 100), IsNaN) + c.Assert(nearestRank(input, 0), IsNaN) + c.Assert(nearestRank(input, 50), IsNaN) + c.Assert(nearestRank(input, 100), IsNaN) } func (s *S) TestNearestRankForSingleton(c *C) { input := []float64{5} - c.Check(NearestRank(input, 0), Equals, 5.0) - c.Check(NearestRank(input, 50), Equals, 5.0) - c.Check(NearestRank(input, 100), Equals, 5.0) + c.Check(nearestRank(input, 0), Equals, 5.0) + c.Check(nearestRank(input, 50), Equals, 5.0) + c.Check(nearestRank(input, 100), Equals, 5.0) } func (s *S) TestNearestRankForDouble(c *C) { input := []float64{5, 5} - c.Check(NearestRank(input, 0), Equals, 5.0) - c.Check(NearestRank(input, 50), Equals, 5.0) - c.Check(NearestRank(input, 100), Equals, 5.0) + c.Check(nearestRank(input, 0), Equals, 5.0) + c.Check(nearestRank(input, 50), Equals, 5.0) + c.Check(nearestRank(input, 100), Equals, 5.0) } func (s *S) TestNearestRankFor100(c *C) { @@ -83,9 +83,9 @@ func (s *S) TestNearestRankFor100(c *C) { input[i] = float64(i + 1) } - c.Check(NearestRank(input, 0), Equals, 1.0) - c.Check(NearestRank(input, 50), Equals, 51.0) - c.Check(NearestRank(input, 100), Equals, 100.0) + c.Check(nearestRank(input, 0), Equals, 1.0) + c.Check(nearestRank(input, 50), Equals, 51.0) + c.Check(nearestRank(input, 100), Equals, 100.0) } func (s *S) TestNearestRankFor101(c *C) { @@ -95,25 +95,25 @@ func (s *S) TestNearestRankFor101(c *C) { input[i] = float64(i + 1) } - c.Check(NearestRank(input, 0), Equals, 1.0) - c.Check(NearestRank(input, 50), Equals, 51.0) - c.Check(NearestRank(input, 100), Equals, 101.0) + c.Check(nearestRank(input, 0), Equals, 1.0) + c.Check(nearestRank(input, 50), Equals, 51.0) + c.Check(nearestRank(input, 100), Equals, 101.0) } func (s *S) TestMedianReducer(c *C) { 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) { 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) { input := []float64{5, 1, 10, 1.1, 4} - c.Check(Maximum(input), Equals, 10.0) + c.Check(MaximumReducer(input), Equals, 10.0) } diff --git a/metrics/tallying_bucket.go b/prometheus/tallying_bucket.go similarity index 68% rename from metrics/tallying_bucket.go rename to prometheus/tallying_bucket.go index bbc6d9d..7ef1137 100644 --- a/metrics/tallying_bucket.go +++ b/prometheus/tallying_bucket.go @@ -1,14 +1,13 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 metrics +package prometheus import ( "fmt" - "github.com/prometheus/client_golang/maths" "math" "sync" ) @@ -35,38 +34,49 @@ func emptyFilter(e TallyingIndexEstimator) TallyingIndexEstimator { } } -// Report the smallest observed value in the bucket. -var Minimum TallyingIndexEstimator = 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 { +var ( + minimumEstimator = emptyFilter(func(minimum, maximum float64, _, observations int) float64 { return minimum - } + }) - location := float64(index) / float64(observations) - - if location > upperThird { + maximumEstimator = emptyFilter(func(minimum, maximum float64, _, observations int) float64 { 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. // 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. func DefaultTallyingBucket() TallyingBucket { return TallyingBucket{ - estimator: Minimum, + estimator: MinimumEstimator, largestObserved: math.SmallestNonzeroFloat64, smallestObserved: math.MaxFloat64, } diff --git a/metrics/tallying_bucket_test.go b/prometheus/tallying_bucket_test.go similarity index 62% rename from metrics/tallying_bucket_test.go rename to prometheus/tallying_bucket_test.go index 6f1048d..f674d5f 100644 --- a/metrics/tallying_bucket_test.go +++ b/prometheus/tallying_bucket_test.go @@ -1,40 +1,39 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 metrics +package prometheus import ( . "github.com/matttproud/gocheck" - "github.com/prometheus/client_golang/maths" ) func (s *S) TestTallyingPercentileEstimatorMinimum(c *C) { - c.Assert(Minimum(-2, -1, 0, 0), maths.IsNaN) - c.Check(Minimum(-2, -1, 0, 1), Equals, -2.0) + c.Assert(MinimumEstimator(-2, -1, 0, 0), IsNaN) + c.Check(MinimumEstimator(-2, -1, 0, 1), Equals, -2.0) } func (s *S) TestTallyingPercentileEstimatorMaximum(c *C) { - c.Assert(Maximum(-2, -1, 0, 0), maths.IsNaN) - c.Check(Maximum(-2, -1, 0, 1), Equals, -1.0) + c.Assert(MaximumEstimator(-2, -1, 0, 0), IsNaN) + c.Check(MaximumEstimator(-2, -1, 0, 1), Equals, -1.0) } func (s *S) TestTallyingPercentilesEstimatorAverage(c *C) { - c.Assert(Average(-2, -1, 0, 0), maths.IsNaN) - c.Check(Average(-2, -2, 0, 1), Equals, -2.0) - c.Check(Average(-1, -1, 0, 1), Equals, -1.0) - c.Check(Average(1, 1, 0, 2), Equals, 1.0) - c.Check(Average(2, 1, 0, 2), Equals, 1.5) + c.Assert(AverageEstimator(-2, -1, 0, 0), IsNaN) + c.Check(AverageEstimator(-2, -2, 0, 1), Equals, -2.0) + c.Check(AverageEstimator(-1, -1, 0, 1), Equals, -1.0) + c.Check(AverageEstimator(1, 1, 0, 2), Equals, 1.0) + c.Check(AverageEstimator(2, 1, 0, 2), Equals, 1.5) } 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(Uniform(-5, 5, 1, 2), Equals, 0.0) - c.Check(Uniform(-5, 5, 2, 2), Equals, 5.0) + c.Check(UniformEstimator(-5, 5, 0, 2), Equals, -5.0) + c.Check(UniformEstimator(-5, 5, 1, 2), Equals, 0.0) + c.Check(UniformEstimator(-5, 5, 2, 2), Equals, 5.0) } func (s *S) TestTallyingBucketBuilder(c *C) { diff --git a/telemetry.go b/prometheus/telemetry.go similarity index 64% rename from telemetry.go rename to prometheus/telemetry.go index 8ce1a6f..3cfa3fb 100644 --- a/telemetry.go +++ b/prometheus/telemetry.go @@ -1,15 +1,13 @@ -// Copyright (c) 2013, Matt T. Proud +// 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 registry +package prometheus import ( - "github.com/prometheus/client_golang/maths" - "github.com/prometheus/client_golang/metrics" "time" ) @@ -17,18 +15,18 @@ import ( // exposed if the DefaultRegistry's exporter is hooked into the HTTP request // handler. var ( - marshalErrorCount = metrics.NewCounter() - dumpErrorCount = metrics.NewCounter() + marshalErrorCount = NewCounter() + dumpErrorCount = NewCounter() - requestCount = metrics.NewCounter() - requestLatencyBuckets = metrics.LogarithmicSizedBucketsFor(0, 1000) - requestLatency = metrics.NewHistogram(&metrics.HistogramSpecification{ + requestCount = NewCounter() + requestLatencyBuckets = LogarithmicSizedBucketsFor(0, 1000) + requestLatency = NewHistogram(&HistogramSpecification{ 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}, }) - startTime = metrics.NewGauge() + startTime = NewGauge() ) func init() { @@ -42,7 +40,7 @@ func init() { // This callback accumulates the microsecond duration of the reporting // 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) requestLatency.Add(nil, microseconds) diff --git a/utility/test_helper.go b/prometheus/test_helper.go similarity index 84% rename from utility/test_helper.go rename to prometheus/test_helper.go index b3d8f7d..b5bd488 100644 --- a/utility/test_helper.go +++ b/prometheus/test_helper.go @@ -1,10 +1,10 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 utility +package prometheus import ( . "github.com/matttproud/gocheck" @@ -19,7 +19,7 @@ var ValueEquals Checker = &valueEqualsChecker{ } 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] return actual == expected, "" diff --git a/metrics/timer.go b/prometheus/timer.go similarity index 96% rename from metrics/timer.go rename to prometheus/timer.go index 491d132..aa1ff92 100644 --- a/metrics/timer.go +++ b/prometheus/timer.go @@ -1,10 +1,10 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 metrics +package prometheus import ( "time" diff --git a/metrics/timer_test.go b/prometheus/timer_test.go similarity index 95% rename from metrics/timer_test.go rename to prometheus/timer_test.go index d3b12e1..e9dab08 100644 --- a/metrics/timer_test.go +++ b/prometheus/timer_test.go @@ -1,10 +1,10 @@ -// Copyright (c) 2012, Matt T. Proud +// 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 metrics +package prometheus import ( . "github.com/matttproud/gocheck" diff --git a/utility/documentation.go b/utility/documentation.go deleted file mode 100644 index 7b9628f..0000000 --- a/utility/documentation.go +++ /dev/null @@ -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 diff --git a/utility/utility_test.go b/utility/utility_test.go deleted file mode 100644 index 17244b1..0000000 --- a/utility/utility_test.go +++ /dev/null @@ -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) -}