...
1 package prometheus
2
3 import (
4 "fmt"
5 dto "github.com/prometheus/client_model/go"
6 "sync"
7 "time"
8 )
9
10 var (
11 tlock sync.Mutex
12 tracker_arrays = make(map[string][]*metrictracker)
13 )
14
15 type metrictracker struct {
16 name string
17 labels map[string]string
18 lastUpdated time.Time
19 }
20
21 func label_map_string(m map[string]string) string {
22 s := ""
23 for k, v := range m {
24 s = s + k + "=" + v + ","
25 }
26 return s
27 }
28 func (p *promRegistry) find_or_create_metric(metricname string, labels map[string]string) *metrictracker {
29 tlock.Lock()
30 defer tlock.Unlock()
31 lms := label_map_string(labels)
32 trackers := tracker_arrays[lms]
33 for _, t := range trackers {
34 if t.name != metricname {
35 continue
36 }
37 if isEqualMap(labels, t.labels) {
38 return t
39 }
40 }
41 t := &metrictracker{name: metricname, labels: labels, lastUpdated: time.Now()}
42
43 tracker_arrays[lms] = append(tracker_arrays[lms], t)
44 return t
45 }
46 func (p *promRegistry) find_metric(metricname string, labels map[string]string) *metrictracker {
47 tlock.Lock()
48 defer tlock.Unlock()
49 lms := label_map_string(labels)
50 trackers := tracker_arrays[lms]
51 for _, t := range trackers {
52 if t.name != metricname {
53 continue
54 }
55 if isEqualMap(labels, t.labels) {
56 return t
57 }
58 }
59 return nil
60 }
61 func (m *metrictracker) String() string {
62 ls := ""
63 deli := ""
64 for k, v := range m.labels {
65 ls = ls + deli + k + "=\"" + v + "\""
66 deli = ","
67 }
68 return fmt.Sprintf("%s{%s}", m.name, ls)
69 }
70 func (m *metrictracker) update() {
71 m.lastUpdated = time.Now()
72 }
73
74
75 func (p *promRegistry) used(metricname string, labels map[string]string) {
76 p.find_or_create_metric(metricname, labels).update()
77 }
78 func (p *promRegistry) recently_used_family(mf *dto.MetricFamily, maxage time.Duration) *dto.MetricFamily {
79 var rm []*dto.Metric
80 for _, m := range mf.Metric {
81 l := make(map[string]string)
82 for _, lp := range m.Label {
83 l[*lp.Name] = l[*lp.Value]
84 }
85 mt := p.find_metric(*mf.Name, l)
86 if mt == nil {
87
88 rm = append(rm, m)
89 continue
90 }
91 if time.Since(mt.lastUpdated) > maxage {
92
93 continue
94 }
95 rm = append(rm, m)
96 }
97 mf.Metric = rm
98 return mf
99 }
100
101 func isEqualMap(a1, a2 map[string]string) bool {
102 if a1 == nil && a2 == nil {
103 return true
104 }
105 if a1 == nil || a2 == nil {
106 return false
107 }
108 if len(a1) != len(a2) {
109 return false
110 }
111 for k, v := range a1 {
112 if a2[k] != v {
113 return false
114 }
115 }
116 return true
117 }
118
View as plain text