diff --git a/README.md b/README.md index 3ed6f33..6e3e1fa 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,5 @@ -# Major Notes -The project's documentation is *not up-to-date due to rapidly-changing -requirements* that have quieted down in the interim, but the overall API should -be stable for several months even if things change under the hood. - -An update to reflect the current state is pending. Key changes for current -users: - -1. The code has been qualified in production environments. -2. Label-oriented metric exposition and registration, including docstrings. -3. Deprecation of gocheck in favor of native table-driven tests. -4. The best way to get a handle on this is to look at the examples. - -Barring that, the antique documentation is below: - # Overview -This [Go](http://golang.org) package is an extraction of a piece of +These [Go](http://golang.org) packages are an extraction of pieces of instrumentation code I whipped-up for a personal project that a friend of mine and I are working on. We were in need for some rudimentary statistics to observe behaviors of the server's various components, so this was written. @@ -33,7 +18,7 @@ to be made, but this task has been deferred for now. [![Build Status](https://secure.travis-ci.org/prometheus/client_golang.png?branch=master)](http://travis-ci.org/prometheus/client_golang) # Documentation -Please read the [generated documentation](http://go.pkgdoc.org/launchpad.net/gocheck) +Please read the [generated documentation](http://go.pkgdoc.org/github.com/prometheus/client_golang) for the project's documentation from source code. # Basic Overview @@ -41,40 +26,42 @@ for the project's documentation from source code. A metric is a measurement mechanism. ### Gauge -A Gauge is a metric that exposes merely an instantaneous value or some snapshot -thereof. +A _Gauge_ is a metric that exposes merely an instantaneous value or some +snapshot thereof. + +### Counter +A _Counter_ is a metric that exposes merely a sum or tally of things. ### Histogram -A Histogram is a metric that captures events or samples into buckets. It +A _Histogram_ is a metric that captures events or samples into _Buckets_. It exposes its values via percentile estimations. #### Buckets -A Bucket is a generic container that collects samples and their values. It +A _Bucket_ is a generic container that collects samples and their values. It prescribes no behavior on its own aside from merely accepting a value, leaving it up to the concrete implementation to what to do with the injected values. ##### Accumulating Bucket -An Accumulating Bucket is a bucket that appends the new sample to a timestamped -priority queue such that the eldest values are evicted according to a given -policy. +An _Accumulating Bucket_ is a _Bucket_ that appends the new sample to a queue +such that the eldest values are evicted according to a given policy. -##### Eviction Policies -Once an Accumulating Bucket reaches capacity, its eviction policy is invoked. +###### Eviction Policies +Once an _Accumulating Bucket_ reaches capacity, its eviction policy is invoked. This reaps the oldest N objects subject to certain behavior. -###### Remove Oldest +####### Remove Oldest This merely removes the oldest N items without performing some aggregation replacement operation on them. -###### Aggregate Oldest +####### Aggregate Oldest This removes the oldest N items while performing some summary aggregation operation thereupon, which is then appended to the list in the former values' place. ##### Tallying Bucket -A Tallying Bucket differs from an Accumulating Bucket in that it never stores -any of the values emitted into it but rather exposes a simplied summary +A _Tallying Bucket_ differs from an _Accumulating Bucket_ in that it never +stores any of the values emitted into it but rather exposes a simplied summary representation thereof. For instance, if a values therein is requested, it may situationally emit a minimum, maximum, an average, or any other reduction mechanism requested. @@ -84,3 +71,6 @@ This package employs [gocheck](http://labix.org/gocheck) for testing. Please ensure that all tests pass by running the following from the project root: $ go test ./... + +The use of gocheck is summarily being phased out; however, old tests that use it +still exist. \ No newline at end of file diff --git a/constants.go b/constants.go index 297ad30..e992d5e 100644 --- a/constants.go +++ b/constants.go @@ -10,6 +10,16 @@ var ( // NilLabels is a nil set of labels merely for end-user convenience. NilLabels map[string]string = nil + // The default http.Handler for exposing telemetric data over a web services + // 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. + DefaultRegistry = NewRegistry() +) + +const ( // A prefix to be used to namespace instrumentation flags from others. FlagNamespace = "telemetry." @@ -17,8 +27,12 @@ var ( // which subscribes to the Semantic Versioning scheme. APIVersion = "0.0.1" + // When reporting telemetric data over the HTTP web services interface, a web + // services interface shall include this header along with APIVersion as its + // value. ProtocolVersionHeader = "X-Prometheus-API-Version" + // The customary web services endpoint on which telemetric data is exposed. ExpositionResource = "/metrics.json" baseLabelsKey = "baseLabels" diff --git a/contributor/documentation.go b/contributor/documentation.go new file mode 100644 index 0000000..fa6f707 --- /dev/null +++ b/contributor/documentation.go @@ -0,0 +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. + +// A repository of various contributed Prometheus client components that may +// assist in your use of the library. +package contributor \ No newline at end of file diff --git a/contributor/responsewriter_delegator.go b/contributor/responsewriter_delegator.go index 100036b..79f91bc 100644 --- a/contributor/responsewriter_delegator.go +++ b/contributor/responsewriter_delegator.go @@ -1,10 +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. -*/ +// 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 contributor diff --git a/documentation.go b/documentation.go index f368048..87f3504 100644 --- a/documentation.go +++ b/documentation.go @@ -6,47 +6,6 @@ // registry.go provides a container for centralized exposition of metrics to // their prospective consumers. - -// registry.Register("human_readable_metric_name", metric) - -// 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. +// +// 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 new file mode 100644 index 0000000..730e474 --- /dev/null +++ b/documentation/documentation.go @@ -0,0 +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. + +// A repository of various Prometheus client documentation and advice. +package documentation \ No newline at end of file diff --git a/documentation/styleguide.go b/documentation/styleguide.go new file mode 100644 index 0000000..d63c2db --- /dev/null +++ b/documentation/styleguide.go @@ -0,0 +1,48 @@ +// 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 \ No newline at end of file diff --git a/examples/documentation.go b/examples/documentation.go new file mode 100644 index 0000000..e7586b9 --- /dev/null +++ b/examples/documentation.go @@ -0,0 +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. + +// Various Prometheus client examples. +package examples diff --git a/examples/random/main.go b/examples/random/main.go index 33e0a67..a055ae2 100644 --- a/examples/random/main.go +++ b/examples/random/main.go @@ -4,9 +4,8 @@ // 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. +// 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. diff --git a/examples/simple/main.go b/examples/simple/main.go index 8f66bd0..c6c8582 100644 --- a/examples/simple/main.go +++ b/examples/simple/main.go @@ -4,8 +4,8 @@ // 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. +// A simple skeletal example of how this instrumentation framework is registered +// and invoked. Literally, this is the bare bones. package main import ( diff --git a/maths/documentation.go b/maths/documentation.go index 76ba017..af7fbed 100644 --- a/maths/documentation.go +++ b/maths/documentation.go @@ -5,18 +5,18 @@ // 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/registry.go b/registry.go index dc850fb..7cf06d1 100644 --- a/registry.go +++ b/registry.go @@ -39,8 +39,6 @@ var ( abortOnMisuse bool debugRegistration bool useAggressiveSanityChecks bool - - DefaultHandler = DefaultRegistry.Handler() ) // container represents a top-level registered metric that encompasses its @@ -52,28 +50,32 @@ 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. -type Registry struct { + +type registry struct { mutex sync.RWMutex signatureContainers map[string]container } +// Registry is a registrar where metrics are listed. +// +// In most situations, using DefaultRegistry is sufficient versus creating one's +// 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 +// 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 +} + // This builds a new metric registry. It is not needed in the majority of // cases. -func NewRegistry() *Registry { - return &Registry{ +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. -// -var DefaultRegistry = NewRegistry() - // 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) @@ -82,7 +84,7 @@ func Register(name, docstring string, baseLabels map[string]string, metric metri // isValidCandidate returns true if the candidate is acceptable for use. In the // event of any apparent incorrect use it will report the problem, invalidate // the candidate, or outright abort. -func (r *Registry) isValidCandidate(name string, baseLabels map[string]string) (signature string, err error) { +func (r registry) isValidCandidate(name string, baseLabels map[string]string) (signature string, err error) { if len(name) == 0 { err = fmt.Errorf("unnamed metric named with baseLabels %s is invalid", baseLabels) @@ -137,8 +139,7 @@ func (r *Registry) isValidCandidate(name string, baseLabels map[string]string) ( return } -// 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) { +func (r registry) Register(name, docstring string, baseLabels map[string]string, metric metrics.Metric) (err error) { r.mutex.Lock() defer r.mutex.Unlock() @@ -163,7 +164,7 @@ 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 { +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. @@ -192,7 +193,7 @@ func (register *Registry) YieldBasicAuthExporter(username, password string) http }) } -func (registry *Registry) dumpToWriter(writer io.Writer) (err error) { +func (registry registry) dumpToWriter(writer io.Writer) (err error) { defer func() { if err != nil { dumpErrorCount.Increment(nil) @@ -260,15 +261,13 @@ func decorateWriter(request *http.Request, writer http.ResponseWriter) io.Writer return gziper } -func (registry *Registry) YieldExporter() http.HandlerFunc { +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 { +func (registry registry) Handler() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var instrumentable metrics.InstrumentableCall = func() { requestCount.Increment(nil) diff --git a/registry_test.go b/registry_test.go index 1ff9d00..b607ff3 100644 --- a/registry_test.go +++ b/registry_test.go @@ -298,7 +298,7 @@ func testDumpToWriter(t test.Tester) { } for i, scenario := range scenarios { - registry := NewRegistry() + registry := NewRegistry().(registry) for name, metric := range scenario.in.metrics { err := registry.Register(name, fmt.Sprintf("metric %s", name), map[string]string{fmt.Sprintf("label_%s", name): name}, metric) diff --git a/utility/documentation.go b/utility/documentation.go index 773be4c..7b9628f 100644 --- a/utility/documentation.go +++ b/utility/documentation.go @@ -3,18 +3,18 @@ // 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