1// Copyright 2014 The Prometheus Authors
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14package prometheus_test
15
16import (
17	"runtime"
18
19	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus"
20)
21
22var (
23	allocDesc = prometheus.NewDesc(
24		prometheus.BuildFQName("", "memstats", "alloc_bytes"),
25		"bytes allocated and still in use",
26		nil, nil,
27	)
28	totalAllocDesc = prometheus.NewDesc(
29		prometheus.BuildFQName("", "memstats", "total_alloc_bytes"),
30		"bytes allocated (even if freed)",
31		nil, nil,
32	)
33	numGCDesc = prometheus.NewDesc(
34		prometheus.BuildFQName("", "memstats", "num_gc_total"),
35		"number of GCs run",
36		nil, nil,
37	)
38)
39
40// MemStatsCollector is an example for a custom Collector that solves the
41// problem of feeding into multiple metrics at the same time. The
42// runtime.ReadMemStats should happen only once, and then the results need to be
43// fed into a number of separate Metrics. In this example, only a few of the
44// values reported by ReadMemStats are used. For each, there is a Desc provided
45// as a var, so the MemStatsCollector itself needs nothing else in the
46// struct. Only the methods need to be implemented.
47type MemStatsCollector struct{}
48
49// Describe just sends the three Desc objects for the Metrics we intend to
50// collect.
51func (_ MemStatsCollector) Describe(ch chan<- *prometheus.Desc) {
52	ch <- allocDesc
53	ch <- totalAllocDesc
54	ch <- numGCDesc
55}
56
57// Collect does the trick by calling ReadMemStats once and then constructing
58// three different Metrics on the fly.
59func (_ MemStatsCollector) Collect(ch chan<- prometheus.Metric) {
60	var ms runtime.MemStats
61	runtime.ReadMemStats(&ms)
62	ch <- prometheus.MustNewConstMetric(
63		allocDesc,
64		prometheus.GaugeValue,
65		float64(ms.Alloc),
66	)
67	ch <- prometheus.MustNewConstMetric(
68		totalAllocDesc,
69		prometheus.GaugeValue,
70		float64(ms.TotalAlloc),
71	)
72	ch <- prometheus.MustNewConstMetric(
73		numGCDesc,
74		prometheus.CounterValue,
75		float64(ms.NumGC),
76	)
77	// To avoid new allocations on each collection, you could also keep
78	// metric objects around and return the same objects each time, just
79	// with new values set.
80}
81
82func ExampleCollector_memstats() {
83	prometheus.MustRegister(&MemStatsCollector{})
84	// Since we are dealing with custom Collector implementations, it might
85	// be a good idea to enable the collect checks in the registry.
86	prometheus.EnableCollectChecks(true)
87}
88