blob: aa4b0f757bef8156f89d98bc02bb050e849b9cdb [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
45//-----------------------------------------------------------------------------
46//
47//-----------------------------------------------------------------------------
48type Metrics struct {
49 Namespace string
50 MetricGroupsCacheMap map[string]*MetricGroupsCache
51}
52
Mohamed Abukar2e78e422019-06-02 11:45:52 +030053func NewMetrics(url, namespace string, r *mux.Router) *Metrics {
54 if url == "" {
55 url = "/ric/v1/metrics"
56 }
57 if namespace == "" {
58 namespace = "ricxapp"
59 }
60
61 Logger.Info("Serving metrics on: url=%s namespace=%s", url, namespace)
62
63 // Expose 'metrics' endpoint with standard golang metrics used by prometheus
64 r.Handle(url, promhttp.Handler())
65
Juha Hyttinen90f6dd42020-05-08 12:17:05 +030066 return &Metrics{Namespace: namespace, MetricGroupsCacheMap: make(map[string]*MetricGroupsCache)}
Mohamed Abukar2e78e422019-06-02 11:45:52 +030067}
68
Juha Hyttinenf619d032020-05-07 12:42:26 +030069/*
70 * Handling counters
71 */
72func (m *Metrics) registerCounter(opts CounterOpts) Counter {
Mohamed Abukar2e78e422019-06-02 11:45:52 +030073 Logger.Info("Register new counter with opts: %v", opts)
Mohamed Abukar2e78e422019-06-02 11:45:52 +030074 return promauto.NewCounter(prometheus.CounterOpts(opts))
75}
76
77func (m *Metrics) RegisterCounterGroup(opts []CounterOpts, subsytem string) (c map[string]Counter) {
78 c = make(map[string]Counter)
79 for _, opt := range opts {
80 opt.Namespace = m.Namespace
81 opt.Subsystem = subsytem
Juha Hyttinenf619d032020-05-07 12:42:26 +030082 c[opt.Name] = m.registerCounter(opt)
Mohamed Abukar2e78e422019-06-02 11:45:52 +030083 }
84
85 return
86}
87
Juha Hyttinenf619d032020-05-07 12:42:26 +030088/*
89 * Handling gauges
90 */
91func (m *Metrics) registerGauge(opts CounterOpts) Gauge {
Mohamed Abukar2e78e422019-06-02 11:45:52 +030092 Logger.Info("Register new gauge with opts: %v", opts)
Mohamed Abukar2e78e422019-06-02 11:45:52 +030093 return promauto.NewGauge(prometheus.GaugeOpts(opts))
94}
95
96func (m *Metrics) RegisterGaugeGroup(opts []CounterOpts, subsytem string) (c map[string]Gauge) {
97 c = make(map[string]Gauge)
98 for _, opt := range opts {
99 opt.Namespace = m.Namespace
100 opt.Subsystem = subsytem
Juha Hyttinenf619d032020-05-07 12:42:26 +0300101 c[opt.Name] = m.registerGauge(opt)
Mohamed Abukar2e78e422019-06-02 11:45:52 +0300102 }
103
104 return
105}
Juha Hyttinenf619d032020-05-07 12:42:26 +0300106
107/*
108 * Handling counter vectors
109 *
110 * Example:
111
112 vec := Metric.RegisterCounterVecGroup(
113 []CounterOpts{
114 {Name: "counter1", Help: "counter1"},
115 {Name: "counter2", Help: "counter2"},
116 },
117 []string{"host"},
118 "SUBSYSTEM")
119
120 stat:=Metric.GetCounterGroupFromVects([]string{"localhost:8888"}, vec)
121
122*/
123type CounterVec struct {
124 Vec *prometheus.CounterVec
125 Opts CounterOpts
126}
127
128func (m *Metrics) registerCounterVec(opts CounterOpts, labelNames []string) *prometheus.CounterVec {
129 Logger.Info("Register new counter vector with opts: %v labelNames: %v", opts, labelNames)
130
131 return promauto.NewCounterVec(prometheus.CounterOpts(opts), labelNames)
132}
133
134func (m *Metrics) RegisterCounterVecGroup(opts []CounterOpts, labelNames []string, subsytem string) (c map[string]CounterVec) {
135 c = make(map[string]CounterVec)
136 for _, opt := range opts {
137 entry := CounterVec{}
138 entry.Opts = opt
139 entry.Opts.Namespace = m.Namespace
140 entry.Opts.Subsystem = subsytem
141 entry.Vec = m.registerCounterVec(entry.Opts, labelNames)
142 c[opt.Name] = entry
143 }
144 return
145}
146
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300147func (m *Metrics) GetCounterGroupFromVectsWithPrefix(prefix string, labels []string, vects ...map[string]CounterVec) (c map[string]Counter) {
Juha Hyttinenf619d032020-05-07 12:42:26 +0300148 c = make(map[string]Counter)
149 for _, vec := range vects {
150 for name, opt := range vec {
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300151 c[prefix+name] = opt.Vec.WithLabelValues(labels...)
Juha Hyttinenf619d032020-05-07 12:42:26 +0300152 Logger.Info("Register new counter for vector with opts: %v labels: %v", opt.Opts, labels)
153 }
154 }
155 return
156}
157
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300158func (m *Metrics) GetCounterGroupFromVects(labels []string, vects ...map[string]CounterVec) (c map[string]Counter) {
159 return m.GetCounterGroupFromVectsWithPrefix("", labels, vects...)
160}
161
Juha Hyttinenf619d032020-05-07 12:42:26 +0300162/*
163 * Handling gauge vectors
164 *
165 * Example:
166
167 vec := Metric.RegisterGaugeVecGroup(
168 []CounterOpts{
169 {Name: "gauge1", Help: "gauge1"},
170 {Name: "gauge2", Help: "gauge2"},
171 },
172 []string{"host"},
173 "SUBSYSTEM")
174
175 stat:=Metric.GetGaugeGroupFromVects([]string{"localhost:8888"},vec)
176
177*/
178type GaugeVec struct {
179 Vec *prometheus.GaugeVec
180 Opts CounterOpts
181}
182
183func (m *Metrics) registerGaugeVec(opts CounterOpts, labelNames []string) *prometheus.GaugeVec {
184 Logger.Info("Register new gauge vector with opts: %v labelNames: %v", opts, labelNames)
185
186 return promauto.NewGaugeVec(prometheus.GaugeOpts(opts), labelNames)
187}
188
189func (m *Metrics) RegisterGaugeVecGroup(opts []CounterOpts, labelNames []string, subsytem string) (c map[string]GaugeVec) {
190 c = make(map[string]GaugeVec)
191 for _, opt := range opts {
192 entry := GaugeVec{}
193 entry.Opts = opt
194 entry.Opts.Namespace = m.Namespace
195 entry.Opts.Subsystem = subsytem
196 entry.Vec = m.registerGaugeVec(entry.Opts, labelNames)
197 c[opt.Name] = entry
198
199 }
200 return
201}
202
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300203func (m *Metrics) GetGaugeGroupFromVectsWithPrefix(prefix string, labels []string, vects ...map[string]GaugeVec) (c map[string]Gauge) {
Juha Hyttinenf619d032020-05-07 12:42:26 +0300204 c = make(map[string]Gauge)
205 for _, vec := range vects {
206 for name, opt := range vec {
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300207 c[prefix+name] = opt.Vec.WithLabelValues(labels...)
Juha Hyttinenf619d032020-05-07 12:42:26 +0300208 Logger.Info("Register new gauge for vector with opts: %v labels: %v", opt.Opts, labels)
209 }
210 }
211 return
212}
213
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300214func (m *Metrics) GetGaugeGroupFromVects(labels []string, vects ...map[string]GaugeVec) (c map[string]Gauge) {
215 return m.GetGaugeGroupFromVectsWithPrefix("", labels, vects...)
216
217}
218
Juha Hyttinenf619d032020-05-07 12:42:26 +0300219/*
220 *
221 */
222func (m *Metrics) CombineCounterGroups(srcs ...map[string]Counter) map[string]Counter {
223 trg := make(map[string]Counter)
224 for _, src := range srcs {
225 for k, v := range src {
226 trg[k] = v
227 }
228 }
229 return trg
230}
231
232func (m *Metrics) CombineGaugeGroups(srcs ...map[string]Gauge) map[string]Gauge {
233 trg := make(map[string]Gauge)
234 for _, src := range srcs {
235 for k, v := range src {
236 trg[k] = v
237 }
238 }
239 return trg
240}
Juha Hyttinen90f6dd42020-05-08 12:17:05 +0300241
242/*
243 *
244 */
245func (m *Metrics) GroupCacheGet(id string) *MetricGroupsCache {
246 entry, ok := m.MetricGroupsCacheMap[id]
247 if ok == false {
248 return nil
249 }
250 return entry
251}
252
253func (m *Metrics) GroupCacheAddCounters(id string, vals map[string]Counter) {
254 entry, ok := m.MetricGroupsCacheMap[id]
255 if ok == false {
256 entry = &MetricGroupsCache{}
257 m.MetricGroupsCacheMap[id] = entry
258 }
259 m.MetricGroupsCacheMap[id].Counters = m.CombineCounterGroups(m.MetricGroupsCacheMap[id].Counters, vals)
260}
261
262func (m *Metrics) GroupCacheAddGauges(id string, vals map[string]Gauge) {
263 entry, ok := m.MetricGroupsCacheMap[id]
264 if ok == false {
265 entry = &MetricGroupsCache{}
266 m.MetricGroupsCacheMap[id] = entry
267 }
268 m.MetricGroupsCacheMap[id].Gauges = m.CombineGaugeGroups(m.MetricGroupsCacheMap[id].Gauges, vals)
269}