...
1 package prometheus
2
3 import (
4 "fmt"
5 pm "github.com/prometheus/client_golang/prometheus"
6 dto "github.com/prometheus/client_model/go"
7
8 "strings"
9 "sync"
10 "time"
11 )
12
13 var (
14 lock sync.Mutex
15 promreg = &promRegistry{Expiry: time.Duration(5) * time.Minute}
16 )
17
18 type Labels pm.Labels
19
20 type HistogramOpts pm.HistogramOpts
21 type GaugeOpts pm.GaugeOpts
22 type SummaryOpts pm.SummaryOpts
23 type CounterOpts pm.CounterOpts
24
25
34 func NewHistogramVec(opts HistogramOpts, label_names []string) *HistogramVec {
35 return (&HistogramVec{opts: opts, labelnames: label_names}).init()
36 }
37 func NewHistogram(opts HistogramOpts) *HistogramVec {
38 return (&HistogramVec{opts: opts, labelnames: []string{}}).init()
39 }
40 func NewSummaryVec(opts SummaryOpts, label_names []string) *SummaryVec {
41 if opts.Objectives == nil || len(opts.Objectives) == 0 {
42 opts.Objectives = map[float64]float64{
43 0.2: 0.2,
44 0.5: 0.5,
45 0.9: 0.9,
46 0.99: 0.99,
47 }
48 }
49 return (&SummaryVec{opts: opts, labelnames: label_names}).init()
50 }
51 func NewSummary(opts SummaryOpts) *SummaryVec {
52 return (&SummaryVec{opts: opts, labelnames: []string{}}).init()
53 }
54 func NewCounterVec(opts CounterOpts, label_names []string) *CounterVec {
55 return (&CounterVec{opts: opts, labelnames: label_names}).init()
56 }
57 func NewCounter(opts CounterOpts) *CounterVec {
58 return (&CounterVec{opts: opts, labelnames: []string{}}).init()
59 }
60 func NewGaugeVec(opts GaugeOpts, label_names []string) *GaugeVec {
61 return (&GaugeVec{opts: opts, labelnames: label_names}).init()
62 }
63 func NewGauge(opts GaugeOpts) *GaugeVec {
64 return (&GaugeVec{opts: opts, labelnames: []string{}}).init()
65 }
66
67 func MustRegister(cols ...pm.Collector) {
68 for _, c := range cols {
69
70
71 promreg.MustRegister(c)
72 }
73 }
74 func Register(cols ...pm.Collector) error {
75 for _, c := range cols {
76
77
78 e := promreg.Register(c)
79 if e != nil {
80 return e
81 }
82 }
83 return nil
84 }
85
86 type promRegistry struct {
87 reg *pm.Registry
88 Expiry time.Duration
89 }
90
91 func (p *promRegistry) MustRegister(c pm.Collector) {
92 e := p.Register(c)
93 if e == nil {
94 return
95 }
96 fmt.Printf("Metric registration of %v failed: %s\n", c, e)
97 panic("Metric registration failed")
98 }
99
100 func (p *promRegistry) Register(c pm.Collector) error {
101 if p.reg == nil {
102 lock.Lock()
103 if p.reg == nil {
104 p.reg = pm.NewRegistry()
105
106 p.reg.MustRegister(pm.NewGoCollector())
107
108 p.reg.MustRegister(pm.NewProcessCollector(pm.ProcessCollectorOpts{}))
109 }
110 lock.Unlock()
111 }
112 e := p.reg.Register(c)
113 return e
114 }
115
116 func GetRegistry() *pm.Registry {
117 return promreg.reg
118 }
119 func GetGatherer() *promRegistry {
120 return promreg
121 }
122 func (p *promRegistry) Gather() ([]*dto.MetricFamily, error) {
123 var d []*dto.MetricFamily
124 dmf, err := p.reg.Gather()
125 if err != nil {
126 return nil, err
127 }
128 if p.Expiry == 0 {
129 return dmf, nil
130 }
131
132 for _, mf := range dmf {
133 usedonly := p.recently_used_family(mf, p.Expiry)
134 if len(usedonly.Metric) > 0 {
135 d = append(d, usedonly)
136 }
137 }
138
139 return d, nil
140 }
141
142 func MetricNames(reg *pm.Registry) ([]string, error) {
143 dtm, err := reg.Gather()
144 if err != nil {
145 return nil, err
146 }
147 ml := make(map[string]bool)
148 for _, mf := range dtm {
149 ml[*mf.Name] = true
150 }
151 var res []string
152 for k, _ := range ml {
153 res = append(res, k)
154 }
155 return res, nil
156 }
157 func NonstandMetricNames(reg *pm.Registry) ([]string, error) {
158 mn, err := MetricNames(reg)
159 if err != nil {
160 return nil, err
161 }
162 var res []string
163 for _, m := range mn {
164 if strings.HasPrefix(m, "go_") {
165 continue
166 }
167 if strings.HasPrefix(m, "process_") {
168 continue
169 }
170 res = append(res, m)
171 }
172 return res, nil
173 }
174
175 func SetExpiry(expiry time.Duration) {
176 promreg.Expiry = expiry
177 }
178
View as plain text