Documentation ¶
Overview ¶
Package prometheus provides embeddable metric primitives for servers and standardized exposition of telemetry through a web services interface.
All exported functions and methods are safe to be used concurrently unless specified otherwise.
To expose metrics registered with the Prometheus registry, an HTTP server needs to know about the Prometheus handler. The usual endpoint is "/metrics".
http.Handle("/metrics", prometheus.Handler())
As a starting point a very basic usage example:
package main import ( "net/http" "github.com/prometheus/client_golang/prometheus" ) var ( cpuTemp = prometheus.NewGauge(prometheus.GaugeOpts{ Name: "cpu_temperature_celsius", Help: "Current temperature of the CPU.", }) hdFailures = prometheus.NewCounter(prometheus.CounterOpts{ Name: "hd_errors_total", Help: "Number of hard-disk errors.", }) ) func init() { prometheus.MustRegister(cpuTemp) prometheus.MustRegister(hdFailures) } func main() { cpuTemp.Set(65.3) hdFailures.Inc() http.Handle("/metrics", prometheus.Handler()) http.ListenAndServe(":8080", nil) }
This is a complete program that exports two metrics, a Gauge and a Counter. It also exports some stats about the HTTP usage of the /metrics endpoint. (See the Handler function for more detail.)
A more advanced metric type is the Summary.
In addition to the fundamental metric types Gauge, Counter, and Summary, a very important part of the Prometheus data model is the partitioning of samples along dimensions called labels, which results in metric vectors. The fundamental types are GaugeVec, CounterVec, and SummaryVec.
Those are all the parts needed for basic usage. Detailed documentation and examples are provided below.
Everything else this package offers is essentially for "power users" only. A few pointers to "power user features":
All the various ...Opts structs have a ConstLabels field for labels that never change their value (which is only useful under special circumstances, see documentation of the Opts type).
The Untyped metric behaves like a Gauge, but signals the Prometheus server not to assume anything about its type.
Functions to fine-tune how the metric registry works: EnableCollectChecks, PanicOnCollectError, Register, Unregister, SetMetricFamilyInjectionHook.
For custom metric collection, there are two entry points: Custom Metric implementations and custom Collector implementations. A Metric is the fundamental unit in the Prometheus data model: a sample at a point in time together with its meta-data (like its fully-qualified name and any number of pairs of label name and label value) that knows how to marshal itself into a data transfer object (aka DTO, implemented as a protocol buffer). A Collector gets registered with the Prometheus registry and manages the collection of one or more Metrics. Many parts of this package are building blocks for Metrics and Collectors. Desc is the metric descriptor, actually used by all metrics under the hood, and by Collectors to describe the Metrics to be collected, but only to be dealt with by users if they implement their own Metrics or Collectors. To create a Desc, the BuildFQName function will come in handy. Other useful components for Metric and Collector implementation include: LabelPairSorter to sort the DTO version of label pairs, NewConstMetric and MustNewConstMetric to create "throw away" Metrics at collection time, MetricVec to bundle custom Metrics into a metric vector Collector, SelfCollector to make a custom Metric collect itself.
A good example for a custom Collector is the ExpVarCollector included in this package, which exports variables exported via the "expvar" package as Prometheus metrics.
Index ¶
- Constants
- Variables
- func BuildFQName(namespace, subsystem, name string) string
- func EnableCollectChecks(b bool)
- func Handler() http.Handler
- func InstrumentHandler(handlerName string, handler http.Handler) http.HandlerFunc
- func InstrumentHandlerFunc(handlerName string, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc
- func InstrumentHandlerFuncWithOpts(opts SummaryOpts, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc
- func InstrumentHandlerWithOpts(opts SummaryOpts, handler http.Handler) http.HandlerFunc
- func MustRegister(m Collector)
- func NewGoCollector() *goCollector
- func NewProcessCollector(pid int, namespace string) *processCollector
- func NewProcessCollectorPIDFn(pidFn func() (int, error), namespace string) *processCollector
- func PanicOnCollectError(b bool)
- func Push(job, instance, addr string) error
- func PushAdd(job, instance, addr string) error
- func Register(m Collector) error
- func SetMetricFamilyInjectionHook(hook func() []*dto.MetricFamily)
- func UninstrumentedHandler() http.Handler
- func Unregister(c Collector) bool
- type Collector
- type Counter
- type CounterFunc
- type CounterOpts
- type CounterVec
- type Desc
- type ExpvarCollector
- type Gauge
- type GaugeFunc
- type GaugeOpts
- type GaugeVec
- type LabelPairSorter
- type Labels
- type Metric
- type MetricVec
- func (m *MetricVec) Collect(ch chan<- Metric)
- func (m *MetricVec) Delete(labels Labels) bool
- func (m *MetricVec) DeleteLabelValues(lvs ...string) bool
- func (m *MetricVec) Describe(ch chan<- *Desc)
- func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error)
- func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error)
- func (m *MetricVec) Reset()
- func (m *MetricVec) With(labels Labels) Metric
- func (m *MetricVec) WithLabelValues(lvs ...string) Metric
- type Opts
- type SelfCollector
- type Summary
- type SummaryOpts
- type SummaryVec
- type Untyped
- type UntypedFunc
- type UntypedOpts
- type UntypedVec
- type ValueType
Examples ¶
Constants ¶
const ( // APIVersion is the version of the format of the exported data. This // will match this library's version, which subscribes to the Semantic // Versioning scheme. APIVersion = "0.0.4" // DelimitedTelemetryContentType is the content type set on telemetry // data responses in delimited protobuf format. DelimitedTelemetryContentType = `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited` // TextTelemetryContentType is the content type set on telemetry data // responses in text format. TextTelemetryContentType = `text/plain; version=` + APIVersion // ProtoTextTelemetryContentType is the content type set on telemetry // data responses in protobuf text format. (Only used for debugging.) ProtoTextTelemetryContentType = `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=text` // ProtoCompactTextTelemetryContentType is the content type set on // telemetry data responses in protobuf compact text format. (Only used // for debugging.) ProtoCompactTextTelemetryContentType = `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=compact-text` )
Constants relevant to the HTTP interface.
const ( // DefMaxAge is the default duration for which observations stay // relevant. DefMaxAge time.Duration = 10 * time.Minute // DefAgeBuckets is the default number of buckets used to calculate the // age of observations. DefAgeBuckets = 5 // DefBufCap is the standard buffer size for collecting Summary observations. DefBufCap = 500 )
Default values for SummaryOpts.
Variables ¶
var (
DefObjectives = map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}
)
DefObjectives are the default Summary quantile values.
Functions ¶
func BuildFQName ¶
BuildFQName joins the given three name components by "_". Empty name components are ignored. If the name parameter itself is empty, an empty string is returned, no matter what. Metric implementations included in this library use this function internally to generate the fully-qualified metric name from the name component in their Opts. Users of the library will only need this function if they implement their own Metric or instantiate a Desc (with NewDesc) directly.
func EnableCollectChecks ¶
func EnableCollectChecks(b bool)
EnableCollectChecks enables (or disables) additional consistency checks during metrics collection. These additional checks are not enabled by default because they inflict a performance penalty and the errors they check for can only happen if the used Metric and Collector types have internal programming errors. It can be helpful to enable these checks while working with custom Collectors or Metrics whose correctness is not well established yet.
func Handler ¶
Handler returns the HTTP handler for the global Prometheus registry. It is already instrumented with InstrumentHandler (using "prometheus" as handler name). Usually the handler is used to handle the "/metrics" endpoint.
func InstrumentHandler ¶
func InstrumentHandler(handlerName string, handler http.Handler) http.HandlerFunc
InstrumentHandler wraps the given HTTP handler for instrumentation. It registers four metric collectors (if not already done) and reports http metrics to the (newly or already) registered collectors: http_requests_total (CounterVec), http_request_duration_microseconds (Summary), http_request_size_bytes (Summary), http_response_size_bytes (Summary). Each has a constant label named "handler" with the provided handlerName as value. http_requests_total is a metric vector partitioned by HTTP method (label name "method") and HTTP status code (label name "code").
Example ¶
package main import ( "net/http" "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus" ) func main() { // Handle the "/doc" endpoint with the standard http.FileServer handler. // By wrapping the handler with InstrumentHandler, request count, // request and response sizes, and request latency are automatically // exported to Prometheus, partitioned by HTTP status code and method // and by the handler name (here "fileserver"). http.Handle("/doc", prometheus.InstrumentHandler( "fileserver", http.FileServer(http.Dir("/usr/share/doc")), )) // The Prometheus handler still has to be registered to handle the // "/metrics" endpoint. The handler returned by prometheus.Handler() is // already instrumented - with "prometheus" as the handler name. In this // example, we want the handler name to be "metrics", so we instrument // the uninstrumented Prometheus handler ourselves. http.Handle("/metrics", prometheus.InstrumentHandler( "metrics", prometheus.UninstrumentedHandler(), )) }
Output:
func InstrumentHandlerFunc ¶
func InstrumentHandlerFunc(handlerName string, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc
InstrumentHandlerFunc wraps the given function for instrumentation. It otherwise works in the same way as InstrumentHandler.
func InstrumentHandlerFuncWithOpts ¶
func InstrumentHandlerFuncWithOpts(opts SummaryOpts, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc
InstrumentHandlerFuncWithOpts works like InstrumentHandlerFunc but provides more flexibility (at the cost of a more complex call syntax). See InstrumentHandlerWithOpts for details how the provided SummaryOpts are used.
func InstrumentHandlerWithOpts ¶
func InstrumentHandlerWithOpts(opts SummaryOpts, handler http.Handler) http.HandlerFunc
InstrumentHandlerWithOpts works like InstrumentHandler but provides more flexibility (at the cost of a more complex call syntax). As InstrumentHandler, this function registers four metric collectors, but it uses the provided SummaryOpts to create them. However, the fields "Name" and "Help" in the SummaryOpts are ignored. "Name" is replaced by "requests_total", "request_duration_microseconds", "request_size_bytes", and "response_size_bytes", respectively. "Help" is replaced by an appropriate help string. The names of the variable labels of the http_requests_total CounterVec are "method" (get, post, etc.), and "code" (HTTP status code).
If InstrumentHandlerWithOpts is called as follows, it mimics exactly the behavior of InstrumentHandler:
prometheus.InstrumentHandlerWithOpts( prometheus.SummaryOpts{ Subsystem: "http", ConstLabels: prometheus.Labels{"handler": handlerName}, }, handler, )
Technical detail: "requests_total" is a CounterVec, not a SummaryVec, so it cannot use SummaryOpts. Instead, a CounterOpts struct is created internally, and all its fields are set to the equally named fields in the provided SummaryOpts.
func MustRegister ¶
func MustRegister(m Collector)
MustRegister works like Register but panics where Register would have returned an error.
func NewGoCollector ¶
func NewGoCollector() *goCollector
NewGoCollector returns a collector which exports metrics about the current go process.
func NewProcessCollector ¶
NewProcessCollector returns a collector which exports the current state of process metrics including cpu, memory and file descriptor usage as well as the process start time for the given process id under the given namespace.
func NewProcessCollectorPIDFn ¶
NewProcessCollectorPIDFn returns a collector which exports the current state of process metrics including cpu, memory and file descriptor usage as well as the process start time under the given namespace. The given pidFn is called on each collect and is used to determine the process to export metrics for.
func PanicOnCollectError ¶
func PanicOnCollectError(b bool)
PanicOnCollectError sets the behavior whether a panic is caused upon an error while metrics are collected and served to the http endpoint. By default, an internal server error (status code 500) is served with an error message.
func Push ¶
Push triggers a metric collection and pushes all collected metrics to the Pushgateway specified by addr. See the Pushgateway documentation for detailed implications of the job and instance parameter. instance can be left empty. The Pushgateway will then use the client's IP number instead. Use just host:port or ip:port ass addr. (Don't add 'http://' or any path.)
Note that all previously pushed metrics with the same job and instance will be replaced with the metrics pushed by this call. (It uses HTTP method 'PUT' to push to the Pushgateway.)
func PushAdd ¶
PushAdd works like Push, but only previously pushed metrics with the same name (and the same job and instance) will be replaced. (It uses HTTP method 'POST' to push to the Pushgateway.)
func Register ¶
Register registers a new Collector to be included in metrics collection. It returns an error if the descriptors provided by the Collector are invalid or if they - in combination with descriptors of already registered Collectors - do not fulfill the consistency and uniqueness criteria described in the Desc documentation.
Do not register the same Collector multiple times concurrently. (Registering the same Collector twice would result in an error anyway, but on top of that, it is not safe to do so concurrently.)
Example ¶
package main import ( "fmt" "net/http" "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus" ) func main() { // Imagine you have a worker pool and want to count the tasks completed. taskCounter := prometheus.NewCounter(prometheus.CounterOpts{ Subsystem: "worker_pool", Name: "completed_tasks_total", Help: "Total number of tasks completed.", }) // This will register fine. if err := prometheus.Register(taskCounter); err != nil { fmt.Println(err) } else { fmt.Println("taskCounter registered.") } // Don't forget to tell the HTTP server about the Prometheus handler. // (In a real program, you still need to start the http server...) http.Handle("/metrics", prometheus.Handler()) // Now you can start workers and give every one of them a pointer to // taskCounter and let it increment it whenever it completes a task. taskCounter.Inc() // This has to happen somewhere in the worker code. // But wait, you want to see how individual workers perform. So you need // a vector of counters, with one element for each worker. taskCounterVec := prometheus.NewCounterVec( prometheus.CounterOpts{ Subsystem: "worker_pool", Name: "completed_tasks_total", Help: "Total number of tasks completed.", }, []string{"worker_id"}, ) // Registering will fail because we already have a metric of that name. if err := prometheus.Register(taskCounterVec); err != nil { fmt.Println("taskCounterVec not registered:", err) } else { fmt.Println("taskCounterVec registered.") } // To fix, first unregister the old taskCounter. if prometheus.Unregister(taskCounter) { fmt.Println("taskCounter unregistered.") } // Try registering taskCounterVec again. if err := prometheus.Register(taskCounterVec); err != nil { fmt.Println("taskCounterVec not registered:", err) } else { fmt.Println("taskCounterVec registered.") } // Bummer! Still doesn't work. // Prometheus will not allow you to ever export metrics with // inconsistent help strings or label names. After unregistering, the // unregistered metrics will cease to show up in the /metrics http // response, but the registry still remembers that those metrics had // been exported before. For this example, we will now choose a // different name. (In a real program, you would obviously not export // the obsolete metric in the first place.) taskCounterVec = prometheus.NewCounterVec( prometheus.CounterOpts{ Subsystem: "worker_pool", Name: "completed_tasks_by_id", Help: "Total number of tasks completed.", }, []string{"worker_id"}, ) if err := prometheus.Register(taskCounterVec); err != nil { fmt.Println("taskCounterVec not registered:", err) } else { fmt.Println("taskCounterVec registered.") } // Finally it worked! // The workers have to tell taskCounterVec their id to increment the // right element in the metric vector. taskCounterVec.WithLabelValues("42").Inc() // Code from worker 42. // Each worker could also keep a reference to their own counter element // around. Pick the counter at initialization time of the worker. myCounter := taskCounterVec.WithLabelValues("42") // From worker 42 initialization code. myCounter.Inc() // Somewhere in the code of that worker. // Note that something like WithLabelValues("42", "spurious arg") would // panic (because you have provided too many label values). If you want // to get an error instead, use GetMetricWithLabelValues(...) instead. notMyCounter, err := taskCounterVec.GetMetricWithLabelValues("42", "spurious arg") if err != nil { fmt.Println("Worker initialization failed:", err) } if notMyCounter == nil { fmt.Println("notMyCounter is nil.") } // A different (and somewhat tricky) approach is to use // ConstLabels. ConstLabels are pairs of label names and label values // that never change. You might ask what those labels are good for (and // rightfully so - if they never change, they could as well be part of // the metric name). There are essentially two use-cases: The first is // if labels are constant throughout the lifetime of a binary execution, // but they vary over time or between different instances of a running // binary. The second is what we have here: Each worker creates and // registers an own Counter instance where the only difference is in the // value of the ConstLabels. Those Counters can all be registered // because the different ConstLabel values guarantee that each worker // will increment a different Counter metric. counterOpts := prometheus.CounterOpts{ Subsystem: "worker_pool", Name: "completed_tasks", Help: "Total number of tasks completed.", ConstLabels: prometheus.Labels{"worker_id": "42"}, } taskCounterForWorker42 := prometheus.NewCounter(counterOpts) if err := prometheus.Register(taskCounterForWorker42); err != nil { fmt.Println("taskCounterVForWorker42 not registered:", err) } else { fmt.Println("taskCounterForWorker42 registered.") } // Obviously, in real code, taskCounterForWorker42 would be a member // variable of a worker struct, and the "42" would be retrieved with a // GetId() method or something. The Counter would be created and // registered in the initialization code of the worker. // For the creation of the next Counter, we can recycle // counterOpts. Just change the ConstLabels. counterOpts.ConstLabels = prometheus.Labels{"worker_id": "2001"} taskCounterForWorker2001 := prometheus.NewCounter(counterOpts) if err := prometheus.Register(taskCounterForWorker2001); err != nil { fmt.Println("taskCounterVForWorker2001 not registered:", err) } else { fmt.Println("taskCounterForWorker2001 registered.") } taskCounterForWorker2001.Inc() taskCounterForWorker42.Inc() taskCounterForWorker2001.Inc() // Yet another approach would be to turn the workers themselves into // Collectors and register them. See the Collector example for details. }
Output: taskCounter registered. taskCounterVec not registered: a previously registered descriptor with the same fully-qualified name as Desc{fqName: "worker_pool_completed_tasks_total", help: "Total number of tasks completed.", constLabels: {}, variableLabels: [worker_id]} has different label names or a different help string taskCounter unregistered. taskCounterVec not registered: a previously registered descriptor with the same fully-qualified name as Desc{fqName: "worker_pool_completed_tasks_total", help: "Total number of tasks completed.", constLabels: {}, variableLabels: [worker_id]} has different label names or a different help string taskCounterVec registered. Worker initialization failed: inconsistent label cardinality notMyCounter is nil. taskCounterForWorker42 registered. taskCounterForWorker2001 registered.
func SetMetricFamilyInjectionHook ¶
func SetMetricFamilyInjectionHook(hook func() []*dto.MetricFamily)
SetMetricFamilyInjectionHook sets a function that is called whenever metrics are collected. The hook function must be set before metrics collection begins (i.e. call SetMetricFamilyInjectionHook before setting the HTTP handler.) The MetricFamily protobufs returned by the hook function are added to the delivered metrics. Each returned MetricFamily must have a unique name (also taking into account the MetricFamilies created in the regular way).
This is a way to directly inject MetricFamily protobufs managed and owned by the caller. The caller has full responsibility. No sanity checks are performed on the returned protobufs (besides the name checks described above). The function must be callable at any time and concurrently.
func UninstrumentedHandler ¶
UninstrumentedHandler works in the same way as Handler, but the returned HTTP handler is not instrumented. This is useful if no instrumentation is desired (for whatever reason) or if the instrumentation has to happen with a different handler name (or with a different instrumentation approach altogether). See the InstrumentHandler example.
func Unregister ¶
Unregister unregisters the Collector that equals the Collector passed in as an argument. (Two Collectors are considered equal if their Describe method yields the same set of descriptors.) The function returns whether a Collector was unregistered.
Types ¶
type Collector ¶
type Collector interface { // Describe sends the super-set of all possible descriptors of metrics // collected by this Collector to the provided channel and returns once // the last descriptor has been sent. The sent descriptors fulfill the // consistency and uniqueness requirements described in the Desc // documentation. (It is valid if one and the same Collector sends // duplicate descriptors. Those duplicates are simply ignored. However, // two different Collectors must not send duplicate descriptors.) This // method idempotently sends the same descriptors throughout the // lifetime of the Collector. If a Collector encounters an error while // executing this method, it must send an invalid descriptor (created // with NewInvalidDesc) to signal the error to the registry. Describe(chan<- *Desc) // Collect is called by Prometheus when collecting metrics. The // implementation sends each collected metric via the provided channel // and returns once the last metric has been sent. The descriptor of // each sent metric is one of those returned by Describe. Returned // metrics that share the same descriptor must differ in their variable // label values. This method may be called concurrently and must // therefore be implemented in a concurrency safe way. Blocking occurs // at the expense of total performance of rendering all registered // metrics. Ideally, Collector implementations support concurrent // readers. Collect(chan<- Metric) }
Collector is the interface implemented by anything that can be used by Prometheus to collect metrics. A Collector has to be registered for collection. See Register, MustRegister, RegisterOrGet, and MustRegisterOrGet.
The stock metrics provided by this package (like Gauge, Counter, Summary) are also Collectors (which only ever collect one metric, namely itself). An implementer of Collector may, however, collect multiple metrics in a coordinated fashion and/or create metrics on the fly. Examples for collectors already implemented in this library are the metric vectors (i.e. collection of multiple instances of the same Metric but with different label values) like GaugeVec or SummaryVec, and the ExpvarCollector.
Example (Clustermanager) ¶
package main import ( "sync" "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus" ) // ClusterManager is an example for a system that might have been built without // Prometheus in mind. It models a central manager of jobs running in a // cluster. To turn it into something that collects Prometheus metrics, we // simply add the two methods required for the Collector interface. // // An additional challenge is that multiple instances of the ClusterManager are // run within the same binary, each in charge of a different zone. We need to // make use of ConstLabels to be able to register each ClusterManager instance // with Prometheus. type ClusterManager struct { Zone string OOMCount *prometheus.CounterVec RAMUsage *prometheus.GaugeVec mtx sync.Mutex // Protects OOMCount and RAMUsage. // ... many more fields } // ReallyExpensiveAssessmentOfTheSystemState is a mock for the data gathering a // real cluster manager would have to do. Since it may actually be really // expensive, it must only be called once per collection. This implementation, // obviously, only returns some made-up data. func (c *ClusterManager) ReallyExpensiveAssessmentOfTheSystemState() ( oomCountByHost map[string]int, ramUsageByHost map[string]float64, ) { // Just example fake data. oomCountByHost = map[string]int{ "foo.example.org": 42, "bar.example.org": 2001, } ramUsageByHost = map[string]float64{ "foo.example.org": 6.023e23, "bar.example.org": 3.14, } return } // Describe faces the interesting challenge that the two metric vectors that are // used in this example are already Collectors themselves. However, thanks to // the use of channels, it is really easy to "chain" Collectors. Here we simply // call the Describe methods of the two metric vectors. func (c *ClusterManager) Describe(ch chan<- *prometheus.Desc) { c.OOMCount.Describe(ch) c.RAMUsage.Describe(ch) } // Collect first triggers the ReallyExpensiveAssessmentOfTheSystemState. Then it // sets the retrieved values in the two metric vectors and then sends all their // metrics to the channel (again using a chaining technique as in the Describe // method). Since Collect could be called multiple times concurrently, that part // is protected by a mutex. func (c *ClusterManager) Collect(ch chan<- prometheus.Metric) { oomCountByHost, ramUsageByHost := c.ReallyExpensiveAssessmentOfTheSystemState() c.mtx.Lock() defer c.mtx.Unlock() for host, oomCount := range oomCountByHost { c.OOMCount.WithLabelValues(host).Set(float64(oomCount)) } for host, ramUsage := range ramUsageByHost { c.RAMUsage.WithLabelValues(host).Set(ramUsage) } c.OOMCount.Collect(ch) c.RAMUsage.Collect(ch) // All metrics in OOMCount and RAMUsage are sent to the channel now. We // can safely reset the two metric vectors now, so that we can start // fresh in the next Collect cycle. (Imagine a host disappears from the // cluster. If we did not reset here, its Metric would stay in the // metric vectors forever.) c.OOMCount.Reset() c.RAMUsage.Reset() } // NewClusterManager creates the two metric vectors OOMCount and RAMUsage. Note // that the zone is set as a ConstLabel. (It's different in each instance of the // ClusterManager, but constant over the lifetime of an instance.) The reported // values are partitioned by host, which is therefore a variable label. func NewClusterManager(zone string) *ClusterManager { return &ClusterManager{ Zone: zone, OOMCount: prometheus.NewCounterVec( prometheus.CounterOpts{ Subsystem: "clustermanager", Name: "oom_count", Help: "number of OOM crashes", ConstLabels: prometheus.Labels{"zone": zone}, }, []string{"host"}, ), RAMUsage: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Subsystem: "clustermanager", Name: "ram_usage_bytes", Help: "RAM usage as reported to the cluster manager", ConstLabels: prometheus.Labels{"zone": zone}, }, []string{"host"}, ), } } func main() { workerDB := NewClusterManager("db") workerCA := NewClusterManager("ca") prometheus.MustRegister(workerDB) prometheus.MustRegister(workerCA) // Since we are dealing with custom Collector implementations, it might // be a good idea to enable the collect checks in the registry. prometheus.EnableCollectChecks(true) }
Output:
Example (Memstats) ¶
package main import ( "runtime" "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus" ) var ( allocDesc = prometheus.NewDesc( prometheus.BuildFQName("", "memstats", "alloc_bytes"), "bytes allocated and still in use", nil, nil, ) totalAllocDesc = prometheus.NewDesc( prometheus.BuildFQName("", "memstats", "total_alloc_bytes"), "bytes allocated (even if freed)", nil, nil, ) numGCDesc = prometheus.NewDesc( prometheus.BuildFQName("", "memstats", "num_gc_total"), "number of GCs run", nil, nil, ) ) // MemStatsCollector is an example for a custom Collector that solves the // problem of feeding into multiple metrics at the same time. The // runtime.ReadMemStats should happen only once, and then the results need to be // fed into a number of separate Metrics. In this example, only a few of the // values reported by ReadMemStats are used. For each, there is a Desc provided // as a var, so the MemStatsCollector itself needs nothing else in the // struct. Only the methods need to be implemented. type MemStatsCollector struct{} // Describe just sends the three Desc objects for the Metrics we intend to // collect. func (_ MemStatsCollector) Describe(ch chan<- *prometheus.Desc) { ch <- allocDesc ch <- totalAllocDesc ch <- numGCDesc } // Collect does the trick by calling ReadMemStats once and then constructing // three different Metrics on the fly. func (_ MemStatsCollector) Collect(ch chan<- prometheus.Metric) { var ms runtime.MemStats runtime.ReadMemStats(&ms) ch <- prometheus.MustNewConstMetric( allocDesc, prometheus.GaugeValue, float64(ms.Alloc), ) ch <- prometheus.MustNewConstMetric( totalAllocDesc, prometheus.GaugeValue, float64(ms.TotalAlloc), ) ch <- prometheus.MustNewConstMetric( numGCDesc, prometheus.CounterValue, float64(ms.NumGC), ) // To avoid new allocations on each collection, you could also keep // metric objects around and return the same objects each time, just // with new values set. } func main() { prometheus.MustRegister(&MemStatsCollector{}) // Since we are dealing with custom Collector implementations, it might // be a good idea to enable the collect checks in the registry. prometheus.EnableCollectChecks(true) }
Output:
func MustRegisterOrGet ¶
MustRegisterOrGet works like Register but panics where RegisterOrGet would have returned an error.
func RegisterOrGet ¶
RegisterOrGet works like Register but does not return an error if a Collector is registered that equals a previously registered Collector. (Two Collectors are considered equal if their Describe method yields the same set of descriptors.) Instead, the previously registered Collector is returned (which is helpful if the new and previously registered Collectors are equal but not identical, i.e. not pointers to the same object).
As for Register, it is still not safe to call RegisterOrGet with the same Collector multiple times concurrently.
type Counter ¶
type Counter interface { Metric Collector // Set is used to set the Counter to an arbitrary value. It is only used // if you have to transfer a value from an external counter into this // Prometheus metrics. Do not use it for regular handling of a // Prometheus counter (as it can be used to break the contract of // monotonically increasing values). Set(float64) // Inc increments the counter by 1. Inc() // Add adds the given value to the counter. It panics if the value is < // 0. Add(float64) }
Counter is a Metric that represents a single numerical value that only ever goes up. That implies that it cannot be used to count items whose number can also go down, e.g. the number of currently running goroutines. Those "counters" are represented by Gauges.
A Counter is typically used to count requests served, tasks completed, errors occurred, etc.
To create Counter instances, use NewCounter.
Example ¶
package main import ( "fmt" "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus" ) func main() { pushCounter := prometheus.NewCounter(prometheus.CounterOpts{ Name: "repository_pushes", // Note: No help string... }) err := prometheus.Register(pushCounter) // ... so this will return an error. if err != nil { fmt.Println("Push counter couldn't be registered, no counting will happen:", err) return } // Try it once more, this time with a help string. pushCounter = prometheus.NewCounter(prometheus.CounterOpts{ Name: "repository_pushes", Help: "Number of pushes to external repository.", }) err = prometheus.Register(pushCounter) if err != nil { fmt.Println("Push counter couldn't be registered AGAIN, no counting will happen:", err) return } pushComplete := make(chan struct{}) // TODO: Start a goroutine that performs repository pushes and reports // each completion via the channel. for _ = range pushComplete { pushCounter.Inc() } }
Output: Push counter couldn't be registered, no counting will happen: descriptor Desc{fqName: "repository_pushes", help: "", constLabels: {}, variableLabels: []} is invalid: empty help string
func NewCounter ¶
func NewCounter(opts CounterOpts) Counter
NewCounter creates a new Counter based on the provided CounterOpts.
type CounterFunc ¶
CounterFunc is a Counter whose value is determined at collect time by calling a provided function.
To create CounterFunc instances, use NewCounterFunc.
func NewCounterFunc ¶
func NewCounterFunc(opts CounterOpts, function func() float64) CounterFunc
NewCounterFunc creates a new CounterFunc based on the provided CounterOpts. The value reported is determined by calling the given function from within the Write method. Take into account that metric collection may happen concurrently. If that results in concurrent calls to Write, like in the case where a CounterFunc is directly registered with Prometheus, the provided function must be concurrency-safe. The function should also honor the contract for a Counter (values only go up, not down), but compliance will not be checked.
type CounterOpts ¶
type CounterOpts Opts
CounterOpts is an alias for Opts. See there for doc comments.
type CounterVec ¶
type CounterVec struct {
MetricVec
}
CounterVec is a Collector that bundles a set of Counters that all share the same Desc, but have different values for their variable labels. This is used if you want to count the same thing partitioned by various dimensions (e.g. number of http requests, partitioned by response code and method). Create instances with NewCounterVec.
CounterVec embeds MetricVec. See there for a full list of methods with detailed documentation.
Example ¶
package main import ( "flag" "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus" ) func main() { binaryVersion := flag.String("environment", "test", "Execution environment: test, staging, production.") flag.Parse() httpReqs := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "http_requests_total", Help: "How many HTTP requests processed, partitioned by status code and http method.", ConstLabels: prometheus.Labels{"env": *binaryVersion}, }, []string{"code", "method"}, ) prometheus.MustRegister(httpReqs) httpReqs.WithLabelValues("404", "POST").Add(42) // If you have to access the same set of labels very frequently, it // might be good to retrieve the metric only once and keep a handle to // it. But beware of deletion of that metric, see below! m := httpReqs.WithLabelValues("200", "GET") for i := 0; i < 1000000; i++ { m.Inc() } // Delete a metric from the vector. If you have previously kept a handle // to that metric (as above), future updates via that handle will go // unseen (even if you re-create a metric with the same label set // later). httpReqs.DeleteLabelValues("200", "GET") // Same thing with the more verbose Labels syntax. httpReqs.Delete(prometheus.Labels{"method": "GET", "code": "200"}) }
Output:
func NewCounterVec ¶
func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec
NewCounterVec creates a new CounterVec based on the provided CounterOpts and partitioned by the given label names. At least one label name must be provided.
func (*CounterVec) GetMetricWith ¶
func (m *CounterVec) GetMetricWith(labels Labels) (Counter, error)
GetMetricWith replaces the method of the same name in MetricVec. The difference is that this method returns a Counter and not a Metric so that no type conversion is required.
func (*CounterVec) GetMetricWithLabelValues ¶
func (m *CounterVec) GetMetricWithLabelValues(lvs ...string) (Counter, error)
GetMetricWithLabelValues replaces the method of the same name in MetricVec. The difference is that this method returns a Counter and not a Metric so that no type conversion is required.
func (*CounterVec) With ¶
func (m *CounterVec) With(labels Labels) Counter
With works as GetMetricWith, but panics where GetMetricWithLabels would have returned an error. By not returning an error, With allows shortcuts like
myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
func (*CounterVec) WithLabelValues ¶
func (m *CounterVec) WithLabelValues(lvs ...string) Counter
WithLabelValues works as GetMetricWithLabelValues, but panics where GetMetricWithLabelValues would have returned an error. By not returning an error, WithLabelValues allows shortcuts like
myVec.WithLabelValues("404", "GET").Add(42)
type Desc ¶
type Desc struct {
// contains filtered or unexported fields
}
Desc is the descriptor used by every Prometheus Metric. It is essentially the immutable meta-data of a Metric. The normal Metric implementations included in this package manage their Desc under the hood. Users only have to deal with Desc if they use advanced features like the ExpvarCollector or custom Collectors and Metrics.
Descriptors registered with the same registry have to fulfill certain consistency and uniqueness criteria if they share the same fully-qualified name: They must have the same help string and the same label names (aka label dimensions) in each, constLabels and variableLabels, but they must differ in the values of the constLabels.
Descriptors that share the same fully-qualified names and the same label values of their constLabels are considered equal.
Use NewDesc to create new Desc instances.
func NewDesc ¶
NewDesc allocates and initializes a new Desc. Errors are recorded in the Desc and will be reported on registration time. variableLabels and constLabels can be nil if no such labels should be set. fqName and help must not be empty.
variableLabels only contain the label names. Their label values are variable and therefore not part of the Desc. (They are managed within the Metric.)
For constLabels, the label values are constant. Therefore, they are fully specified in the Desc. See the Opts documentation for the implications of constant labels.
func NewInvalidDesc ¶
NewInvalidDesc returns an invalid descriptor, i.e. a descriptor with the provided error set. If a collector returning such a descriptor is registered, registration will fail with the provided error. NewInvalidDesc can be used by a Collector to signal inability to describe itself.
type ExpvarCollector ¶
type ExpvarCollector struct {
// contains filtered or unexported fields
}
ExpvarCollector collects metrics from the expvar interface. It provides a quick way to expose numeric values that are already exported via expvar as Prometheus metrics. Note that the data models of expvar and Prometheus are fundamentally different, and that the ExpvarCollector is inherently slow. Thus, the ExpvarCollector is probably great for experiments and prototying, but you should seriously consider a more direct implementation of Prometheus metrics for monitoring production systems.
Use NewExpvarCollector to create new instances.
Example ¶
package main import ( "expvar" "fmt" "sort" "strings" "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus" dto "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_model/go" ) func main() { expvarCollector := prometheus.NewExpvarCollector(map[string]*prometheus.Desc{ "memstats": prometheus.NewDesc( "expvar_memstats", "All numeric memstats as one metric family. Not a good role-model, actually... ;-)", []string{"type"}, nil, ), "lone-int": prometheus.NewDesc( "expvar_lone_int", "Just an expvar int as an example.", nil, nil, ), "http-request-map": prometheus.NewDesc( "expvar_http_request_total", "How many http requests processed, partitioned by status code and http method.", []string{"code", "method"}, nil, ), }) prometheus.MustRegister(expvarCollector) // The Prometheus part is done here. But to show that this example is // doing anything, we have to manually export something via expvar. In // real-life use-cases, some library would already have exported via // expvar what we want to re-export as Prometheus metrics. expvar.NewInt("lone-int").Set(42) expvarMap := expvar.NewMap("http-request-map") var ( expvarMap1, expvarMap2 expvar.Map expvarInt11, expvarInt12, expvarInt21, expvarInt22 expvar.Int ) expvarMap1.Init() expvarMap2.Init() expvarInt11.Set(3) expvarInt12.Set(13) expvarInt21.Set(11) expvarInt22.Set(212) expvarMap1.Set("POST", &expvarInt11) expvarMap1.Set("GET", &expvarInt12) expvarMap2.Set("POST", &expvarInt21) expvarMap2.Set("GET", &expvarInt22) expvarMap.Set("404", &expvarMap1) expvarMap.Set("200", &expvarMap2) // Results in the following expvar map: // "http-request-count": {"200": {"POST": 11, "GET": 212}, "404": {"POST": 3, "GET": 13}} // Let's see what the scrape would yield, but exclude the memstats metrics. metricStrings := []string{} metric := dto.Metric{} metricChan := make(chan prometheus.Metric) go func() { expvarCollector.Collect(metricChan) close(metricChan) }() for m := range metricChan { if strings.Index(m.Desc().String(), "expvar_memstats") == -1 { metric.Reset() m.Write(&metric) metricStrings = append(metricStrings, metric.String()) } } sort.Strings(metricStrings) for _, s := range metricStrings { fmt.Println(strings.TrimRight(s, " ")) } }
Output: label:<name:"code" value:"200" > label:<name:"method" value:"GET" > untyped:<value:212 > label:<name:"code" value:"200" > label:<name:"method" value:"POST" > untyped:<value:11 > label:<name:"code" value:"404" > label:<name:"method" value:"GET" > untyped:<value:13 > label:<name:"code" value:"404" > label:<name:"method" value:"POST" > untyped:<value:3 > untyped:<value:42 >
func NewExpvarCollector ¶
func NewExpvarCollector(exports map[string]*Desc) *ExpvarCollector
NewExpvarCollector returns a newly allocated ExpvarCollector that still has to be registered with the Prometheus registry.
The exports map has the following meaning:
The keys in the map correspond to expvar keys, i.e. for every expvar key you want to export as Prometheus metric, you need an entry in the exports map. The descriptor mapped to each key describes how to export the expvar value. It defines the name and the help string of the Prometheus metric proxying the expvar value. The type will always be Untyped.
For descriptors without variable labels, the expvar value must be a number or a bool. The number is then directly exported as the Prometheus sample value. (For a bool, 'false' translates to 0 and 'true' to 1). Expvar values that are not numbers or bools are silently ignored.
If the descriptor has one variable label, the expvar value must be an expvar map. The keys in the expvar map become the various values of the one Prometheus label. The values in the expvar map must be numbers or bools again as above.
For descriptors with more than one variable label, the expvar must be a nested expvar map, i.e. where the values of the topmost map are maps again etc. until a depth is reached that corresponds to the number of labels. The leaves of that structure must be numbers or bools as above to serve as the sample values.
Anything that does not fit into the scheme above is silently ignored.
func (*ExpvarCollector) Collect ¶
func (e *ExpvarCollector) Collect(ch chan<- Metric)
Collect implements Collector.
func (*ExpvarCollector) Describe ¶
func (e *ExpvarCollector) Describe(ch chan<- *Desc)
Describe implements Collector.
type Gauge ¶
type Gauge interface { Metric Collector // Set sets the Gauge to an arbitrary value. Set(float64) // Inc increments the Gauge by 1. Inc() // Dec decrements the Gauge by 1. Dec() // Add adds the given value to the Gauge. (The value can be // negative, resulting in a decrease of the Gauge.) Add(float64) // Sub subtracts the given value from the Gauge. (The value can be // negative, resulting in an increase of the Gauge.) Sub(float64) }
Gauge is a Metric that represents a single numerical value that can arbitrarily go up and down.
A Gauge is typically used for measured values like temperatures or current memory usage, but also "counts" that can go up and down, like the number of running goroutines.
To create Gauge instances, use NewGauge.
Example ¶
package main import ( "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus" ) func main() { opsQueued := prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: "our_company", Subsystem: "blob_storage", Name: "ops_queued", Help: "Number of blob storage operations waiting to be processed.", }) prometheus.MustRegister(opsQueued) // 10 operations queued by the goroutine managing incoming requests. opsQueued.Add(10) // A worker goroutine has picked up a waiting operation. opsQueued.Dec() // And once more... opsQueued.Dec() }
Output:
type GaugeFunc ¶
GaugeFunc is a Gauge whose value is determined at collect time by calling a provided function.
To create GaugeFunc instances, use NewGaugeFunc.
Example ¶
package main import ( "fmt" "runtime" "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus" ) func main() { if err := prometheus.Register(prometheus.NewGaugeFunc( prometheus.GaugeOpts{ Subsystem: "runtime", Name: "goroutines_count", Help: "Number of goroutines that currently exist.", }, func() float64 { return float64(runtime.NumGoroutine()) }, )); err == nil { fmt.Println("GaugeFunc 'goroutines_count' registered.") } // Note that the count of goroutines is a gauge (and not a counter) as // it can go up and down. }
Output: GaugeFunc 'goroutines_count' registered.
func NewGaugeFunc ¶
NewGaugeFunc creates a new GaugeFunc based on the provided GaugeOpts. The value reported is determined by calling the given function from within the Write method. Take into account that metric collection may happen concurrently. If that results in concurrent calls to Write, like in the case where a GaugeFunc is directly registered with Prometheus, the provided function must be concurrency-safe.
type GaugeVec ¶
type GaugeVec struct {
MetricVec
}
GaugeVec is a Collector that bundles a set of Gauges that all share the same Desc, but have different values for their variable labels. This is used if you want to count the same thing partitioned by various dimensions (e.g. number of operations queued, partitioned by user and operation type). Create instances with NewGaugeVec.
Example ¶
package main import ( "flag" "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus" ) func main() { binaryVersion := flag.String("binary_version", "debug", "Version of the binary: debug, canary, production.") flag.Parse() opsQueued := prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: "our_company", Subsystem: "blob_storage", Name: "ops_queued", Help: "Number of blob storage operations waiting to be processed, partitioned by user and type.", ConstLabels: prometheus.Labels{"binary_version": *binaryVersion}, }, []string{ // Which user has requested the operation? "user", // Of what type is the operation? "type", }, ) prometheus.MustRegister(opsQueued) // Increase a value using compact (but order-sensitive!) WithLabelValues(). opsQueued.WithLabelValues("bob", "put").Add(4) // Increase a value with a map using WithLabels. More verbose, but order // doesn't matter anymore. opsQueued.With(prometheus.Labels{"type": "delete", "user": "alice"}).Inc() }
Output:
func NewGaugeVec ¶
NewGaugeVec creates a new GaugeVec based on the provided GaugeOpts and partitioned by the given label names. At least one label name must be provided.
func (*GaugeVec) GetMetricWith ¶
GetMetricWith replaces the method of the same name in MetricVec. The difference is that this method returns a Gauge and not a Metric so that no type conversion is required.
func (*GaugeVec) GetMetricWithLabelValues ¶
GetMetricWithLabelValues replaces the method of the same name in MetricVec. The difference is that this method returns a Gauge and not a Metric so that no type conversion is required.
func (*GaugeVec) With ¶
With works as GetMetricWith, but panics where GetMetricWithLabels would have returned an error. By not returning an error, With allows shortcuts like
myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
func (*GaugeVec) WithLabelValues ¶
WithLabelValues works as GetMetricWithLabelValues, but panics where GetMetricWithLabelValues would have returned an error. By not returning an error, WithLabelValues allows shortcuts like
myVec.WithLabelValues("404", "GET").Add(42)
type LabelPairSorter ¶
LabelPairSorter implements sort.Interface. It is used to sort a slice of dto.LabelPair pointers. This is useful for implementing the Write method of custom metrics.
Example ¶
package main import ( "fmt" "sort" "github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto" "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus" dto "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_model/go" ) func main() { labelPairs := []*dto.LabelPair{ &dto.LabelPair{Name: proto.String("status"), Value: proto.String("404")}, &dto.LabelPair{Name: proto.String("method"), Value: proto.String("get")}, } sort.Sort(prometheus.LabelPairSorter(labelPairs)) fmt.Println(labelPairs) }
Output: [name:"method" value:"get" name:"status" value:"404" ]
func (LabelPairSorter) Len ¶
func (s LabelPairSorter) Len() int
func (LabelPairSorter) Less ¶
func (s LabelPairSorter) Less(i, j int) bool
func (LabelPairSorter) Swap ¶
func (s LabelPairSorter) Swap(i, j int)
type Labels ¶
Labels represents a collection of label name -> value mappings. This type is commonly used with the With(Labels) and GetMetricWith(Labels) methods of metric vector Collectors, e.g.:
myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
The other use-case is the specification of constant label pairs in Opts or to create a Desc.
type Metric ¶
type Metric interface { // Desc returns the descriptor for the Metric. This method idempotently // returns the same descriptor throughout the lifetime of the // Metric. The returned descriptor is immutable by contract. A Metric // unable to describe itself must return an invalid descriptor (created // with NewInvalidDesc). Desc() *Desc // Write encodes the Metric into a "Metric" Protocol Buffer data // transmission object. // // Implementers of custom Metric types must observe concurrency safety // as reads of this metric may occur at any time, and any blocking // occurs at the expense of total performance of rendering all // registered metrics. Ideally Metric implementations should support // concurrent readers. // // The Prometheus client library attempts to minimize memory allocations // and will provide a pre-existing reset dto.Metric pointer. Prometheus // may recycle the dto.Metric proto message, so Metric implementations // should just populate the provided dto.Metric and then should not keep // any reference to it. // // While populating dto.Metric, labels must be sorted lexicographically. // (Implementers may find LabelPairSorter useful for that.) Write(*dto.Metric) error }
A Metric models a single sample value with its meta data being exported to Prometheus. Implementers of Metric in this package inclued Gauge, Counter, Untyped, and Summary. Users can implement their own Metric types, but that should be rarely needed. See the example for SelfCollector, which is also an example for a user-implemented Metric.
func MustNewConstMetric ¶
func MustNewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) Metric
MustNewConstMetric is a version of NewConstMetric that panics where NewConstMetric would have returned an error.
func NewConstMetric ¶
func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) (Metric, error)
NewConstMetric returns a metric with one fixed value that cannot be changed. Users of this package will not have much use for it in regular operations. However, when implementing custom Collectors, it is useful as a throw-away metric that is generated on the fly to send it to Prometheus in the Collect method. NewConstMetric returns an error if the length of labelValues is not consistent with the variable labels in Desc.
func NewInvalidMetric ¶
NewInvalidMetric returns a metric whose Write method always returns the provided error. It is useful if a Collector finds itself unable to collect a metric and wishes to report an error to the registry.
type MetricVec ¶
type MetricVec struct {
// contains filtered or unexported fields
}
MetricVec is a Collector to bundle metrics of the same name that differ in their label values. MetricVec is usually not used directly but as a building block for implementations of vectors of a given metric type. GaugeVec, CounterVec, SummaryVec, and UntypedVec are examples already provided in this package.
func (*MetricVec) Delete ¶
Delete deletes the metric where the variable labels are the same as those passed in as labels. It returns true if a metric was deleted.
It is not an error if the number and names of the Labels are inconsistent with those of the VariableLabels in the Desc of the MetricVec. However, such inconsistent Labels can never match an actual Metric, so the method will always return false in that case.
This method is used for the same purpose as DeleteLabelValues(...string). See there for pros and cons of the two methods.
func (*MetricVec) DeleteLabelValues ¶
DeleteLabelValues removes the metric where the variable labels are the same as those passed in as labels (same order as the VariableLabels in Desc). It returns true if a metric was deleted.
It is not an error if the number of label values is not the same as the number of VariableLabels in Desc. However, such inconsistent label count can never match an actual Metric, so the method will always return false in that case.
Note that for more than one label value, this method is prone to mistakes caused by an incorrect order of arguments. Consider Delete(Labels) as an alternative to avoid that type of mistake. For higher label numbers, the latter has a much more readable (albeit more verbose) syntax, but it comes with a performance overhead (for creating and processing the Labels map). See also the CounterVec example.
func (*MetricVec) Describe ¶
Describe implements Collector. The length of the returned slice is always one.
func (*MetricVec) GetMetricWith ¶
GetMetricWith returns the Metric for the given Labels map (the label names must match those of the VariableLabels in Desc). If that label map is accessed for the first time, a new Metric is created. Implications of keeping the Metric are the same as for GetMetricWithLabelValues.
An error is returned if the number and names of the Labels are inconsistent with those of the VariableLabels in Desc.
This method is used for the same purpose as GetMetricWithLabelValues(...string). See there for pros and cons of the two methods.
func (*MetricVec) GetMetricWithLabelValues ¶
GetMetricWithLabelValues returns the Metric for the given slice of label values (same order as the VariableLabels in Desc). If that combination of label values is accessed for the first time, a new Metric is created. Keeping the Metric for later use is possible (and should be considered if performance is critical), but keep in mind that Reset, DeleteLabelValues and Delete can be used to delete the Metric from the MetricVec. In that case, the Metric will still exist, but it will not be exported anymore, even if a Metric with the same label values is created later. See also the CounterVec example.
An error is returned if the number of label values is not the same as the number of VariableLabels in Desc.
Note that for more than one label value, this method is prone to mistakes caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as an alternative to avoid that type of mistake. For higher label numbers, the latter has a much more readable (albeit more verbose) syntax, but it comes with a performance overhead (for creating and processing the Labels map). See also the GaugeVec example.
func (*MetricVec) With ¶
With works as GetMetricWith, but panics if an error occurs. The method allows neat syntax like:
httpReqs.With(Labels{"status":"404", "method":"POST"}).Inc()
func (*MetricVec) WithLabelValues ¶
WithLabelValues works as GetMetricWithLabelValues, but panics if an error occurs. The method allows neat syntax like:
httpReqs.WithLabelValues("404", "POST").Inc()
type Opts ¶
type Opts struct { // Namespace, Subsystem, and Name are components of the fully-qualified // name of the Metric (created by joining these components with // "_"). Only Name is mandatory, the others merely help structuring the // name. Note that the fully-qualified name of the metric must be a // valid Prometheus metric name. Namespace string Subsystem string Name string // Help provides information about this metric. Mandatory! // // Metrics with the same fully-qualified name must have the same Help // string. Help string // ConstLabels are used to attach fixed labels to this metric. Metrics // with the same fully-qualified name must have the same label names in // their ConstLabels. // // Note that in most cases, labels have a value that varies during the // lifetime of a process. Those labels are usually managed with a metric // vector collector (like CounterVec, GaugeVec, UntypedVec). ConstLabels // serve only special purposes. One is for the special case where the // value of a label does not change during the lifetime of a process, // e.g. if the revision of the running binary is put into a // label. Another, more advanced purpose is if more than one Collector // needs to collect Metrics with the same fully-qualified name. In that // case, those Metrics must differ in the values of their // ConstLabels. See the Collector examples. // // If the value of a label never changes (not even between binaries), // that label most likely should not be a label at all (but part of the // metric name). ConstLabels Labels }
Opts bundles the options for creating most Metric types. Each metric implementation XXX has its own XXXOpts type, but in most cases, it is just be an alias of this type (which might change when the requirement arises.)
It is mandatory to set Name and Help to a non-empty string. All other fields are optional and can safely be left at their zero value.
type SelfCollector ¶
type SelfCollector struct {
// contains filtered or unexported fields
}
SelfCollector implements Collector for a single Metric so that that the Metric collects itself. Add it as an anonymous field to a struct that implements Metric, and call Init with the Metric itself as an argument.
Example ¶
package main import ( "runtime" "github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto" "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus" dto "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_model/go" ) func NewCallbackMetric(desc *prometheus.Desc, callback func() float64) *CallbackMetric { result := &CallbackMetric{desc: desc, callback: callback} result.Init(result) // Initialize the SelfCollector. return result } // TODO: Come up with a better example. // CallbackMetric is an example for a user-defined Metric that exports the // result of a function call as a metric of type "untyped" without any // labels. It uses SelfCollector to turn the Metric into a Collector so that it // can be registered with Prometheus. // // Note that this example is pretty much academic as the prometheus package // already provides an UntypedFunc type. type CallbackMetric struct { prometheus.SelfCollector desc *prometheus.Desc callback func() float64 } func (cm *CallbackMetric) Desc() *prometheus.Desc { return cm.desc } func (cm *CallbackMetric) Write(m *dto.Metric) error { m.Untyped = &dto.Untyped{Value: proto.Float64(cm.callback())} return nil } func main() { m := NewCallbackMetric( prometheus.NewDesc( "runtime_goroutines_count", "Total number of goroutines that currently exist.", nil, nil, // No labels, these must be nil. ), func() float64 { return float64(runtime.NumGoroutine()) }, ) prometheus.MustRegister(m) }
Output:
func (*SelfCollector) Collect ¶
func (c *SelfCollector) Collect(ch chan<- Metric)
Collect implements Collector.
func (*SelfCollector) Describe ¶
func (c *SelfCollector) Describe(ch chan<- *Desc)
Describe implements Collector.
func (*SelfCollector) Init ¶
func (c *SelfCollector) Init(self Metric)
Init provides the SelfCollector with a reference to the metric it is supposed to collect. It is usually called within the factory function to create a metric. See example.
type Summary ¶
type Summary interface { Metric Collector // Observe adds a single observation to the summary. Observe(float64) }
A Summary captures individual observations from an event or sample stream and summarizes them in a manner similar to traditional summary statistics: 1. sum of observations, 2. observation count, 3. rank estimations.
A typical use-case is the observation of request latencies. By default, a Summary provides the median, the 90th and the 99th percentile of the latency as rank estimations.
To create Summary instances, use NewSummary.
Example ¶
package main import ( "fmt" "math" "github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto" "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus" dto "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_model/go" ) func main() { temps := prometheus.NewSummary(prometheus.SummaryOpts{ Name: "pond_temperature_celsius", Help: "The temperature of the frog pond.", // Sorry, we can't measure how badly it smells. }) // Simulate some observations. for i := 0; i < 1000; i++ { temps.Observe(30 + math.Floor(120*math.Sin(float64(i)*0.1))/10) } // Just for demonstration, let's check the state of the summary by // (ab)using its Write method (which is usually only used by Prometheus // internally). metric := &dto.Metric{} temps.Write(metric) fmt.Println(proto.MarshalTextString(metric)) }
Output: summary: < sample_count: 1000 sample_sum: 29969.50000000001 quantile: < quantile: 0.5 value: 31.1 > quantile: < quantile: 0.9 value: 41.3 > quantile: < quantile: 0.99 value: 41.9 > >
func NewSummary ¶
func NewSummary(opts SummaryOpts) Summary
NewSummary creates a new Summary based on the provided SummaryOpts.
type SummaryOpts ¶
type SummaryOpts struct { // Namespace, Subsystem, and Name are components of the fully-qualified // name of the Summary (created by joining these components with // "_"). Only Name is mandatory, the others merely help structuring the // name. Note that the fully-qualified name of the Summary must be a // valid Prometheus metric name. Namespace string Subsystem string Name string // Help provides information about this Summary. Mandatory! // // Metrics with the same fully-qualified name must have the same Help // string. Help string // ConstLabels are used to attach fixed labels to this // Summary. Summaries with the same fully-qualified name must have the // same label names in their ConstLabels. // // Note that in most cases, labels have a value that varies during the // lifetime of a process. Those labels are usually managed with a // SummaryVec. ConstLabels serve only special purposes. One is for the // special case where the value of a label does not change during the // lifetime of a process, e.g. if the revision of the running binary is // put into a label. Another, more advanced purpose is if more than one // Collector needs to collect Summaries with the same fully-qualified // name. In that case, those Summaries must differ in the values of // their ConstLabels. See the Collector examples. // // If the value of a label never changes (not even between binaries), // that label most likely should not be a label at all (but part of the // metric name). ConstLabels Labels // Objectives defines the quantile rank estimates with their respective // absolute error. The default value is DefObjectives. Objectives map[float64]float64 // MaxAge defines the duration for which an observation stays relevant // for the summary. Must be positive. The default value is DefMaxAge. MaxAge time.Duration // AgeBuckets is the number of buckets used to exclude observations that // are older than MaxAge from the summary. A higher number has a // resource penalty, so only increase it if the higher resolution is // really required. The default value is DefAgeBuckets. AgeBuckets uint32 // BufCap defines the default sample stream buffer size. The default // value of DefBufCap should suffice for most uses. If there is a need // to increase the value, a multiple of 500 is recommended (because that // is the internal buffer size of the underlying package // "github.com/bmizerany/perks/quantile"). BufCap uint32 // Epsilon is the error epsilon for the quantile rank estimate. Must be // positive. The default is DefEpsilon. Epsilon float64 }
SummaryOpts bundles the options for creating a Summary metric. It is mandatory to set Name and Help to a non-empty string. All other fields are optional and can safely be left at their zero value.
type SummaryVec ¶
type SummaryVec struct {
MetricVec
}
SummaryVec is a Collector that bundles a set of Summaries that all share the same Desc, but have different values for their variable labels. This is used if you want to count the same thing partitioned by various dimensions (e.g. http request latencies, partitioned by status code and method). Create instances with NewSummaryVec.
Example ¶
package main import ( "fmt" "math" "sort" "github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto" "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus" dto "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_model/go" ) func main() { temps := prometheus.NewSummaryVec( prometheus.SummaryOpts{ Name: "pond_temperature_celsius", Help: "The temperature of the frog pond.", // Sorry, we can't measure how badly it smells. }, []string{"species"}, ) // Simulate some observations. for i := 0; i < 1000; i++ { temps.WithLabelValues("litoria-caerulea").Observe(30 + math.Floor(120*math.Sin(float64(i)*0.1))/10) temps.WithLabelValues("lithobates-catesbeianus").Observe(32 + math.Floor(100*math.Cos(float64(i)*0.11))/10) } // Just for demonstration, let's check the state of the summary vector // by (ab)using its Collect method and the Write method of its elements // (which is usually only used by Prometheus internally - code like the // following will never appear in your own code). metricChan := make(chan prometheus.Metric) go func() { defer close(metricChan) temps.Collect(metricChan) }() metricStrings := []string{} for metric := range metricChan { dtoMetric := &dto.Metric{} metric.Write(dtoMetric) metricStrings = append(metricStrings, proto.MarshalTextString(dtoMetric)) } sort.Strings(metricStrings) // For reproducible print order. fmt.Println(metricStrings) }
Output: [label: < name: "species" value: "lithobates-catesbeianus" > summary: < sample_count: 1000 sample_sum: 31956.100000000017 quantile: < quantile: 0.5 value: 32.4 > quantile: < quantile: 0.9 value: 41.4 > quantile: < quantile: 0.99 value: 41.9 > > label: < name: "species" value: "litoria-caerulea" > summary: < sample_count: 1000 sample_sum: 29969.50000000001 quantile: < quantile: 0.5 value: 31.1 > quantile: < quantile: 0.9 value: 41.3 > quantile: < quantile: 0.99 value: 41.9 > > ]
func NewSummaryVec ¶
func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec
NewSummaryVec creates a new SummaryVec based on the provided SummaryOpts and partitioned by the given label names. At least one label name must be provided.
func (*SummaryVec) GetMetricWith ¶
func (m *SummaryVec) GetMetricWith(labels Labels) (Summary, error)
GetMetricWith replaces the method of the same name in MetricVec. The difference is that this method returns a Summary and not a Metric so that no type conversion is required.
func (*SummaryVec) GetMetricWithLabelValues ¶
func (m *SummaryVec) GetMetricWithLabelValues(lvs ...string) (Summary, error)
GetMetricWithLabelValues replaces the method of the same name in MetricVec. The difference is that this method returns a Summary and not a Metric so that no type conversion is required.
func (*SummaryVec) With ¶
func (m *SummaryVec) With(labels Labels) Summary
With works as GetMetricWith, but panics where GetMetricWithLabels would have returned an error. By not returning an error, With allows shortcuts like
myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
func (*SummaryVec) WithLabelValues ¶
func (m *SummaryVec) WithLabelValues(lvs ...string) Summary
WithLabelValues works as GetMetricWithLabelValues, but panics where GetMetricWithLabelValues would have returned an error. By not returning an error, WithLabelValues allows shortcuts like
myVec.WithLabelValues("404", "GET").Add(42)
type Untyped ¶
type Untyped interface { Metric Collector // Set sets the Untyped metric to an arbitrary value. Set(float64) // Inc increments the Untyped metric by 1. Inc() // Dec decrements the Untyped metric by 1. Dec() // Add adds the given value to the Untyped metric. (The value can be // negative, resulting in a decrease.) Add(float64) // Sub subtracts the given value from the Untyped metric. (The value can // be negative, resulting in an increase.) Sub(float64) }
Untyped is a Metric that represents a single numerical value that can arbitrarily go up and down.
An Untyped metric works the same as a Gauge. The only difference is that to no type information is implied.
To create Gauge instances, use NewUntyped.
func NewUntyped ¶
func NewUntyped(opts UntypedOpts) Untyped
NewUntyped creates a new Untyped metric from the provided UntypedOpts.
type UntypedFunc ¶
UntypedFunc is an Untyped whose value is determined at collect time by calling a provided function.
To create UntypedFunc instances, use NewUntypedFunc.
func NewUntypedFunc ¶
func NewUntypedFunc(opts UntypedOpts, function func() float64) UntypedFunc
NewUntypedFunc creates a new UntypedFunc based on the provided UntypedOpts. The value reported is determined by calling the given function from within the Write method. Take into account that metric collection may happen concurrently. If that results in concurrent calls to Write, like in the case where an UntypedFunc is directly registered with Prometheus, the provided function must be concurrency-safe.
type UntypedOpts ¶
type UntypedOpts Opts
UntypedOpts is an alias for Opts. See there for doc comments.
type UntypedVec ¶
type UntypedVec struct {
MetricVec
}
UntypedVec is a Collector that bundles a set of Untyped metrics that all share the same Desc, but have different values for their variable labels. This is used if you want to count the same thing partitioned by various dimensions. Create instances with NewUntypedVec.
func NewUntypedVec ¶
func NewUntypedVec(opts UntypedOpts, labelNames []string) *UntypedVec
NewUntypedVec creates a new UntypedVec based on the provided UntypedOpts and partitioned by the given label names. At least one label name must be provided.
func (*UntypedVec) GetMetricWith ¶
func (m *UntypedVec) GetMetricWith(labels Labels) (Untyped, error)
GetMetricWith replaces the method of the same name in MetricVec. The difference is that this method returns an Untyped and not a Metric so that no type conversion is required.
func (*UntypedVec) GetMetricWithLabelValues ¶
func (m *UntypedVec) GetMetricWithLabelValues(lvs ...string) (Untyped, error)
GetMetricWithLabelValues replaces the method of the same name in MetricVec. The difference is that this method returns an Untyped and not a Metric so that no type conversion is required.
func (*UntypedVec) With ¶
func (m *UntypedVec) With(labels Labels) Untyped
With works as GetMetricWith, but panics where GetMetricWithLabels would have returned an error. By not returning an error, With allows shortcuts like
myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
func (*UntypedVec) WithLabelValues ¶
func (m *UntypedVec) WithLabelValues(lvs ...string) Untyped
WithLabelValues works as GetMetricWithLabelValues, but panics where GetMetricWithLabelValues would have returned an error. By not returning an error, WithLabelValues allows shortcuts like
myVec.WithLabelValues("404", "GET").Add(42)