Documentation ¶
Overview ¶
Package metrics provides an API for counters, gauges, and histograms.
Metric Types ¶
The metrics package provides types for three metrics: counters, gauges, and histograms.
- A Counter is a number that can only increase over time. It never decreases. You can use a counter to measure things like the number of HTTP requests your program has processed so far.
- A Gauge is a number that can increase or decrease over time. You can use a gauge to measure things like the current amount of memory your program is using, in bytes.
- A Histogram is a collection of numbers that are grouped into buckets. You can use a histogram to measure things like the latency of every HTTP request your program has received so far.
Declaring Metrics ¶
Declare metrics using NewCounter, NewGauge, or NewHistogram. We recommend you declare metrics at package scope.
var ( exampleCount = metrics.NewCounter( "example_count", "An example counter", ) exampleGauge = metrics.NewGauge( "example_gauge", "An example gauge", ) exampleHistogram = metrics.NewHistogram( "example_histogram", "An example histogram", []float64{1, 10, 100, 1000, 10000}, ) )
Updating Metrics ¶
Every metric type has a set of methods you can use to update the metric. Counters can be added to. Gauges can be set. Histograms can have values added to them.
func main() { exampleCount.Add(1) exampleGauge.Set(2) exampleHistogram.Put(3) }
Metric Labels ¶
You can declare a metric with a set of key-value labels. For example, if you have a metric that measures the latency of handling HTTP requests, you can declare the metric with a label that identifies the URL of the request (e.g., "/users/foo").
You can declare a labeled metric using NewCounterMap, NewGaugeMap, or NewHistogramMap. Service Weaver represents metric labels using structs. For example, here's how to declare a counter with labels "foo" and "bar":
type labels struct { Foo string Bar string } var exampleLabeledCounter = xcweaver.NewCounterMap[labels]( "example_labeled_counter", `An example counter with labels "foo" and "bar"`, )
Use the Get method to get a metric with the provided set of label values.
func main() { // Get the counter with foo="a" and bar="b". counter := exampleLabeledCounter.Get(labels{Foo: "a", Bar: "b"}) counter.Add(1) }
More precisely, labels are represented as a comparable struct of type L. We say a label struct L is valid if every field of L is a string, bool, or integer type and is exported. For example, the following are valid label structs:
struct{} // an empty struct struct{X string} // a struct with one field struct{X, Y int} // a struct with two fields
The following are invalid label structs:
struct{x string} // unexported field string // not a struct struct{X chan int} // unsupported label type (i.e. chan int)
Note that the order of the fields within a label struct is unimportant. For example, if one program exports a metric with labels
struct{X, Y string}
another program can safely export the same metric with labels
struct{Y, X string}
To adhere to popular metric naming conventions, the first letter of every label is lowercased by default. The Foo label for example is exported as "foo", not "Foo". You can override this behavior and provide a custom label name using a xcweaver annotation.
type labels struct { Foo string // exported as "foo" Bar string `xcweaver:"my_custom_name"` // exported as "my_custom_name" }
Exporting Metrics ¶
Service Weaver integrates metrics into the environment where your application is deployed. If you deploy a Service Weaver application to Google Cloud, for example, metrics are automatically exported to the Google Cloud Metrics Explorer where they can be queried, aggregated, and graphed. Refer to your deployer documentation for details.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Counter ¶
type Counter struct {
// contains filtered or unexported fields
}
A Counter is a float-valued, monotonically increasing metric. For example, you can use a Counter to count the number of requests received, the number of requests that resulted in an error, etc.
func NewCounter ¶
NewCounter returns a new Counter. It is typically called during package initialization since it panics if called more than once in the same process with the same name. Use NewCounterMap to make a Counter with labels.
type CounterMap ¶
type CounterMap[L comparable] struct { // contains filtered or unexported fields }
A CounterMap is a collection of Counters with the same name and label schema but with different label values. See package documentation for a description of L.
Example ¶
package main import ( "github.com/XCWeaver/xcweaver/metrics" ) func main() { // At package scope. type carLabels struct { Make string Model string } var ( carCounts = metrics.NewCounterMap[carLabels]("car_count", "The number of cars") civicCount = carCounts.Get(carLabels{"Honda", "Civic"}) camryCount = carCounts.Get(carLabels{"Toyota", "Camry"}) f150Count = carCounts.Get(carLabels{"Ford", "F-150"}) ) // In your code. civicCount.Add(1) camryCount.Add(2) f150Count.Add(150) }
Output:
func NewCounterMap ¶
func NewCounterMap[L comparable](name, help string) *CounterMap[L]
NewCounterMap returns a new CounterMap. It is typically called during package initialization since it panics if called more than once in the same process with the same name.
func (*CounterMap[L]) Get ¶
func (c *CounterMap[L]) Get(labels L) *Counter
Get returns the Counter with the provided labels, constructing it if it doesn't already exist. Multiple calls to Get with the same labels will return the same Counter.
func (*CounterMap[L]) Name ¶
func (c *CounterMap[L]) Name() string
Name returns the name of the CounterMap.
type Gauge ¶
type Gauge struct {
// contains filtered or unexported fields
}
A Gauge is a float-valued metric that can hold an arbitrary numerical value, which can increase or decrease over time. For example, you can use a Gauge to measure the current memory usage or the current number of outstanding requests.
func NewGauge ¶
NewGauge returns a new Gauge. It is typically called during package initialization since it panics if called more than once in the same process with the same name. Use NewGaugeMap to make a Gauge with labels.
type GaugeMap ¶
type GaugeMap[L comparable] struct { // contains filtered or unexported fields }
A GaugeMap is a collection of Gauges with the same name and label schema but with different label values. See package documentation for a description of L.
Example ¶
package main import ( "github.com/XCWeaver/xcweaver/metrics" ) func main() { // At package scope. type tempLabels struct { Room string Index int } var ( temps = metrics.NewGaugeMap[tempLabels]("temperature", "Temperature, in Fahrenheit") livingRoomTemp = temps.Get(tempLabels{"Living Room", 0}) bathroomTemp = temps.Get(tempLabels{"Bathroom", 0}) bedroom0Temp = temps.Get(tempLabels{"Bedroom", 0}) bedroom1Temp = temps.Get(tempLabels{"Bedroom", 1}) ) // In your code. livingRoomTemp.Set(78.4) bathroomTemp.Set(65.3) bedroom0Temp.Set(84.1) bedroom1Temp.Set(80.9) livingRoomTemp.Add(1.2) bathroomTemp.Sub(2.1) }
Output:
func NewGaugeMap ¶
func NewGaugeMap[L comparable](name, help string) *GaugeMap[L]
NewGaugeMap returns a new GaugeMap. It is typically called during package initialization since it panics if called more than once in the same process with the same name.
type Histogram ¶
type Histogram struct {
// contains filtered or unexported fields
}
A Histogram is a metric that counts the number of values that fall in specified ranges (i.e. buckets). For example, you can use a Histogram to measure the distribution of request latencies.
func NewHistogram ¶
NewHistogram returns a new Histogram. It is typically called during package initialization since it panics if called more than once in the same process with the same name. Use NewHistogram to make a Histogram with labels.
The bucket boundaries must be strictly increasing. Given n boundary values, the histogram will contain n+1 buckets, organized as follows:
- bucket[0] is the underflow bucket, which counts values in the range [-inf, bounds[0]).
- bucket[n] is the overflow bucket, which counts values in the range [bounds[n-1], +inf).
- bucket[i], for 0 < i < n, is a bucket that counts values in the range [bounds[i-1], bounds[i]).
For example, given the bounds [0, 10, 100], we have the following buckets:
- Bucket 0: (-inf, 0]
- Bucket 1: [0, 10)
- Bucket 2: [10, 100)
- Bucket 3: [100, +inf)
type HistogramMap ¶
type HistogramMap[L comparable] struct { // contains filtered or unexported fields }
A HistogramMap is a collection of Histograms with the same name and label schema but with different label values. See package documentation for a description of L.
Example ¶
package main import ( "github.com/XCWeaver/xcweaver/metrics" ) func main() { // At package scope. type latencyLabels struct { Endpoint string } var ( latencies = metrics.NewHistogramMap[latencyLabels]( "http_request_latency_nanoseconds", "HTTP request latency, in nanoseconds, by endpoint", []float64{10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000}, ) fooLatency = latencies.Get(latencyLabels{"/foo"}) barLatency = latencies.Get(latencyLabels{"/bar"}) metricsLatency = latencies.Get(latencyLabels{"/metrics"}) ) // In your code. fooLatency.Put(8714.5) barLatency.Put(491.7) metricsLatency.Put(375.0) }
Output:
func NewHistogramMap ¶
func NewHistogramMap[L comparable](name, help string, bounds []float64) *HistogramMap[L]
NewHistogramMap returns a new HistogramMap. It is typically called during package initialization since it panics if called more than once in the same process with the same name.
func (*HistogramMap[L]) Get ¶
func (h *HistogramMap[L]) Get(labels L) *Histogram
Get returns the Histogram with the provided labels, constructing it if it doesn't already exist. Multiple calls to Get with the same labels will return the same Histogram.
func (*HistogramMap[L]) Name ¶
func (h *HistogramMap[L]) Name() string
Name returns the name of the HistogramMap.