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"
29 //-----------------------------------------------------------------------------
31 //-----------------------------------------------------------------------------
32 type CounterOpts prometheus.Opts
33 type Counter prometheus.Counter
34 type Gauge prometheus.Gauge
36 //-----------------------------------------------------------------------------
38 //-----------------------------------------------------------------------------
40 type MetricGroupsCache struct {
41 Counters map[string]Counter
42 Gauges map[string]Gauge
45 func (met *MetricGroupsCache) CInc(metric string) {
46 met.Counters[metric].Inc()
49 func (met *MetricGroupsCache) CAdd(metric string, val float64) {
50 met.Counters[metric].Add(val)
53 func (met *MetricGroupsCache) GSet(metric string, val float64) {
54 met.Gauges[metric].Set(val)
57 //-----------------------------------------------------------------------------
59 //-----------------------------------------------------------------------------
62 MetricGroupsCacheMap map[string]*MetricGroupsCache
65 func NewMetrics(url, namespace string, r *mux.Router) *Metrics {
67 url = "/ric/v1/metrics"
73 Logger.Info("Serving metrics on: url=%s namespace=%s", url, namespace)
75 // Expose 'metrics' endpoint with standard golang metrics used by prometheus
76 r.Handle(url, promhttp.Handler())
78 return &Metrics{Namespace: namespace, MetricGroupsCacheMap: make(map[string]*MetricGroupsCache)}
84 func (m *Metrics) registerCounter(opts CounterOpts) Counter {
85 Logger.Info("Register new counter with opts: %v", opts)
86 return promauto.NewCounter(prometheus.CounterOpts(opts))
89 func (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
94 c[opt.Name] = m.registerCounter(opt)
103 func (m *Metrics) registerGauge(opts CounterOpts) Gauge {
104 Logger.Info("Register new gauge with opts: %v", opts)
105 return promauto.NewGauge(prometheus.GaugeOpts(opts))
108 func (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
113 c[opt.Name] = m.registerGauge(opt)
120 * Handling counter vectors
124 vec := Metric.RegisterCounterVecGroup(
126 {Name: "counter1", Help: "counter1"},
127 {Name: "counter2", Help: "counter2"},
132 stat:=Metric.GetCounterGroupFromVects([]string{"localhost:8888"}, vec)
135 type CounterVec struct {
136 Vec *prometheus.CounterVec
140 func (m *Metrics) registerCounterVec(opts CounterOpts, labelNames []string) *prometheus.CounterVec {
141 Logger.Info("Register new counter vector with opts: %v labelNames: %v", opts, labelNames)
143 return promauto.NewCounterVec(prometheus.CounterOpts(opts), labelNames)
146 func (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{}
151 entry.Opts.Namespace = m.Namespace
152 entry.Opts.Subsystem = subsytem
153 entry.Vec = m.registerCounterVec(entry.Opts, labelNames)
159 func (m *Metrics) GetCounterGroupFromVectsWithPrefix(prefix string, labels []string, vects ...map[string]CounterVec) (c map[string]Counter) {
160 c = make(map[string]Counter)
161 for _, vec := range vects {
162 for name, opt := range vec {
163 c[prefix+name] = opt.Vec.WithLabelValues(labels...)
164 Logger.Info("Register new counter for vector with opts: %v labels: %v", opt.Opts, labels)
170 func (m *Metrics) GetCounterGroupFromVects(labels []string, vects ...map[string]CounterVec) (c map[string]Counter) {
171 return m.GetCounterGroupFromVectsWithPrefix("", labels, vects...)
175 * Handling gauge vectors
179 vec := Metric.RegisterGaugeVecGroup(
181 {Name: "gauge1", Help: "gauge1"},
182 {Name: "gauge2", Help: "gauge2"},
187 stat:=Metric.GetGaugeGroupFromVects([]string{"localhost:8888"},vec)
190 type GaugeVec struct {
191 Vec *prometheus.GaugeVec
195 func (m *Metrics) registerGaugeVec(opts CounterOpts, labelNames []string) *prometheus.GaugeVec {
196 Logger.Info("Register new gauge vector with opts: %v labelNames: %v", opts, labelNames)
198 return promauto.NewGaugeVec(prometheus.GaugeOpts(opts), labelNames)
201 func (m *Metrics) RegisterGaugeVecGroup(opts []CounterOpts, labelNames []string, subsytem string) (c map[string]GaugeVec) {
202 c = make(map[string]GaugeVec)
203 for _, opt := range opts {
206 entry.Opts.Namespace = m.Namespace
207 entry.Opts.Subsystem = subsytem
208 entry.Vec = m.registerGaugeVec(entry.Opts, labelNames)
215 func (m *Metrics) GetGaugeGroupFromVectsWithPrefix(prefix string, labels []string, vects ...map[string]GaugeVec) (c map[string]Gauge) {
216 c = make(map[string]Gauge)
217 for _, vec := range vects {
218 for name, opt := range vec {
219 c[prefix+name] = opt.Vec.WithLabelValues(labels...)
220 Logger.Info("Register new gauge for vector with opts: %v labels: %v", opt.Opts, labels)
226 func (m *Metrics) GetGaugeGroupFromVects(labels []string, vects ...map[string]GaugeVec) (c map[string]Gauge) {
227 return m.GetGaugeGroupFromVectsWithPrefix("", labels, vects...)
234 func (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 {
244 func (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 {
257 func (m *Metrics) GroupCacheGet(id string) *MetricGroupsCache {
258 entry, ok := m.MetricGroupsCacheMap[id]
265 func (m *Metrics) GroupCacheAddCounters(id string, vals map[string]Counter) {
266 entry, ok := m.MetricGroupsCacheMap[id]
268 entry = &MetricGroupsCache{}
269 m.MetricGroupsCacheMap[id] = entry
271 m.MetricGroupsCacheMap[id].Counters = m.CombineCounterGroups(m.MetricGroupsCacheMap[id].Counters, vals)
274 func (m *Metrics) GroupCacheAddGauges(id string, vals map[string]Gauge) {
275 entry, ok := m.MetricGroupsCacheMap[id]
277 entry = &MetricGroupsCache{}
278 m.MetricGroupsCacheMap[id] = entry
280 m.MetricGroupsCacheMap[id].Gauges = m.CombineGaugeGroups(m.MetricGroupsCacheMap[id].Gauges, vals)