Fix documentation after reading via server.

Examining the existing documentation over the standard Go documentation
server revealed some serious formatting flaws.  Everything should be
readable now.
This commit is contained in:
Matt T. Proud 2013-02-17 22:09:21 -06:00
parent 6c3a2ddddb
commit ee7ab62137
14 changed files with 151 additions and 119 deletions

View File

@ -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.

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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 (

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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