blob: 73a9b62179f887cde2c1c1ec05daf07b81a2b066 [file] [log] [blame]
Mohamed Abukar2e78e422019-06-02 11:45:52 +03001/*
2==================================================================================
3 Copyright (c) 2019 AT&T Intellectual Property.
4 Copyright (c) 2019 Nokia
5
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17==================================================================================
18*/
19
20package xapp
21
22import (
23 "github.com/gorilla/mux"
24 "github.com/prometheus/client_golang/prometheus"
25 "github.com/prometheus/client_golang/prometheus/promauto"
26 "github.com/prometheus/client_golang/prometheus/promhttp"
Juha Hyttinen64924382020-10-08 14:06:57 +030027 "sync"
Mohamed Abukar2e78e422019-06-02 11:45:52 +030028)
29
Juha Hyttinen90f6dd42020-05-08 12:17:05 +030030//-----------------------------------------------------------------------------
Mohamed Abukar2e78e422019-06-02 11:45:52 +030031// Alias
Juha Hyttinen90f6dd42020-05-08 12:17:05 +030032//-----------------------------------------------------------------------------
Juha Hyttinenf619d032020-05-07 12:42:26 +030033type CounterOpts prometheus.Opts
Mohamed Abukar2e78e422019-06-02 11:45:52 +030034type Counter prometheus.Counter
35type Gauge prometheus.Gauge
36
Juha Hyttinen90f6dd42020-05-08 12:17:05 +030037//-----------------------------------------------------------------------------
38//
39//-----------------------------------------------------------------------------
40
41type MetricGroupsCache struct {
42 Counters map[string]Counter
43 Gauges map[string]Gauge
44}
45
Juha Hyttinen622bae32020-08-10 08:20:22 +030046func (met *MetricGroupsCache) CInc(metric string) {
47 met.Counters[metric].Inc()
48}
49
50func (met *MetricGroupsCache) CAdd(metric string, val float64) {
51 met.Counters[metric].Add(val)
52}
53
54func (met *MetricGroupsCache) GSet(metric string, val float64) {
55 met.Gauges[metric].Set(val)
56}
57
Juha Hyttinen90f6dd42020-05-08 12:17:05 +030058//-----------------------------------------------------------------------------
59//
60//-----------------------------------------------------------------------------
61type Metrics struct {
Juha Hyttinen64924382020-10-08 14:06:57 +030062 lock sync.Mutex
Juha Hyttinen90f6dd42020-05-08 12:17:05 +030063 Namespace string
64 MetricGroupsCacheMap map[string]*MetricGroupsCache
65}
66
Mohamed Abukar2e78e422019-06-02 11:45:52 +030067func NewMetrics(url, namespace string, r *mux.Router) *Metrics {
68 if url == "" {
69 url = "/ric/v1/metrics"
70 }
71 if namespace == "" {
72 namespace = "ricxapp"
73 }
74
75 Logger.Info("Serving metrics on: url=%s namespace=%s", url, namespace)
76
77 // Expose 'metrics' endpoint with standard golang metrics used by prometheus
78 r.Handle(url, promhttp.Handler())
79
Juha Hyttinen90f6dd42020-05-08 12:17:05 +030080 return &Metrics{Namespace: namespace, MetricGroupsCacheMap: make(map[string]*MetricGroupsCache)}
Mohamed Abukar2e78e422019-06-02 11:45:52 +030081}
82
Juha Hyttinenf619d032020-05-07 12:42:26 +030083/*
84 * Handling counters
85 */
86func (m *Metrics) registerCounter(opts CounterOpts) Counter {
Mohamed Abukar2e78e422019-06-02 11:45:52 +030087 Logger.Info("Register new counter with opts: %v", opts)
Mohamed Abukar2e78e422019-06-02 11:45:52 +030088 return promauto.NewCounter(prometheus.CounterOpts(opts))
89}
90
91func (m *Metrics) RegisterCounterGroup(opts []CounterOpts, subsytem string) (c map[string]Counter) {
92 c = make(map[string]Counter)
93 for _, opt := range opts {
94 opt.Namespace = m.Namespace
95 opt.Subsystem = subsytem
Juha Hyttinenf619d032020-05-07 12:42:26 +030096 c[opt.Name] = m.registerCounter(opt)
Mohamed Abukar2e78e422019-06-02 11:45:52 +030097 }
98
99 return
100}
101
Juha Hyttinenf619d032020-05-07 12:42:26 +0300102/*
103 * Handling gauges
104 */
105func (m *Metrics) registerGauge(opts CounterOpts) Gauge {
Mohamed Abukar2e78e422019-06-02 11:45:52 +0300106 Logger.Info("Register new gauge with opts: %v", opts)
Mohamed Abukar2e78e422019-06-02 11:45:52 +0300107 return promauto.NewGauge(prometheus.GaugeOpts(opts))
108}
109
110func (m *Metrics) RegisterGaugeGroup(opts []CounterOpts, subsytem string) (c map[string]Gauge) {
111 c = make(map[string]Gauge)
112 for _, opt := range opts {
113 opt.Namespace = m.Namespace
114 opt.Subsystem = subsytem
Juha Hyttinenf619d032020-05-07 12:42:26 +0300115 c[opt.Name] = m.registerGauge(opt)
Mohamed Abukar2e78e422019-06-02 11:45:52 +0300116 }
117
118 return
119}
Juha Hyttinenf619d032020-05-07 12:42:26 +0300120
121/*
122 * Handling counter vectors
123 *
124 * Example:
125
126 vec := Metric.RegisterCounterVecGroup(
127 []CounterOpts{
128 {Name: "counter1", Help: "counter1"},
129 {Name: "counter2", Help: "counter2"},
130 },
131 []string{"host"},
132 "SUBSYSTEM")
133
134 stat:=Metric.GetCounterGroupFromVects([]string{"localhost:8888"}, vec)
135
136*/
137type CounterVec struct {
138 Vec *prometheus.CounterVec
139 Opts CounterOpts
140}
141
142func (m *Metrics) registerCounterVec(opts CounterOpts, labelNames []string) *prometheus.CounterVec {
143 Logger.Info("Register new counter vector with opts: %v labelNames: %v", opts, labelNames)
144
145 return promauto.NewCounterVec(prometheus.CounterOpts(opts), labelNames)
146}
147
148func (m *Metrics) RegisterCounterVecGroup(opts []CounterOpts, labelNames []string, subsytem string) (c map[string]CounterVec) {
149 c = make(map[string]CounterVec)
150 for _, opt := range opts {
151 entry := CounterVec{}
152 entry.Opts = opt
153 entry.Opts.Namespace = m.Namespace
154 entry.Opts.Subsystem = subsytem
155 entry.Vec = m.registerCounterVec(entry.Opts, labelNames)
156 c[opt.Name] = entry
157 }
158 return
159}
160
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300161func (m *Metrics) GetCounterGroupFromVectsWithPrefix(prefix string, labels []string, vects ...map[string]CounterVec) (c map[string]Counter) {
Juha Hyttinenf619d032020-05-07 12:42:26 +0300162 c = make(map[string]Counter)
163 for _, vec := range vects {
164 for name, opt := range vec {
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300165 c[prefix+name] = opt.Vec.WithLabelValues(labels...)
Juha Hyttinenf619d032020-05-07 12:42:26 +0300166 Logger.Info("Register new counter for vector with opts: %v labels: %v", opt.Opts, labels)
167 }
168 }
169 return
170}
171
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300172func (m *Metrics) GetCounterGroupFromVects(labels []string, vects ...map[string]CounterVec) (c map[string]Counter) {
173 return m.GetCounterGroupFromVectsWithPrefix("", labels, vects...)
174}
175
Juha Hyttinenf619d032020-05-07 12:42:26 +0300176/*
177 * Handling gauge vectors
178 *
179 * Example:
180
181 vec := Metric.RegisterGaugeVecGroup(
182 []CounterOpts{
183 {Name: "gauge1", Help: "gauge1"},
184 {Name: "gauge2", Help: "gauge2"},
185 },
186 []string{"host"},
187 "SUBSYSTEM")
188
189 stat:=Metric.GetGaugeGroupFromVects([]string{"localhost:8888"},vec)
190
191*/
192type GaugeVec struct {
193 Vec *prometheus.GaugeVec
194 Opts CounterOpts
195}
196
197func (m *Metrics) registerGaugeVec(opts CounterOpts, labelNames []string) *prometheus.GaugeVec {
198 Logger.Info("Register new gauge vector with opts: %v labelNames: %v", opts, labelNames)
199
200 return promauto.NewGaugeVec(prometheus.GaugeOpts(opts), labelNames)
201}
202
203func (m *Metrics) RegisterGaugeVecGroup(opts []CounterOpts, labelNames []string, subsytem string) (c map[string]GaugeVec) {
204 c = make(map[string]GaugeVec)
205 for _, opt := range opts {
206 entry := GaugeVec{}
207 entry.Opts = opt
208 entry.Opts.Namespace = m.Namespace
209 entry.Opts.Subsystem = subsytem
210 entry.Vec = m.registerGaugeVec(entry.Opts, labelNames)
211 c[opt.Name] = entry
212
213 }
214 return
215}
216
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300217func (m *Metrics) GetGaugeGroupFromVectsWithPrefix(prefix string, labels []string, vects ...map[string]GaugeVec) (c map[string]Gauge) {
Juha Hyttinenf619d032020-05-07 12:42:26 +0300218 c = make(map[string]Gauge)
219 for _, vec := range vects {
220 for name, opt := range vec {
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300221 c[prefix+name] = opt.Vec.WithLabelValues(labels...)
Juha Hyttinenf619d032020-05-07 12:42:26 +0300222 Logger.Info("Register new gauge for vector with opts: %v labels: %v", opt.Opts, labels)
223 }
224 }
225 return
226}
227
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300228func (m *Metrics) GetGaugeGroupFromVects(labels []string, vects ...map[string]GaugeVec) (c map[string]Gauge) {
229 return m.GetGaugeGroupFromVectsWithPrefix("", labels, vects...)
230
231}
232
Juha Hyttinenf619d032020-05-07 12:42:26 +0300233/*
234 *
235 */
236func (m *Metrics) CombineCounterGroups(srcs ...map[string]Counter) map[string]Counter {
237 trg := make(map[string]Counter)
238 for _, src := range srcs {
239 for k, v := range src {
240 trg[k] = v
241 }
242 }
243 return trg
244}
245
246func (m *Metrics) CombineGaugeGroups(srcs ...map[string]Gauge) map[string]Gauge {
247 trg := make(map[string]Gauge)
248 for _, src := range srcs {
249 for k, v := range src {
250 trg[k] = v
251 }
252 }
253 return trg
254}
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300255
256/*
257 *
258 */
259func (m *Metrics) GroupCacheGet(id string) *MetricGroupsCache {
Juha Hyttinen64924382020-10-08 14:06:57 +0300260 m.lock.Lock()
261 defer m.lock.Unlock()
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300262 entry, ok := m.MetricGroupsCacheMap[id]
263 if ok == false {
264 return nil
265 }
266 return entry
267}
268
269func (m *Metrics) GroupCacheAddCounters(id string, vals map[string]Counter) {
Juha Hyttinen64924382020-10-08 14:06:57 +0300270 m.lock.Lock()
271 defer m.lock.Unlock()
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300272 entry, ok := m.MetricGroupsCacheMap[id]
273 if ok == false {
274 entry = &MetricGroupsCache{}
275 m.MetricGroupsCacheMap[id] = entry
276 }
277 m.MetricGroupsCacheMap[id].Counters = m.CombineCounterGroups(m.MetricGroupsCacheMap[id].Counters, vals)
278}
279
280func (m *Metrics) GroupCacheAddGauges(id string, vals map[string]Gauge) {
Juha Hyttinen64924382020-10-08 14:06:57 +0300281 m.lock.Lock()
282 defer m.lock.Unlock()
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300283 entry, ok := m.MetricGroupsCacheMap[id]
284 if ok == false {
285 entry = &MetricGroupsCache{}
286 m.MetricGroupsCacheMap[id] = entry
287 }
288 m.MetricGroupsCacheMap[id].Gauges = m.CombineGaugeGroups(m.MetricGroupsCacheMap[id].Gauges, vals)
289}