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	"expvar"
18	"fmt"
19	"sort"
20	"strings"
21
22	dto "github.com/prometheus/client_model/go"
23
24	"github.com/prometheus/client_golang/prometheus"
25)
26
27func ExampleNewExpvarCollector() {
28	expvarCollector := prometheus.NewExpvarCollector(map[string]*prometheus.Desc{
29		"memstats": prometheus.NewDesc(
30			"expvar_memstats",
31			"All numeric memstats as one metric family. Not a good role-model, actually... ;-)",
32			[]string{"type"}, nil,
33		),
34		"lone-int": prometheus.NewDesc(
35			"expvar_lone_int",
36			"Just an expvar int as an example.",
37			nil, nil,
38		),
39		"http-request-map": prometheus.NewDesc(
40			"expvar_http_request_total",
41			"How many http requests processed, partitioned by status code and http method.",
42			[]string{"code", "method"}, nil,
43		),
44	})
45	prometheus.MustRegister(expvarCollector)
46
47	// The Prometheus part is done here. But to show that this example is
48	// doing anything, we have to manually export something via expvar.  In
49	// real-life use-cases, some library would already have exported via
50	// expvar what we want to re-export as Prometheus metrics.
51	expvar.NewInt("lone-int").Set(42)
52	expvarMap := expvar.NewMap("http-request-map")
53	var (
54		expvarMap1, expvarMap2                             expvar.Map
55		expvarInt11, expvarInt12, expvarInt21, expvarInt22 expvar.Int
56	)
57	expvarMap1.Init()
58	expvarMap2.Init()
59	expvarInt11.Set(3)
60	expvarInt12.Set(13)
61	expvarInt21.Set(11)
62	expvarInt22.Set(212)
63	expvarMap1.Set("POST", &expvarInt11)
64	expvarMap1.Set("GET", &expvarInt12)
65	expvarMap2.Set("POST", &expvarInt21)
66	expvarMap2.Set("GET", &expvarInt22)
67	expvarMap.Set("404", &expvarMap1)
68	expvarMap.Set("200", &expvarMap2)
69	// Results in the following expvar map:
70	// "http-request-count": {"200": {"POST": 11, "GET": 212}, "404": {"POST": 3, "GET": 13}}
71
72	// Let's see what the scrape would yield, but exclude the memstats metrics.
73	metricStrings := []string{}
74	metric := dto.Metric{}
75	metricChan := make(chan prometheus.Metric)
76	go func() {
77		expvarCollector.Collect(metricChan)
78		close(metricChan)
79	}()
80	for m := range metricChan {
81		if !strings.Contains(m.Desc().String(), "expvar_memstats") {
82			metric.Reset()
83			m.Write(&metric)
84			metricStrings = append(metricStrings, metric.String())
85		}
86	}
87	sort.Strings(metricStrings)
88	for _, s := range metricStrings {
89		fmt.Println(strings.TrimRight(s, " "))
90	}
91	// Output:
92	// label:<name:"code" value:"200" > label:<name:"method" value:"GET" > untyped:<value:212 >
93	// label:<name:"code" value:"200" > label:<name:"method" value:"POST" > untyped:<value:11 >
94	// label:<name:"code" value:"404" > label:<name:"method" value:"GET" > untyped:<value:13 >
95	// label:<name:"code" value:"404" > label:<name:"method" value:"POST" > untyped:<value:3 >
96	// untyped:<value:42 >
97}
98