mirror of
https://github.com/golang/go
synced 2024-11-23 12:10:11 -07:00
runtime/metrics: add package interface
This change creates the runtime/metrics package and adds the initial interface as laid out in the design document. For #37112. Change-Id: I202dcee08ab008dd63bf96f7a4162f5b5f813637 Reviewed-on: https://go-review.googlesource.com/c/go/+/247040 Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Michael Knyszek <mknyszek@google.com> Reviewed-by: Michael Pratt <mpratt@google.com>
This commit is contained in:
parent
c02134abb0
commit
2159c26ceb
@ -138,6 +138,9 @@ var depsRules = `
|
|||||||
MATH
|
MATH
|
||||||
< math/rand;
|
< math/rand;
|
||||||
|
|
||||||
|
MATH
|
||||||
|
< runtime/metrics;
|
||||||
|
|
||||||
MATH, unicode/utf8
|
MATH, unicode/utf8
|
||||||
< strconv;
|
< strconv;
|
||||||
|
|
||||||
|
52
src/runtime/metrics/description.go
Normal file
52
src/runtime/metrics/description.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Copyright 2020 The Go Authors. 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
|
||||||
|
|
||||||
|
// Description describes a runtime metric.
|
||||||
|
type Description struct {
|
||||||
|
// Name is the full name of the metric which includes the unit.
|
||||||
|
//
|
||||||
|
// The format of the metric may be described by the following regular expression.
|
||||||
|
//
|
||||||
|
// ^(?P<name>/[^:]+):(?P<unit>[^:*\/]+(?:[*\/][^:*\/]+)*)$
|
||||||
|
//
|
||||||
|
// The format splits the name into two components, separated by a colon: a path which always
|
||||||
|
// starts with a /, and a machine-parseable unit. The name may contain any valid Unicode
|
||||||
|
// codepoint in between / characters, but by convention will try to stick to lowercase
|
||||||
|
// characters and hyphens. An example of such a path might be "/memory/heap/free".
|
||||||
|
//
|
||||||
|
// The unit is by convention a series of lowercase English unit names (singular or plural)
|
||||||
|
// without prefixes delimited by '*' or '/'. The unit names may contain any valid Unicode
|
||||||
|
// codepoint that is not a delimiter.
|
||||||
|
// Examples of units might be "seconds", "bytes", "bytes/second", "cpu-seconds",
|
||||||
|
// "byte*cpu-seconds", and "bytes/second/second".
|
||||||
|
//
|
||||||
|
// A complete name might look like "/memory/heap/free:bytes".
|
||||||
|
Name string
|
||||||
|
|
||||||
|
// Kind is the kind of value for this metric.
|
||||||
|
//
|
||||||
|
// The purpose of this field is to allow users to filter out metrics whose values are
|
||||||
|
// types which their application may not understand.
|
||||||
|
Kind ValueKind
|
||||||
|
|
||||||
|
// Cumulative is whether or not the metric is cumulative. If a cumulative metric is just
|
||||||
|
// a single number, then it increases monotonically. If the metric is a distribution,
|
||||||
|
// then each bucket count increases monotonically.
|
||||||
|
//
|
||||||
|
// This flag thus indicates whether or not it's useful to compute a rate from this value.
|
||||||
|
Cumulative bool
|
||||||
|
|
||||||
|
// StopTheWorld is whether or not the metric requires a stop-the-world
|
||||||
|
// event in order to collect it.
|
||||||
|
StopTheWorld bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var allDesc = []Description{}
|
||||||
|
|
||||||
|
// All returns a slice of containing metric descriptions for all supported metrics.
|
||||||
|
func All() []Description {
|
||||||
|
return allDesc
|
||||||
|
}
|
49
src/runtime/metrics/doc.go
Normal file
49
src/runtime/metrics/doc.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright 2020 The Go Authors. 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 provides a stable interface to access implementation-defined
|
||||||
|
metrics exported by the Go runtime. This package is similar to existing functions
|
||||||
|
like runtime.ReadMemStats and debug.ReadGCStats, but significantly more general.
|
||||||
|
|
||||||
|
The set of metrics defined by this package may evolve as the runtime itself
|
||||||
|
evolves, and also enables variation across Go implementations, whose relevant
|
||||||
|
metric sets may not intersect.
|
||||||
|
|
||||||
|
Interface
|
||||||
|
|
||||||
|
Metrics are designated by a string key, rather than, for example, a field name in
|
||||||
|
a struct. The full list of supported metrics is always available in the slice of
|
||||||
|
Descriptions returned by All. Each Description also includes useful information
|
||||||
|
about the metric, such as how to display it (e.g. gauge vs. counter) and how difficult
|
||||||
|
or disruptive it is to obtain it (e.g. do you need to stop the world?).
|
||||||
|
|
||||||
|
Thus, users of this API are encouraged to sample supported metrics defined by the
|
||||||
|
slice returned by All to remain compatible across Go versions. Of course, situations
|
||||||
|
arise where reading specific metrics is critical. For these cases, users are
|
||||||
|
encouranged to use build tags, and although metrics may be deprecated and removed,
|
||||||
|
users should consider this to be an exceptional and rare event, coinciding with a
|
||||||
|
very large change in a particular Go implementation.
|
||||||
|
|
||||||
|
Each metric key also has a "kind" that describes the format of the metric's value.
|
||||||
|
In the interest of not breaking users of this package, the "kind" for a given metric
|
||||||
|
is guaranteed not to change. If it must change, then a new metric will be introduced
|
||||||
|
with a new key and a new "kind."
|
||||||
|
|
||||||
|
Metric key format
|
||||||
|
|
||||||
|
As mentioned earlier, metric keys are strings. Their format is simple and well-defined,
|
||||||
|
designed to be both human and machine readable. It is split into two components,
|
||||||
|
separated by a colon: a rooted path and a unit. The choice to include the unit in
|
||||||
|
the key is motivated by compatibility: if a metric's unit changes, its semantics likely
|
||||||
|
did also, and a new key should be introduced.
|
||||||
|
|
||||||
|
For more details on the precise definition of the metric key's path and unit formats, see
|
||||||
|
the documentation of the Name field of the Description struct.
|
||||||
|
|
||||||
|
Supported metrics
|
||||||
|
|
||||||
|
TODO(mknyszek): List them here as they're added.
|
||||||
|
*/
|
||||||
|
package metrics
|
30
src/runtime/metrics/histogram.go
Normal file
30
src/runtime/metrics/histogram.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright 2020 The Go Authors. 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
|
||||||
|
|
||||||
|
// Float64Histogram represents a distribution of float64 values.
|
||||||
|
type Float64Histogram struct {
|
||||||
|
// Counts contains the weights for each histogram bucket. The length of
|
||||||
|
// Counts is equal to the length of Buckets (in the metric description)
|
||||||
|
// plus one to account for the implicit minimum bucket.
|
||||||
|
//
|
||||||
|
// Given N buckets, the following is the mathematical relationship between
|
||||||
|
// Counts and Buckets.
|
||||||
|
// count[0] is the weight of the range (-inf, bucket[0])
|
||||||
|
// count[n] is the weight of the range [bucket[n], bucket[n+1]), for 0 < n < N-1
|
||||||
|
// count[N-1] is the weight of the range [bucket[N-1], inf)
|
||||||
|
Counts []uint64
|
||||||
|
|
||||||
|
// Buckets contains the boundaries between histogram buckets, in increasing order.
|
||||||
|
//
|
||||||
|
// Because this slice contains boundaries, there are len(Buckets)+1 counts:
|
||||||
|
// a count for all values less than the first boundary, a count covering each
|
||||||
|
// [slice[i], slice[i+1]) interval, and a count for all values greater than or
|
||||||
|
// equal to the last boundary.
|
||||||
|
//
|
||||||
|
// For a given metric name, the value of Buckets is guaranteed not to change
|
||||||
|
// between calls until program exit.
|
||||||
|
Buckets []float64
|
||||||
|
}
|
29
src/runtime/metrics/sample.go
Normal file
29
src/runtime/metrics/sample.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2020 The Go Authors. 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
|
||||||
|
|
||||||
|
// Sample captures a single metric sample.
|
||||||
|
type Sample struct {
|
||||||
|
// Name is the name of the metric sampled.
|
||||||
|
//
|
||||||
|
// It must correspond to a name in one of the metric descriptions
|
||||||
|
// returned by Descriptions.
|
||||||
|
Name string
|
||||||
|
|
||||||
|
// Value is the value of the metric sample.
|
||||||
|
Value Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read populates each Value field in the given slice of metric samples.
|
||||||
|
//
|
||||||
|
// Desired metrics should be present in the slice with the appropriate name.
|
||||||
|
// The user of this API is encouraged to re-use the same slice between calls.
|
||||||
|
//
|
||||||
|
// Metric values with names not appearing in the value returned by Descriptions
|
||||||
|
// will have the value populated as KindBad to indicate that the name is
|
||||||
|
// unknown.
|
||||||
|
func Read(m []Sample) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
69
src/runtime/metrics/value.go
Normal file
69
src/runtime/metrics/value.go
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
// Copyright 2020 The Go Authors. 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 (
|
||||||
|
"math"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ValueKind is a tag for a metric Value which indicates its type.
|
||||||
|
type ValueKind int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// KindBad indicates that the Value has no type and should not be used.
|
||||||
|
KindBad ValueKind = iota
|
||||||
|
|
||||||
|
// KindUint64 indicates that the type of the Value is a uint64.
|
||||||
|
KindUint64
|
||||||
|
|
||||||
|
// KindFloat64 indicates that the type of the Value is a float64.
|
||||||
|
KindFloat64
|
||||||
|
|
||||||
|
// KindFloat64Histogram indicates that the type of the Value is a *Float64Histogram.
|
||||||
|
KindFloat64Histogram
|
||||||
|
)
|
||||||
|
|
||||||
|
// Value represents a metric value returned by the runtime.
|
||||||
|
type Value struct {
|
||||||
|
kind ValueKind
|
||||||
|
scalar uint64 // contains scalar values for scalar Kinds.
|
||||||
|
pointer unsafe.Pointer // contains non-scalar values.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kind returns the a tag representing the kind of value this is.
|
||||||
|
func (v Value) Kind() ValueKind {
|
||||||
|
return v.kind
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint64 returns the internal uint64 value for the metric.
|
||||||
|
//
|
||||||
|
// If v.Kind() != KindUint64, this method panics.
|
||||||
|
func (v Value) Uint64() uint64 {
|
||||||
|
if v.kind != KindUint64 {
|
||||||
|
panic("called Uint64 on non-uint64 metric value")
|
||||||
|
}
|
||||||
|
return v.scalar
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float64 returns the internal float64 value for the metric.
|
||||||
|
//
|
||||||
|
// If v.Kind() != KindFloat64, this method panics.
|
||||||
|
func (v Value) Float64() float64 {
|
||||||
|
if v.kind != KindFloat64 {
|
||||||
|
panic("called Float64 on non-float64 metric value")
|
||||||
|
}
|
||||||
|
return math.Float64frombits(v.scalar)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float64Histogram returns the internal *Float64Histogram value for the metric.
|
||||||
|
//
|
||||||
|
// If v.Kind() != KindFloat64Histogram, this method panics.
|
||||||
|
func (v Value) Float64Histogram() *Float64Histogram {
|
||||||
|
if v.kind != KindFloat64Histogram {
|
||||||
|
panic("called Float64 on non-float64 metric value")
|
||||||
|
}
|
||||||
|
return (*Float64Histogram)(v.pointer)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user