From 6c3a2ddddbee689c020166a452a82ce31a5ba1ff Mon Sep 17 00:00:00 2001 From: "Matt T. Proud" Date: Tue, 12 Feb 2013 02:36:06 +0100 Subject: [PATCH] Sundry cosmetic fixes across the board. - Comments are migrated from ``/* */`` to ``//`` per convention. - ``NewDefaultHistogram`` helper. - ``Registry.Handler`` and ``Registry.YieldExporter`` deprecation. - Cleanup of legacy import paths. - Updating examples to use acknowledged patterns. - Parameterizing the random parameter namespaces for ``examples/random/main.go``, which is useful for demoing population behaviors. --- constants.go | 6 +- documentation.go | 80 +++++++------- examples/random/main.go | 83 ++++++++------ examples/simple/main.go | 22 ++-- maths/distributions.go | 24 ++--- maths/documentation.go | 34 +++--- maths/helpers_for_testing.go | 18 ++-- maths/maths_test.go | 12 +-- maths/statistics.go | 36 +++---- maths/statistics_test.go | 12 +-- metrics/accumulating_bucket.go | 34 +++--- metrics/accumulating_bucket_test.go | 39 +++---- metrics/bucket.go | 56 ++++------ metrics/constants.go | 16 ++- metrics/counter.go | 24 ++--- metrics/counter_test.go | 12 +-- metrics/documentation.go | 67 ++++++------ metrics/eviction.go | 35 +++--- metrics/eviction_test.go | 12 +-- metrics/gauge.go | 30 +++--- metrics/gauge_test.go | 12 +-- metrics/histogram.go | 162 ++++++++++++---------------- metrics/metrics_test.go | 12 +-- metrics/tallying_bucket.go | 62 ++++------- metrics/tallying_bucket_test.go | 14 ++- metrics/timer.go | 48 +++------ metrics/timer_test.go | 12 +-- registry.go | 72 +++++-------- registry_test.go | 4 +- telemetry.go | 29 ++--- utility/documentation.go | 30 +++--- utility/priority_queue.go | 10 +- utility/priority_queue_test.go | 12 +-- utility/test_helper.go | 12 +-- utility/utility_test.go | 12 +-- 35 files changed, 492 insertions(+), 663 deletions(-) diff --git a/constants.go b/constants.go index 3dfaead..297ad30 100644 --- a/constants.go +++ b/constants.go @@ -1,8 +1,8 @@ // 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. +// Use of this source code is governed by a BSD-style license that can be found +// in the LICENSE file. package registry @@ -19,6 +19,8 @@ var ( ProtocolVersionHeader = "X-Prometheus-API-Version" + ExpositionResource = "/metrics.json" + baseLabelsKey = "baseLabels" docstringKey = "docstring" metricKey = "metric" diff --git a/documentation.go b/documentation.go index eb8ca81..f368048 100644 --- a/documentation.go +++ b/documentation.go @@ -1,54 +1,52 @@ -/* -Copyright (c) 2012, Matt T. Proud -All rights reserved. +// 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. -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.go provides a container for centralized exposition of metrics to -their prospective consumers. +// registry.Register("human_readable_metric_name", metric) - registry.Register("human_readable_metric_name", metric) +// Please try to observe the following rules when naming metrics: -Please try to observe the following rules when naming metrics: +// - Use underbars "_" to separate words. -- 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 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". -- 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. -- 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". -- 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. -- 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: -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. -- 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. -*/ +// - 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 registry diff --git a/examples/random/main.go b/examples/random/main.go index f6ad084..33e0a67 100644 --- a/examples/random/main.go +++ b/examples/random/main.go @@ -1,19 +1,15 @@ -/* -Copyright (c) 2012, Matt T. Proud -All rights reserved. +// 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. -Use of this source code is governed by a BSD-style -license that can be found in the LICENSE file. -*/ - -/* -main.go provides a simple example of how to use this instrumentation -framework in the context of having something that emits values into -its collectors. - -The emitted values correspond to uniform, normal, and exponential -distributions. -*/ +// main.go provides a simple example of how to use this instrumentation +// framework in the context of having something that emits values into +// its collectors. +// +// The emitted values correspond to uniform, normal, and exponential +// distributions. package main import ( @@ -28,34 +24,52 @@ import ( var ( listeningAddress string + + barDomain float64 + barMean float64 + fooDomain float64 + + // Create a histogram to track fictitious interservice RPC latency for three + // distinct services. + rpc_latency = metrics.NewHistogram(&metrics.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), + // 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), + // The histogram reports percentiles 1, 5, 50, 90, and 99. + ReportablePercentiles: []float64{0.01, 0.05, 0.5, 0.90, 0.99}, + }) + + rpc_calls = metrics.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() ) func init() { flag.StringVar(&listeningAddress, "listeningAddress", ":8080", "The address to listen to requests on.") + flag.Float64Var(&fooDomain, "random.fooDomain", 200, "The domain for the random parameter foo.") + flag.Float64Var(&barDomain, "random.barDomain", 10, "The domain for the random parameter bar.") + flag.Float64Var(&barMean, "random.barMean", 100, "The mean for the random parameter bar.") } func main() { flag.Parse() - rpc_latency := metrics.NewHistogram(&metrics.HistogramSpecification{ - Starts: metrics.EquallySizedBucketsFor(0, 200, 4), - BucketBuilder: metrics.AccumulatingBucketBuilder(metrics.EvictAndReplaceWith(10, maths.Average), 50), - ReportablePercentiles: []float64{0.01, 0.05, 0.5, 0.90, 0.99}, - }) - - rpc_calls := metrics.NewCounter() - - metrics := registry.NewRegistry() - - metrics.Register("rpc_latency_microseconds", "RPC latency.", registry.NilLabels, rpc_latency) - metrics.Register("rpc_calls_total", "RPC calls.", registry.NilLabels, rpc_calls) - go func() { for { - rpc_latency.Add(map[string]string{"service": "foo"}, rand.Float64()*200) + rpc_latency.Add(map[string]string{"service": "foo"}, rand.Float64()*fooDomain) rpc_calls.Increment(map[string]string{"service": "foo"}) - rpc_latency.Add(map[string]string{"service": "bar"}, (rand.NormFloat64()*10.0)+100.0) + rpc_latency.Add(map[string]string{"service": "bar"}, (rand.NormFloat64()*barDomain)+barMean) rpc_calls.Increment(map[string]string{"service": "bar"}) rpc_latency.Add(map[string]string{"service": "zed"}, rand.ExpFloat64()) @@ -65,8 +79,11 @@ func main() { } }() - exporter := metrics.YieldExporter() - - http.Handle("/metrics.json", exporter) + http.Handle(registry.ExpositionResource, customRegistry.Handler()) http.ListenAndServe(listeningAddress, nil) } + +func init() { + customRegistry.Register("rpc_latency_microseconds", "RPC latency.", registry.NilLabels, rpc_latency) + customRegistry.Register("rpc_calls_total", "RPC calls.", registry.NilLabels, rpc_calls) +} diff --git a/examples/simple/main.go b/examples/simple/main.go index 06f4830..8f66bd0 100644 --- a/examples/simple/main.go +++ b/examples/simple/main.go @@ -1,15 +1,11 @@ -/* -Copyright (c) 2012, Matt T. Proud -All rights reserved. +// 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. -Use of this source code is governed by a BSD-style -license that can be found in the LICENSE file. -*/ - -/* -main.go provides a simple skeletal example of how this instrumentation -framework is registered and invoked. -*/ +// main.go provides a simple skeletal example of how this instrumentation +// framework is registered and invoked. package main import ( @@ -29,8 +25,6 @@ func init() { func main() { flag.Parse() - exporter := registry.DefaultRegistry.YieldExporter() - - http.Handle("/metrics.json", exporter) + http.Handle(registry.ExpositionResource, registry.DefaultHandler) http.ListenAndServe(listeningAddress, nil) } diff --git a/maths/distributions.go b/maths/distributions.go index 5ca1711..50783c6 100644 --- a/maths/distributions.go +++ b/maths/distributions.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 @@ -12,9 +10,7 @@ import ( "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 { if of <= 0 { return 1 @@ -29,11 +25,9 @@ func Factorial(of int) int64 { return result } -/* -Create 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. -*/ +// 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)) intermediate := math.Pow(p, float64(k)) * math.Pow(1-p, float64(n-k)) diff --git a/maths/documentation.go b/maths/documentation.go index 375eb6f..76ba017 100644 --- a/maths/documentation.go +++ b/maths/documentation.go @@ -1,26 +1,22 @@ -/* -Copyright (c) 2012, Matt T. Proud -All rights reserved. +// 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. -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: -/* -The maths package provides a number of mathematical-related helpers: +// distributions.go provides basic distribution-generating functions that are +// used primarily in testing contexts. -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. -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. -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.go provides basic summary statistics functions for the purpose of -metrics aggregation. - -statistics_test.go provides a test complement for the statistics.go module. -*/ +// statistics_test.go provides a test complement for the statistics.go module. package maths diff --git a/maths/helpers_for_testing.go b/maths/helpers_for_testing.go index 57b8a38..aac7951 100644 --- a/maths/helpers_for_testing.go +++ b/maths/helpers_for_testing.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 @@ -18,10 +16,8 @@ type isNaNChecker struct { *CheckerInfo } -/* -This piece provides a simple tester for the gocheck testing library to -ascertain if a value is not-a-number. -*/ +// This piece provides a simple tester for the gocheck testing library to +// ascertain if a value is not-a-number. var IsNaN Checker = &isNaNChecker{ &CheckerInfo{Name: "IsNaN", Params: []string{"value"}}, } diff --git a/maths/maths_test.go b/maths/maths_test.go index 6bee219..4e5ff10 100644 --- a/maths/maths_test.go +++ b/maths/maths_test.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 diff --git a/maths/statistics.go b/maths/statistics.go index a837565..6e190c0 100644 --- a/maths/statistics.go +++ b/maths/statistics.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 @@ -13,15 +11,11 @@ import ( "sort" ) -/* -TODO(mtp): Split this out into a summary statistics file once moving/rolling - averages are calculated. -*/ +// 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 given scalar +// value. type ReductionMethod func([]float64) float64 var Average ReductionMethod = func(input []float64) float64 { @@ -40,9 +34,7 @@ var Average ReductionMethod = func(input []float64) float64 { return sum / count } -/* -Extract the first modal value. -*/ +// Extract the first modal value. var FirstMode ReductionMethod = func(input []float64) float64 { valuesToFrequency := map[float64]int64{} var largestTally int64 = math.MinInt64 @@ -63,9 +55,7 @@ var FirstMode ReductionMethod = func(input []float64) float64 { return largestTallyValue } -/* -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 { inputSize := len(input) @@ -88,9 +78,7 @@ func NearestRank(input []float64, percentile float64) float64 { return copiedInput[preliminaryIndex] } -/* -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 { return func(input []float64) float64 { return NearestRank(input, percentile) diff --git a/maths/statistics_test.go b/maths/statistics_test.go index 061c0b2..b17e980 100644 --- a/maths/statistics_test.go +++ b/maths/statistics_test.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 diff --git a/metrics/accumulating_bucket.go b/metrics/accumulating_bucket.go index 4c4a4ee..00b0cc4 100644 --- a/metrics/accumulating_bucket.go +++ b/metrics/accumulating_bucket.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 @@ -27,11 +25,9 @@ type AccumulatingBucket struct { observations int } -/* -AccumulatingBucketBuilder is a convenience method for generating a -BucketBuilder that produces AccumatingBucket entries with a certain -behavior set. -*/ +// AccumulatingBucketBuilder is a convenience method for generating a +// BucketBuilder that produces AccumatingBucket entries with a certain +// behavior set. func AccumulatingBucketBuilder(evictionPolicy EvictionPolicy, maximumSize int) BucketBuilder { return func() Bucket { return &AccumulatingBucket{ @@ -42,10 +38,8 @@ func AccumulatingBucketBuilder(evictionPolicy EvictionPolicy, maximumSize int) B } } -/* -Add a value to the bucket. Depending on whether the bucket is full, it may -trigger an eviction of older items. -*/ +// Add a value to the bucket. Depending on whether the bucket is full, it may +// trigger an eviction of older items. func (b *AccumulatingBucket) Add(value float64) { b.mutex.Lock() defer b.mutex.Unlock() @@ -100,11 +94,9 @@ func (b *AccumulatingBucket) ValueForIndex(index int) float64 { sort.Float64s(sortedElements) - /* - N.B.(mtp): Interfacing components should not need to comprehend what - eviction and storage container strategies used; therefore, - we adjust this silently. - */ + // N.B.(mtp): Interfacing components should not need to comprehend what + // eviction and storage container strategies used; therefore, + // we adjust this silently. targetIndex := int(float64(elementCount-1) * (float64(index) / float64(b.observations))) return sortedElements[targetIndex] diff --git a/metrics/accumulating_bucket_test.go b/metrics/accumulating_bucket_test.go index c97b256..789c682 100644 --- a/metrics/accumulating_bucket_test.go +++ b/metrics/accumulating_bucket_test.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 @@ -123,23 +121,18 @@ func (s *S) TestAccumulatingBucketValueForIndex(c *C) { c.Assert(b.ValueForIndex(i), maths.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. b.Add(1.0) c.Check(b.ValueForIndex(0), Equals, 1.0) - /* - Let's sanity check what occurs if presumably an eviction happened and - we requested an index larger than what is contained. - */ + // Let's sanity check what occurs if presumably an eviction happened and + // we requested an index larger than what is contained. c.Check(b.ValueForIndex(1), Equals, 1.0) for i := 2.0; i <= 100; i += 1 { b.Add(i) - /* - TODO(mtp): This is a sin. Provide a mechanism for deterministic testing. - */ + + // TODO(mtp): This is a sin. Provide a mechanism for deterministic testing. time.Sleep(1 * time.Millisecond) } @@ -149,17 +142,13 @@ func (s *S) TestAccumulatingBucketValueForIndex(c *C) { for i := 101.0; i <= 150; i += 1 { b.Add(i) - /* - TODO(mtp): This is a sin. Provide a mechanism for deterministic testing. - */ + // TODO(mtp): This is a sin. Provide a mechanism for deterministic testing. time.Sleep(1 * time.Millisecond) } - /* - The bucket's capacity has been exceeded by inputs at this point; - consequently, we search for a given element by percentage offset - therein. - */ + // The bucket's capacity has been exceeded by inputs at this point; + // consequently, we search for a given element by percentage offset + // therein. c.Check(b.ValueForIndex(0), Equals, 51.0) c.Check(b.ValueForIndex(50), Equals, 84.0) c.Check(b.ValueForIndex(99), Equals, 116.0) diff --git a/metrics/bucket.go b/metrics/bucket.go index 577a2c1..d4a8414 100644 --- a/metrics/bucket.go +++ b/metrics/bucket.go @@ -1,49 +1,33 @@ -/* -Copyright (c) 2012, Matt T. Proud -All rights reserved. +// 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. -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. -*/ +// bucket.go provides fundamental interface expectations for various bucket +// 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 -/* -This defines the base Bucket type. The exact behaviors of the bucket are -at the whim of the implementor. - -A Bucket is used as a container by Histogram as a collection for its -accumulated samples. -*/ +// This defines the base Bucket type. The exact behaviors of the bucket are +// at the whim of the implementor. +// +// A Bucket is used as a container by Histogram as a collection for its +// accumulated samples. type Bucket interface { - /* - Add a value to the bucket. - */ + // Add a value to the bucket. Add(value float64) - /* - Provide a count of observations throughout the bucket's lifetime. - */ + // Provide a count of observations throughout the bucket's lifetime. Observations() int // Reset is responsible for resetting this bucket back to a pristine state. Reset() - /* - Provide a humanized representation hereof. - */ + // Provide a humanized representation hereof. String() string - /* - Provide the value from the given in-memory value cache or an estimate - thereof for the given index. The consumer of the bucket's data makes - no assumptions about the underlying storage mechanisms that the bucket - employs. - */ + // Provide the value from the given in-memory value cache or an estimate + // thereof for the given index. The consumer of the bucket's data makes + // no assumptions about the underlying storage mechanisms that the bucket + // employs. ValueForIndex(index int) float64 } diff --git a/metrics/constants.go b/metrics/constants.go index cd8d9cd..11c9a9b 100644 --- a/metrics/constants.go +++ b/metrics/constants.go @@ -1,14 +1,10 @@ -/* -Copyright (c) 2012, Matt T. Proud -All rights reserved. +// 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. -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. -*/ +// constants.go provides package-level constants for metrics. package metrics const ( diff --git a/metrics/counter.go b/metrics/counter.go index 06d0bcb..0aaf14d 100644 --- a/metrics/counter.go +++ b/metrics/counter.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 @@ -27,20 +25,20 @@ type Counter interface { String() string } -type counterValue struct { +type counterVector struct { labels map[string]string value float64 } func NewCounter() Counter { return &counter{ - values: map[string]*counterValue{}, + values: map[string]*counterVector{}, } } type counter struct { mutex sync.RWMutex - values map[string]*counterValue + values map[string]*counterVector } func (metric *counter) Set(labels map[string]string, value float64) float64 { @@ -55,7 +53,7 @@ func (metric *counter) Set(labels map[string]string, value float64) float64 { if original, ok := metric.values[signature]; ok { original.value = value } else { - metric.values[signature] = &counterValue{ + metric.values[signature] = &counterVector{ labels: labels, value: value, } @@ -97,7 +95,7 @@ func (metric *counter) IncrementBy(labels map[string]string, value float64) floa if original, ok := metric.values[signature]; ok { original.value += value } else { - metric.values[signature] = &counterValue{ + metric.values[signature] = &counterVector{ labels: labels, value: value, } @@ -122,7 +120,7 @@ func (metric *counter) DecrementBy(labels map[string]string, value float64) floa if original, ok := metric.values[signature]; ok { original.value -= value } else { - metric.values[signature] = &counterValue{ + metric.values[signature] = &counterVector{ labels: labels, value: -1 * value, } diff --git a/metrics/counter_test.go b/metrics/counter_test.go index 285d149..aa489e5 100644 --- a/metrics/counter_test.go +++ b/metrics/counter_test.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 diff --git a/metrics/documentation.go b/metrics/documentation.go index 4b850ec..8e60d61 100644 --- a/metrics/documentation.go +++ b/metrics/documentation.go @@ -1,51 +1,48 @@ -/* -Copyright (c) 2012, Matt T. Proud -All rights reserved. +// 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. -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. -/* -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.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. -accumulating_bucket_test.go provides a test complement for the -accumulating_bucket_go module. +// eviction.go provides several histogram bucket eviction strategies. -eviction.go provides several histogram bucket eviction strategies. +// eviction_test.go provides a test complement for the eviction.go module. -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.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. -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.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. -histogram_test.go provides a test complement for the histogram.go module. +// metric.go provides fundamental interface expectations for the various +// metrics. -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. -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.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. -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.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. -*/ +// timer_test.go provides a test complement for the timer.go module. package metrics diff --git a/metrics/eviction.go b/metrics/eviction.go index 997938f..904d08b 100644 --- a/metrics/eviction.go +++ b/metrics/eviction.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 @@ -15,16 +13,12 @@ import ( "time" ) -/* -EvictionPolicy implements some sort of garbage collection methodology for -an underlying heap.Interface. This is presently only used for -AccumulatingBucket. -*/ +// EvictionPolicy implements some sort of garbage collection methodology for +// an underlying heap.Interface. This is presently only used for +// AccumulatingBucket. type EvictionPolicy func(h heap.Interface) -/* -As the name implies, this evicts the oldest x objects from the heap. -*/ +// As the name implies, this evicts the oldest x objects from the heap. func EvictOldest(count int) EvictionPolicy { return func(h heap.Interface) { for i := 0; i < count; i++ { @@ -33,10 +27,8 @@ func EvictOldest(count int) EvictionPolicy { } } -/* -This factory produces an EvictionPolicy that applies some standardized -reduction methodology on the to-be-terminated values. -*/ +// 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 { return func(h heap.Interface) { oldValues := make([]float64, count) @@ -49,9 +41,8 @@ func EvictAndReplaceWith(count int, reducer maths.ReductionMethod) EvictionPolic heap.Push(h, &utility.Item{ Value: reduced, - /* - TODO(mtp): Parameterize the priority generation since these tools are useful. - */ + // TODO(mtp): Parameterize the priority generation since these tools are + // useful. Priority: -1 * time.Now().UnixNano(), }) } diff --git a/metrics/eviction_test.go b/metrics/eviction_test.go index 07b82d7..efc3e73 100644 --- a/metrics/eviction_test.go +++ b/metrics/eviction_test.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 diff --git a/metrics/gauge.go b/metrics/gauge.go index 2926831..e97bfc2 100644 --- a/metrics/gauge.go +++ b/metrics/gauge.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 @@ -14,12 +12,10 @@ import ( "sync" ) -/* -A gauge metric merely provides an instantaneous representation of a scalar -value or an accumulation. For instance, if one wants to expose the current -temperature or the hitherto bandwidth used, this would be the metric for such -circumstances. -*/ +// A gauge metric merely provides an instantaneous representation of a scalar +// value or an accumulation. For instance, if one wants to expose the current +// temperature or the hitherto bandwidth used, this would be the metric for such +// circumstances. type Gauge interface { AsMarshallable() map[string]interface{} ResetAll() @@ -27,20 +23,20 @@ type Gauge interface { String() string } -type gaugeValue struct { +type gaugeVector struct { labels map[string]string value float64 } func NewGauge() Gauge { return &gauge{ - values: map[string]*gaugeValue{}, + values: map[string]*gaugeVector{}, } } type gauge struct { mutex sync.RWMutex - values map[string]*gaugeValue + values map[string]*gaugeVector } func (metric *gauge) String() string { @@ -65,7 +61,7 @@ func (metric *gauge) Set(labels map[string]string, value float64) float64 { if original, ok := metric.values[signature]; ok { original.value = value } else { - metric.values[signature] = &gaugeValue{ + metric.values[signature] = &gaugeVector{ labels: labels, value: value, } diff --git a/metrics/gauge_test.go b/metrics/gauge_test.go index 52eac3f..5bc6c8f 100644 --- a/metrics/gauge_test.go +++ b/metrics/gauge_test.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 diff --git a/metrics/histogram.go b/metrics/histogram.go index 1716f78..3cafc14 100644 --- a/metrics/histogram.go +++ b/metrics/histogram.go @@ -1,27 +1,24 @@ -/* -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. -*/ +// 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 ( "bytes" "fmt" + "github.com/prometheus/client_golang/maths" "github.com/prometheus/client_golang/utility" "math" "strconv" "sync" ) -/* -This generates count-buckets of equal size distributed along the open -interval of lower to upper. For instance, {lower=0, upper=10, count=5} -yields the following: [0, 2, 4, 6, 8]. -*/ +// This generates count-buckets of equal size distributed along the open +// interval of lower to upper. For instance, {lower=0, upper=10, count=5} +// yields the following: [0, 2, 4, 6, 8]. func EquallySizedBucketsFor(lower, upper float64, count int) []float64 { buckets := make([]float64, count) @@ -35,10 +32,8 @@ func EquallySizedBucketsFor(lower, upper float64, count int) []float64 { return buckets } -/* -This generates log2-sized buckets spanning from lower to upper inclusively -as well as values beyond it. -*/ +// This generates log2-sized buckets spanning from lower to upper inclusively +// as well as values beyond it. func LogarithmicSizedBucketsFor(lower, upper float64) []float64 { bucketCount := int(math.Ceil(math.Log2(upper))) @@ -51,9 +46,7 @@ func LogarithmicSizedBucketsFor(lower, upper float64) []float64 { return buckets } -/* -A HistogramSpecification defines how a Histogram is to be built. -*/ +// A HistogramSpecification defines how a Histogram is to be built. type HistogramSpecification struct { BucketBuilder BucketBuilder ReportablePercentiles []float64 @@ -67,39 +60,30 @@ type Histogram interface { String() string } -/* -The histogram is an accumulator for samples. It merely routes into which -to bucket to capture an event and provides a percentile calculation -mechanism. -*/ +// The histogram is an accumulator for samples. It merely routes into which +// bucket to capture an event and provides a percentile calculation mechanism. type histogram struct { bucketMaker BucketBuilder - /* - This represents the open interval's start at which values shall be added to - the bucket. The interval continues until the beginning of the next bucket - exclusive or positive infinity. - - N.B. - - bucketStarts should be sorted in ascending order; - - len(bucketStarts) must be equivalent to len(buckets); - - The index of a given bucketStarts' element is presumed to - correspond to the appropriate element in buckets. - */ + // This represents the open interval's start at which values shall be added to + // the bucket. The interval continues until the beginning of the next bucket + // exclusive or positive infinity. + // + // N.B. + // - bucketStarts should be sorted in ascending order; + // - len(bucketStarts) must be equivalent to len(buckets); + // - The index of a given bucketStarts' element is presumed to + // correspond to the appropriate element in buckets. bucketStarts []float64 mutex sync.RWMutex - /* - These are the buckets that capture samples as they are emitted to the - histogram. Please consult the reference interface and its implements for - further details about behavior expectations. - */ - values map[string]*histogramValue - /* - These are the percentile values that will be reported on marshalling. - */ + // These are the buckets that capture samples as they are emitted to the + // histogram. Please consult the reference interface and its implements for + // further details about behavior expectations. + values map[string]*histogramVector + // These are the percentile values that will be reported on marshalling. reportablePercentiles []float64 } -type histogramValue struct { +type histogramVector struct { buckets []Bucket labels map[string]string } @@ -113,12 +97,12 @@ func (h *histogram) Add(labels map[string]string, value float64) { } signature := utility.LabelsToSignature(labels) - var histogram *histogramValue = nil + var histogram *histogramVector = nil if original, ok := h.values[signature]; ok { histogram = original } else { bucketCount := len(h.bucketStarts) - histogram = &histogramValue{ + histogram = &histogramVector{ buckets: make([]Bucket, bucketCount), labels: labels, } @@ -161,9 +145,7 @@ func (h *histogram) String() string { return stringBuffer.String() } -/* -Determine the number of previous observations up to a given index. -*/ +// Determine the number of previous observations up to a given index. func previousCumulativeObservations(cumulativeObservations []int, bucketIndex int) int { if bucketIndex == 0 { return 0 @@ -172,16 +154,12 @@ func previousCumulativeObservations(cumulativeObservations []int, bucketIndex in return cumulativeObservations[bucketIndex-1] } -/* -Determine the index for an element given a percentage of length. -*/ +// Determine the index for an element given a percentage of length. func prospectiveIndexForPercentile(percentile float64, totalObservations int) int { return int(percentile * float64(totalObservations-1)) } -/* -Determine the next bucket element when interim bucket intervals may be empty. -*/ +// Determine the next bucket element when interim bucket intervals may be empty. func (h *histogram) nextNonEmptyBucketElement(signature string, currentIndex, bucketCount int, observationsByBucket []int) (*Bucket, int) { for i := currentIndex; i < bucketCount; i++ { if observationsByBucket[i] == 0 { @@ -196,24 +174,18 @@ func (h *histogram) nextNonEmptyBucketElement(signature string, currentIndex, bu panic("Illegal Condition: There were no remaining buckets to provide a value.") } -/* -Find what bucket and element index contains a given percentile value. -If a percentile is requested that results in a corresponding index that is no -longer contained by the bucket, the index of the last item is returned. This -may occur if the underlying bucket catalogs values and employs an eviction -strategy. -*/ +// Find what bucket and element index contains a given percentile value. +// If a percentile is requested that results in a corresponding index that is no +// longer contained by the bucket, the index of the last item is returned. This +// may occur if the underlying bucket catalogs values and employs an eviction +// strategy. func (h *histogram) bucketForPercentile(signature string, percentile float64) (*Bucket, int) { bucketCount := len(h.bucketStarts) - /* - This captures the quantity of samples in a given bucket's range. - */ + // This captures the quantity of samples in a given bucket's range. observationsByBucket := make([]int, bucketCount) - /* - This captures the cumulative quantity of observations from all preceding - buckets up and to the end of this bucket. - */ + // This captures the cumulative quantity of observations from all preceding + // buckets up and to the end of this bucket. cumulativeObservationsByBucket := make([]int, bucketCount) totalObservations := 0 @@ -227,11 +199,9 @@ func (h *histogram) bucketForPercentile(signature string, percentile float64) (* cumulativeObservationsByBucket[i] = totalObservations } - /* - This captures the index offset where the given percentile value would be - were all submitted samples stored and never down-/re-sampled nor deleted - and housed in a singular array. - */ + // This captures the index offset where the given percentile value would be + // were all submitted samples stored and never down-/re-sampled nor deleted + // and housed in a singular array. prospectiveIndex := prospectiveIndexForPercentile(percentile, totalObservations) for i, cumulativeObservation := range cumulativeObservationsByBucket { @@ -239,21 +209,15 @@ func (h *histogram) bucketForPercentile(signature string, percentile float64) (* continue } - /* - Find the bucket that contains the given index. - */ + // Find the bucket that contains the given index. if cumulativeObservation >= prospectiveIndex { var subIndex int - /* - This calculates the index within the current bucket where the given - percentile may be found. - */ + // This calculates the index within the current bucket where the given + // percentile may be found. subIndex = prospectiveIndex - previousCumulativeObservations(cumulativeObservationsByBucket, i) - /* - Sometimes the index may be the last item, in which case we need to - take this into account. - */ + // Sometimes the index may be the last item, in which case we need to + // take this into account. if observationsByBucket[i] == subIndex { return h.nextNonEmptyBucketElement(signature, i+1, bucketCount, observationsByBucket) } @@ -265,11 +229,9 @@ func (h *histogram) bucketForPercentile(signature string, percentile float64) (* return &histogram.buckets[0], 0 } -/* -Return the histogram's estimate of the value for a given percentile of -collected samples. The requested percentile is expected to be a real -value within (0, 1.0]. -*/ +// Return the histogram's estimate of the value for a given percentile of +// collected samples. The requested percentile is expected to be a real +// value within (0, 1.0]. func (h *histogram) percentile(signature string, percentile float64) float64 { bucket, index := h.bucketForPercentile(signature, percentile) @@ -318,16 +280,26 @@ func (h *histogram) ResetAll() { } } -/* -Produce a histogram from a given specification. -*/ +// Produce a histogram from a given specification. func NewHistogram(specification *HistogramSpecification) Histogram { metric := &histogram{ bucketMaker: specification.BucketBuilder, bucketStarts: specification.Starts, reportablePercentiles: specification.ReportablePercentiles, - values: map[string]*histogramValue{}, + values: map[string]*histogramVector{}, } return metric } + +// Furnish a Histogram with unsensible default values and behaviors that is +// strictly useful for prototyping purposes. +func NewDefaultHistogram() Histogram { + return NewHistogram( + &HistogramSpecification{ + Starts: LogarithmicSizedBucketsFor(0, 4096), + BucketBuilder: AccumulatingBucketBuilder(EvictAndReplaceWith(10, maths.Average), 50), + ReportablePercentiles: []float64{0.01, 0.05, 0.5, 0.90, 0.99}, + }, + ) +} diff --git a/metrics/metrics_test.go b/metrics/metrics_test.go index beb1e59..a2a81ae 100644 --- a/metrics/metrics_test.go +++ b/metrics/metrics_test.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 diff --git a/metrics/tallying_bucket.go b/metrics/tallying_bucket.go index 7c370fc..142767e 100644 --- a/metrics/tallying_bucket.go +++ b/metrics/tallying_bucket.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 @@ -20,17 +18,13 @@ const ( upperThird = 2.0 * lowerThird ) -/* -A TallyingIndexEstimator is responsible for estimating the value of index for -a given TallyingBucket, even though a TallyingBucket does not possess a -collection of samples. There are a few strategies listed below for how -this value should be approximated. -*/ +// A TallyingIndexEstimator is responsible for estimating the value of index for +// a given TallyingBucket, even though a TallyingBucket does not possess a +// collection of samples. There are a few strategies listed below for how +// this value should be approximated. type TallyingIndexEstimator func(minimum, maximum float64, index, observations int) float64 -/* -Provide a filter for handling empty buckets. -*/ +// Provide a filter for handling empty buckets. func emptyFilter(e TallyingIndexEstimator) TallyingIndexEstimator { return func(minimum, maximum float64, index, observations int) float64 { if observations == 0 { @@ -41,31 +35,23 @@ func emptyFilter(e TallyingIndexEstimator) TallyingIndexEstimator { } } -/* -Report the smallest observed value in the bucket. -*/ +// 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. -*/ +// 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. -*/ +// 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. -*/ +// 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 @@ -82,11 +68,9 @@ var Uniform TallyingIndexEstimator = emptyFilter(func(minimum, maximum float64, return maths.Average([]float64{minimum, maximum}) }) -/* -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 -as a new minimum or maximum if appropriate. -*/ +// 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 +// as a new minimum or maximum if appropriate. type TallyingBucket struct { estimator TallyingIndexEstimator largestObserved float64 @@ -140,9 +124,7 @@ func (b *TallyingBucket) Reset() { b.smallestObserved = math.MaxFloat64 } -/* -Produce a TallyingBucket with sane defaults. -*/ +// Produce a TallyingBucket with sane defaults. func DefaultTallyingBucket() TallyingBucket { return TallyingBucket{ estimator: Minimum, @@ -159,10 +141,8 @@ func CustomTallyingBucket(estimator TallyingIndexEstimator) TallyingBucket { } } -/* -This is used strictly for testing. -*/ -func TallyingBucketBuilder() Bucket { +// This is used strictly for testing. +func tallyingBucketBuilder() Bucket { b := DefaultTallyingBucket() return &b } diff --git a/metrics/tallying_bucket_test.go b/metrics/tallying_bucket_test.go index c413681..6f1048d 100644 --- a/metrics/tallying_bucket_test.go +++ b/metrics/tallying_bucket_test.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 @@ -40,7 +38,7 @@ func (s *S) TestTallyingPercentilesEstimatorUniform(c *C) { } func (s *S) TestTallyingBucketBuilder(c *C) { - var bucket Bucket = TallyingBucketBuilder() + var bucket Bucket = tallyingBucketBuilder() c.Assert(bucket, Not(IsNil)) } diff --git a/metrics/timer.go b/metrics/timer.go index cdd5ec0..491d132 100644 --- a/metrics/timer.go +++ b/metrics/timer.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 @@ -12,24 +10,18 @@ import ( "time" ) -/* -This callback is called upon the completion of the timer—i.e., when it stops. -*/ +// This callback is called upon the completion of the timer—i.e., when it stops. type CompletionCallback func(duration time.Duration) -/* -This is meant to capture a function that a StopWatch can call for purposes -of instrumentation. -*/ +// This is meant to capture a function that a StopWatch can call for purposes +// of instrumentation. type InstrumentableCall func() -/* -StopWatch is the structure that captures instrumentation for durations. +// StopWatch is the structure that captures instrumentation for durations. -N.B.(mtp): A major limitation hereof is that the StopWatch protocol cannot -retain instrumentation if a panic percolates within the context that is -being measured. -*/ +// N.B.(mtp): A major limitation hereof is that the StopWatch protocol cannot +// retain instrumentation if a panic percolates within the context that is +// being measured. type StopWatch interface { Stop() time.Duration } @@ -40,9 +32,7 @@ type stopWatch struct { startTime time.Time } -/* -Return a new StopWatch that is ready for instrumentation. -*/ +// Return a new StopWatch that is ready for instrumentation. func Start(onCompletion CompletionCallback) StopWatch { return &stopWatch{ onCompletion: onCompletion, @@ -50,10 +40,8 @@ func Start(onCompletion CompletionCallback) StopWatch { } } -/* -Stop the StopWatch returning the elapsed duration of its lifetime while -firing an optional CompletionCallback in the background. -*/ +// Stop the StopWatch returning the elapsed duration of its lifetime while +// firing an optional CompletionCallback in the background. func (s *stopWatch) Stop() time.Duration { s.endTime = time.Now() duration := s.endTime.Sub(s.startTime) @@ -65,10 +53,8 @@ func (s *stopWatch) Stop() time.Duration { return duration } -/* -Provide a quick way of instrumenting a InstrumentableCall and emitting its -duration. -*/ +// Provide a quick way of instrumenting a InstrumentableCall and emitting its +// duration. func InstrumentCall(instrumentable InstrumentableCall, onCompletion CompletionCallback) time.Duration { s := Start(onCompletion) instrumentable() diff --git a/metrics/timer_test.go b/metrics/timer_test.go index 62ae099..d3b12e1 100644 --- a/metrics/timer_test.go +++ b/metrics/timer_test.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 diff --git a/registry.go b/registry.go index 7b1cb8a..dc850fb 100644 --- a/registry.go +++ b/registry.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 registry @@ -22,7 +20,6 @@ import ( "sort" "strings" "sync" - "time" ) const ( @@ -42,18 +39,10 @@ var ( abortOnMisuse bool debugRegistration bool useAggressiveSanityChecks bool + + DefaultHandler = DefaultRegistry.Handler() ) -/* -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) { - microseconds := float64(duration / time.Microsecond) - - requestLatency.Add(nil, microseconds) -} - // container represents a top-level registered metric that encompasses its // static metadata. type container struct { @@ -63,36 +52,29 @@ type container struct { name string } -/* -Registry is, as the name implies, a registrar where metrics are listed. - -In most situations, using DefaultRegistry is sufficient versus creating one's -own. -*/ +// Registry is, as the name implies, a registrar where metrics are listed. +// +// In most situations, using DefaultRegistry is sufficient versus creating one's +// own. type Registry struct { mutex sync.RWMutex signatureContainers map[string]container } -/* -This builds a new metric registry. It is not needed in the majority of -cases. -*/ +// This builds a new metric registry. It is not needed in the majority of +// cases. func NewRegistry() *Registry { return &Registry{ signatureContainers: make(map[string]container), } } -/* -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. It +// is primarily a read-only object after server instantiation. +// var DefaultRegistry = NewRegistry() -/* -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 { return DefaultRegistry.Register(name, docstring, baseLabels, metric) } @@ -155,9 +137,7 @@ func (r *Registry) isValidCandidate(name string, baseLabels map[string]string) ( return } -/* -Register a metric with a given name. Name should be globally unique. -*/ +// Register a metric with a given name. Name should be globally unique. func (r *Registry) Register(name, docstring string, baseLabels map[string]string, metric metrics.Metric) (err error) { r.mutex.Lock() defer r.mutex.Unlock() @@ -184,6 +164,9 @@ func (r *Registry) Register(name, docstring string, baseLabels map[string]string // YieldBasicAuthExporter creates a http.HandlerFunc that is protected by HTTP's // basic authentication. func (register *Registry) YieldBasicAuthExporter(username, password string) http.HandlerFunc { + // XXX: Work with Daniel to get this removed from the library, as it is really + // superfluous and can be much more elegantly accomplished via + // delegation. exporter := register.YieldExporter() return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -277,11 +260,15 @@ func decorateWriter(request *http.Request, writer http.ResponseWriter) io.Writer return gziper } -/* -Create a http.HandlerFunc that is tied to r Registry such that requests -against it generate a representation of the housed metrics. -*/ func (registry *Registry) YieldExporter() http.HandlerFunc { + log.Println("Registry.YieldExporter is deprecated in favor of Registry.Handler.") + + return registry.Handler() +} + +// Create a http.HandlerFunc that is tied to a Registry such that requests +// against it generate a representation of the housed metrics. +func (registry *Registry) Handler() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var instrumentable metrics.InstrumentableCall = func() { requestCount.Increment(nil) @@ -294,7 +281,6 @@ func (registry *Registry) YieldExporter() http.HandlerFunc { writer := decorateWriter(r, w) - // TODO(matt): Migrate to ioutil.NopCloser. if closer, ok := writer.(io.Closer); ok { defer closer.Close() } diff --git a/registry_test.go b/registry_test.go index 2b43a57..1ff9d00 100644 --- a/registry_test.go +++ b/registry_test.go @@ -1,8 +1,8 @@ // 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. +// Use of this source code is governed by a BSD-style license that can be found +// in the LICENSE file. package registry diff --git a/telemetry.go b/telemetry.go index ff224cc..8ce1a6f 100644 --- a/telemetry.go +++ b/telemetry.go @@ -1,10 +1,9 @@ -/* -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. -*/ +// 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. +// package registry @@ -14,11 +13,9 @@ import ( "time" ) -/* -Boilerplate metrics about the metrics reporting subservice. These are only -exposed if the DefaultRegistry's exporter is hooked into the HTTP request -handler. -*/ +// Boilerplate metrics about the metrics reporting subservice. These are only +// exposed if the DefaultRegistry's exporter is hooked into the HTTP request +// handler. var ( marshalErrorCount = metrics.NewCounter() dumpErrorCount = metrics.NewCounter() @@ -42,3 +39,11 @@ func init() { DefaultRegistry.Register("instance_start_time_seconds", "The time at which the current instance started (UTC).", NilLabels, startTime) } + +// 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) { + microseconds := float64(duration / time.Microsecond) + + requestLatency.Add(nil, microseconds) +} diff --git a/utility/documentation.go b/utility/documentation.go index a4bdfdf..773be4c 100644 --- a/utility/documentation.go +++ b/utility/documentation.go @@ -1,24 +1,20 @@ -/* -Copyright (c) 2012, Matt T. Proud -All rights reserved. +// 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. -*/ +// 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. +// The utility package provides general purpose helpers to assist with this +// library. -priority_queue.go provides a simple priority queue. +// priority_queue.go provides a simple priority queue. -priority_queue_test.go provides a test complement for the priority_queue.go -module. +// 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. +// 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. -*/ +// 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/priority_queue.go b/utility/priority_queue.go index 9d2780c..36ebd64 100644 --- a/utility/priority_queue.go +++ b/utility/priority_queue.go @@ -1,10 +1,8 @@ -/* -Copyright (c) 2012, Matt T. Proud -All rights reserved. +// 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. -*/ +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. package utility diff --git a/utility/priority_queue_test.go b/utility/priority_queue_test.go index 3922622..0f66a1a 100644 --- a/utility/priority_queue_test.go +++ b/utility/priority_queue_test.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 diff --git a/utility/test_helper.go b/utility/test_helper.go index b57c4d2..b3d8f7d 100644 --- a/utility/test_helper.go +++ b/utility/test_helper.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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 diff --git a/utility/utility_test.go b/utility/utility_test.go index 5647f1b..17244b1 100644 --- a/utility/utility_test.go +++ b/utility/utility_test.go @@ -1,10 +1,8 @@ -/* -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. -*/ +// 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