blob: c943db6bb61cdd6040aec2da60fec1531d11fe78 [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"
27)
28
Juha Hyttinen90f6dd42020-05-08 12:17:05 +030029//-----------------------------------------------------------------------------
Mohamed Abukar2e78e422019-06-02 11:45:52 +030030// Alias
Juha Hyttinen90f6dd42020-05-08 12:17:05 +030031//-----------------------------------------------------------------------------
Juha Hyttinenf619d032020-05-07 12:42:26 +030032type CounterOpts prometheus.Opts
Mohamed Abukar2e78e422019-06-02 11:45:52 +030033type Counter prometheus.Counter
34type Gauge prometheus.Gauge
35
Juha Hyttinen90f6dd42020-05-08 12:17:05 +030036//-----------------------------------------------------------------------------
37//
38//-----------------------------------------------------------------------------
39
40type MetricGroupsCache struct {
41 Counters map[string]Counter
42 Gauges map[string]Gauge
43}
44
Juha Hyttinen622bae32020-08-10 08:20:22 +030045func (met *MetricGroupsCache) CInc(metric string) {
46 met.Counters[metric].Inc()
47}
48
49func (met *MetricGroupsCache) CAdd(metric string, val float64) {
50 met.Counters[metric].Add(val)
51}
52
53func (met *MetricGroupsCache) GSet(metric string, val float64) {
54 met.Gauges[metric].Set(val)
55}
56
Juha Hyttinen90f6dd42020-05-08 12:17:05 +030057//-----------------------------------------------------------------------------
58//
59//-----------------------------------------------------------------------------
60type Metrics struct {
61 Namespace string
62 MetricGroupsCacheMap map[string]*MetricGroupsCache
63}
64
Mohamed Abukar2e78e422019-06-02 11:45:52 +030065func NewMetrics(url, namespace string, r *mux.Router) *Metrics {
66 if url == "" {
67 url = "/ric/v1/metrics"
68 }
69 if namespace == "" {
70 namespace = "ricxapp"
71 }
72
73 Logger.Info("Serving metrics on: url=%s namespace=%s", url, namespace)
74
75 // Expose 'metrics' endpoint with standard golang metrics used by prometheus
76 r.Handle(url, promhttp.Handler())
77
Juha Hyttinen90f6dd42020-05-08 12:17:05 +030078 return &Metrics{Namespace: namespace, MetricGroupsCacheMap: make(map[string]*MetricGroupsCache)}
Mohamed Abukar2e78e422019-06-02 11:45:52 +030079}
80
Juha Hyttinenf619d032020-05-07 12:42:26 +030081/*
82 * Handling counters
83 */
84func (m *Metrics) registerCounter(opts CounterOpts) Counter {
Mohamed Abukar2e78e422019-06-02 11:45:52 +030085 Logger.Info("Register new counter with opts: %v", opts)
Mohamed Abukar2e78e422019-06-02 11:45:52 +030086 return promauto.NewCounter(prometheus.CounterOpts(opts))
87}
88
89func (m *Metrics) RegisterCounterGroup(opts []CounterOpts, subsytem string) (c map[string]Counter) {
90 c = make(map[string]Counter)
91 for _, opt := range opts {
92 opt.Namespace = m.Namespace
93 opt.Subsystem = subsytem
Juha Hyttinenf619d032020-05-07 12:42:26 +030094 c[opt.Name] = m.registerCounter(opt)
Mohamed Abukar2e78e422019-06-02 11:45:52 +030095 }
96
97 return
98}
99
Juha Hyttinenf619d032020-05-07 12:42:26 +0300100/*
101 * Handling gauges
102 */
103func (m *Metrics) registerGauge(opts CounterOpts) Gauge {
Mohamed Abukar2e78e422019-06-02 11:45:52 +0300104 Logger.Info("Register new gauge with opts: %v", opts)
Mohamed Abukar2e78e422019-06-02 11:45:52 +0300105 return promauto.NewGauge(prometheus.GaugeOpts(opts))
106}
107
108func (m *Metrics) RegisterGaugeGroup(opts []CounterOpts, subsytem string) (c map[string]Gauge) {
109 c = make(map[string]Gauge)
110 for _, opt := range opts {
111 opt.Namespace = m.Namespace
112 opt.Subsystem = subsytem
Juha Hyttinenf619d032020-05-07 12:42:26 +0300113 c[opt.Name] = m.registerGauge(opt)
Mohamed Abukar2e78e422019-06-02 11:45:52 +0300114 }
115
116 return
117}
Juha Hyttinenf619d032020-05-07 12:42:26 +0300118
119/*
120 * Handling counter vectors
121 *
122 * Example:
123
124 vec := Metric.RegisterCounterVecGroup(
125 []CounterOpts{
126 {Name: "counter1", Help: "counter1"},
127 {Name: "counter2", Help: "counter2"},
128 },
129 []string{"host"},
130 "SUBSYSTEM")
131
132 stat:=Metric.GetCounterGroupFromVects([]string{"localhost:8888"}, vec)
133
134*/
135type CounterVec struct {
136 Vec *prometheus.CounterVec
137 Opts CounterOpts
138}
139
140func (m *Metrics) registerCounterVec(opts CounterOpts, labelNames []string) *prometheus.CounterVec {
141 Logger.Info("Register new counter vector with opts: %v labelNames: %v", opts, labelNames)
142
143 return promauto.NewCounterVec(prometheus.CounterOpts(opts), labelNames)
144}
145
146func (m *Metrics) RegisterCounterVecGroup(opts []CounterOpts, labelNames []string, subsytem string) (c map[string]CounterVec) {
147 c = make(map[string]CounterVec)
148 for _, opt := range opts {
149 entry := CounterVec{}
150 entry.Opts = opt
151 entry.Opts.Namespace = m.Namespace
152 entry.Opts.Subsystem = subsytem
153 entry.Vec = m.registerCounterVec(entry.Opts, labelNames)
154 c[opt.Name] = entry
155 }
156 return
157}
158
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300159func (m *Metrics) GetCounterGroupFromVectsWithPrefix(prefix string, labels []string, vects ...map[string]CounterVec) (c map[string]Counter) {
Juha Hyttinenf619d032020-05-07 12:42:26 +0300160 c = make(map[string]Counter)
161 for _, vec := range vects {
162 for name, opt := range vec {
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300163 c[prefix+name] = opt.Vec.WithLabelValues(labels...)
Juha Hyttinenf619d032020-05-07 12:42:26 +0300164 Logger.Info("Register new counter for vector with opts: %v labels: %v", opt.Opts, labels)
165 }
166 }
167 return
168}
169
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300170func (m *Metrics) GetCounterGroupFromVects(labels []string, vects ...map[string]CounterVec) (c map[string]Counter) {
171 return m.GetCounterGroupFromVectsWithPrefix("", labels, vects...)
172}
173
Juha Hyttinenf619d032020-05-07 12:42:26 +0300174/*
175 * Handling gauge vectors
176 *
177 * Example:
178
179 vec := Metric.RegisterGaugeVecGroup(
180 []CounterOpts{
181 {Name: "gauge1", Help: "gauge1"},
182 {Name: "gauge2", Help: "gauge2"},
183 },
184 []string{"host"},
185 "SUBSYSTEM")
186
187 stat:=Metric.GetGaugeGroupFromVects([]string{"localhost:8888"},vec)
188
189*/
190type GaugeVec struct {
191 Vec *prometheus.GaugeVec
192 Opts CounterOpts
193}
194
195func (m *Metrics) registerGaugeVec(opts CounterOpts, labelNames []string) *prometheus.GaugeVec {
196 Logger.Info("Register new gauge vector with opts: %v labelNames: %v", opts, labelNames)
197
198 return promauto.NewGaugeVec(prometheus.GaugeOpts(opts), labelNames)
199}
200
201func (m *Metrics) RegisterGaugeVecGroup(opts []CounterOpts, labelNames []string, subsytem string) (c map[string]GaugeVec) {
202 c = make(map[string]GaugeVec)
203 for _, opt := range opts {
204 entry := GaugeVec{}
205 entry.Opts = opt
206 entry.Opts.Namespace = m.Namespace
207 entry.Opts.Subsystem = subsytem
208 entry.Vec = m.registerGaugeVec(entry.Opts, labelNames)
209 c[opt.Name] = entry
210
211 }
212 return
213}
214
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300215func (m *Metrics) GetGaugeGroupFromVectsWithPrefix(prefix string, labels []string, vects ...map[string]GaugeVec) (c map[string]Gauge) {
Juha Hyttinenf619d032020-05-07 12:42:26 +0300216 c = make(map[string]Gauge)
217 for _, vec := range vects {
218 for name, opt := range vec {
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300219 c[prefix+name] = opt.Vec.WithLabelValues(labels...)
Juha Hyttinenf619d032020-05-07 12:42:26 +0300220 Logger.Info("Register new gauge for vector with opts: %v labels: %v", opt.Opts, labels)
221 }
222 }
223 return
224}
225
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300226func (m *Metrics) GetGaugeGroupFromVects(labels []string, vects ...map[string]GaugeVec) (c map[string]Gauge) {
227 return m.GetGaugeGroupFromVectsWithPrefix("", labels, vects...)
228
229}
230
Juha Hyttinenf619d032020-05-07 12:42:26 +0300231/*
232 *
233 */
234func (m *Metrics) CombineCounterGroups(srcs ...map[string]Counter) map[string]Counter {
235 trg := make(map[string]Counter)
236 for _, src := range srcs {
237 for k, v := range src {
238 trg[k] = v
239 }
240 }
241 return trg
242}
243
244func (m *Metrics) CombineGaugeGroups(srcs ...map[string]Gauge) map[string]Gauge {
245 trg := make(map[string]Gauge)
246 for _, src := range srcs {
247 for k, v := range src {
248 trg[k] = v
249 }
250 }
251 return trg
252}
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300253
254/*
255 *
256 */
257func (m *Metrics) GroupCacheGet(id string) *MetricGroupsCache {
258 entry, ok := m.MetricGroupsCacheMap[id]
259 if ok == false {
260 return nil
261 }
262 return entry
263}
264
265func (m *Metrics) GroupCacheAddCounters(id string, vals map[string]Counter) {
266 entry, ok := m.MetricGroupsCacheMap[id]
267 if ok == false {
268 entry = &MetricGroupsCache{}
269 m.MetricGroupsCacheMap[id] = entry
270 }
271 m.MetricGroupsCacheMap[id].Counters = m.CombineCounterGroups(m.MetricGroupsCacheMap[id].Counters, vals)
272}
273
274func (m *Metrics) GroupCacheAddGauges(id string, vals map[string]Gauge) {
275 entry, ok := m.MetricGroupsCacheMap[id]
276 if ok == false {
277 entry = &MetricGroupsCache{}
278 m.MetricGroupsCacheMap[id] = entry
279 }
280 m.MetricGroupsCacheMap[id].Gauges = m.CombineGaugeGroups(m.MetricGroupsCacheMap[id].Gauges, vals)
281}