2 ==================================================================================
3 Copyright (c) 2019 AT&T Intellectual Property.
4 Copyright (c) 2019 Nokia
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
10 http://www.apache.org/licenses/LICENSE-2.0
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 ==================================================================================
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"
30 //-----------------------------------------------------------------------------
32 //-----------------------------------------------------------------------------
33 type CounterOpts prometheus.Opts
34 type Counter prometheus.Counter
35 type Gauge prometheus.Gauge
37 //-----------------------------------------------------------------------------
39 //-----------------------------------------------------------------------------
41 type MetricGroupsCache struct {
42 Counters map[string]Counter
43 Gauges map[string]Gauge
46 func (met *MetricGroupsCache) CInc(metric string) {
47 met.Counters[metric].Inc()
50 func (met *MetricGroupsCache) CAdd(metric string, val float64) {
51 met.Counters[metric].Add(val)
54 func (met *MetricGroupsCache) GSet(metric string, val float64) {
55 met.Gauges[metric].Set(val)
58 //-----------------------------------------------------------------------------
60 //-----------------------------------------------------------------------------
64 MetricGroupsCacheMap map[string]*MetricGroupsCache
67 func NewMetrics(url, namespace string, r *mux.Router) *Metrics {
69 url = "/ric/v1/metrics"
75 Logger.Info("Serving metrics on: url=%s namespace=%s", url, namespace)
77 // Expose 'metrics' endpoint with standard golang metrics used by prometheus
78 r.Handle(url, promhttp.Handler())
80 return &Metrics{Namespace: namespace, MetricGroupsCacheMap: make(map[string]*MetricGroupsCache)}
86 func (m *Metrics) registerCounter(opts CounterOpts) Counter {
87 Logger.Info("Register new counter with opts: %v", opts)
88 return promauto.NewCounter(prometheus.CounterOpts(opts))
91 func (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
96 c[opt.Name] = m.registerCounter(opt)
105 func (m *Metrics) registerGauge(opts CounterOpts) Gauge {
106 Logger.Info("Register new gauge with opts: %v", opts)
107 return promauto.NewGauge(prometheus.GaugeOpts(opts))
110 func (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
115 c[opt.Name] = m.registerGauge(opt)
122 * Handling counter vectors
126 vec := Metric.RegisterCounterVecGroup(
128 {Name: "counter1", Help: "counter1"},
129 {Name: "counter2", Help: "counter2"},
134 stat:=Metric.GetCounterGroupFromVects([]string{"localhost:8888"}, vec)
137 type CounterVec struct {
138 Vec *prometheus.CounterVec
142 func (m *Metrics) registerCounterVec(opts CounterOpts, labelNames []string) *prometheus.CounterVec {
143 Logger.Info("Register new counter vector with opts: %v labelNames: %v", opts, labelNames)
145 return promauto.NewCounterVec(prometheus.CounterOpts(opts), labelNames)
148 func (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{}
153 entry.Opts.Namespace = m.Namespace
154 entry.Opts.Subsystem = subsytem
155 entry.Vec = m.registerCounterVec(entry.Opts, labelNames)
161 func (m *Metrics) GetCounterGroupFromVectsWithPrefix(prefix string, labels []string, vects ...map[string]CounterVec) (c map[string]Counter) {
162 c = make(map[string]Counter)
163 for _, vec := range vects {
164 for name, opt := range vec {
165 c[prefix+name] = opt.Vec.WithLabelValues(labels...)
166 Logger.Info("Register new counter for vector with opts: %v labels: %v", opt.Opts, labels)
172 func (m *Metrics) GetCounterGroupFromVects(labels []string, vects ...map[string]CounterVec) (c map[string]Counter) {
173 return m.GetCounterGroupFromVectsWithPrefix("", labels, vects...)
177 * Handling gauge vectors
181 vec := Metric.RegisterGaugeVecGroup(
183 {Name: "gauge1", Help: "gauge1"},
184 {Name: "gauge2", Help: "gauge2"},
189 stat:=Metric.GetGaugeGroupFromVects([]string{"localhost:8888"},vec)
192 type GaugeVec struct {
193 Vec *prometheus.GaugeVec
197 func (m *Metrics) registerGaugeVec(opts CounterOpts, labelNames []string) *prometheus.GaugeVec {
198 Logger.Info("Register new gauge vector with opts: %v labelNames: %v", opts, labelNames)
200 return promauto.NewGaugeVec(prometheus.GaugeOpts(opts), labelNames)
203 func (m *Metrics) RegisterGaugeVecGroup(opts []CounterOpts, labelNames []string, subsytem string) (c map[string]GaugeVec) {
204 c = make(map[string]GaugeVec)
205 for _, opt := range opts {
208 entry.Opts.Namespace = m.Namespace
209 entry.Opts.Subsystem = subsytem
210 entry.Vec = m.registerGaugeVec(entry.Opts, labelNames)
217 func (m *Metrics) GetGaugeGroupFromVectsWithPrefix(prefix string, labels []string, vects ...map[string]GaugeVec) (c map[string]Gauge) {
218 c = make(map[string]Gauge)
219 for _, vec := range vects {
220 for name, opt := range vec {
221 c[prefix+name] = opt.Vec.WithLabelValues(labels...)
222 Logger.Info("Register new gauge for vector with opts: %v labels: %v", opt.Opts, labels)
228 func (m *Metrics) GetGaugeGroupFromVects(labels []string, vects ...map[string]GaugeVec) (c map[string]Gauge) {
229 return m.GetGaugeGroupFromVectsWithPrefix("", labels, vects...)
236 func (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 {
246 func (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 {
259 func (m *Metrics) GroupCacheGet(id string) *MetricGroupsCache {
261 defer m.lock.Unlock()
262 entry, ok := m.MetricGroupsCacheMap[id]
269 func (m *Metrics) GroupCacheAddCounters(id string, vals map[string]Counter) {
271 defer m.lock.Unlock()
272 entry, ok := m.MetricGroupsCacheMap[id]
274 entry = &MetricGroupsCache{}
275 m.MetricGroupsCacheMap[id] = entry
277 m.MetricGroupsCacheMap[id].Counters = m.CombineCounterGroups(m.MetricGroupsCacheMap[id].Counters, vals)
280 func (m *Metrics) GroupCacheAddGauges(id string, vals map[string]Gauge) {
282 defer m.lock.Unlock()
283 entry, ok := m.MetricGroupsCacheMap[id]
285 entry = &MetricGroupsCache{}
286 m.MetricGroupsCacheMap[id] = entry
288 m.MetricGroupsCacheMap[id].Gauges = m.CombineGaugeGroups(m.MetricGroupsCacheMap[id].Gauges, vals)