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 //-----------------------------------------------------------------------------
47 //-----------------------------------------------------------------------------
50 MetricGroupsCacheMap map[string]*MetricGroupsCache
53 func NewMetrics(url, namespace string, r *mux.Router) *Metrics {
55 url = "/ric/v1/metrics"
61 Logger.Info("Serving metrics on: url=%s namespace=%s", url, namespace)
63 // Expose 'metrics' endpoint with standard golang metrics used by prometheus
64 r.Handle(url, promhttp.Handler())
66 return &Metrics{Namespace: namespace, MetricGroupsCacheMap: make(map[string]*MetricGroupsCache)}
72 func (m *Metrics) registerCounter(opts CounterOpts) Counter {
73 Logger.Info("Register new counter with opts: %v", opts)
74 return promauto.NewCounter(prometheus.CounterOpts(opts))
77 func (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
82 c[opt.Name] = m.registerCounter(opt)
91 func (m *Metrics) registerGauge(opts CounterOpts) Gauge {
92 Logger.Info("Register new gauge with opts: %v", opts)
93 return promauto.NewGauge(prometheus.GaugeOpts(opts))
96 func (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
101 c[opt.Name] = m.registerGauge(opt)
108 * Handling counter vectors
112 vec := Metric.RegisterCounterVecGroup(
114 {Name: "counter1", Help: "counter1"},
115 {Name: "counter2", Help: "counter2"},
120 stat:=Metric.GetCounterGroupFromVects([]string{"localhost:8888"}, vec)
123 type CounterVec struct {
124 Vec *prometheus.CounterVec
128 func (m *Metrics) registerCounterVec(opts CounterOpts, labelNames []string) *prometheus.CounterVec {
129 Logger.Info("Register new counter vector with opts: %v labelNames: %v", opts, labelNames)
131 return promauto.NewCounterVec(prometheus.CounterOpts(opts), labelNames)
134 func (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{}
139 entry.Opts.Namespace = m.Namespace
140 entry.Opts.Subsystem = subsytem
141 entry.Vec = m.registerCounterVec(entry.Opts, labelNames)
147 func (m *Metrics) GetCounterGroupFromVectsWithPrefix(prefix string, labels []string, vects ...map[string]CounterVec) (c map[string]Counter) {
148 c = make(map[string]Counter)
149 for _, vec := range vects {
150 for name, opt := range vec {
151 c[prefix+name] = opt.Vec.WithLabelValues(labels...)
152 Logger.Info("Register new counter for vector with opts: %v labels: %v", opt.Opts, labels)
158 func (m *Metrics) GetCounterGroupFromVects(labels []string, vects ...map[string]CounterVec) (c map[string]Counter) {
159 return m.GetCounterGroupFromVectsWithPrefix("", labels, vects...)
163 * Handling gauge vectors
167 vec := Metric.RegisterGaugeVecGroup(
169 {Name: "gauge1", Help: "gauge1"},
170 {Name: "gauge2", Help: "gauge2"},
175 stat:=Metric.GetGaugeGroupFromVects([]string{"localhost:8888"},vec)
178 type GaugeVec struct {
179 Vec *prometheus.GaugeVec
183 func (m *Metrics) registerGaugeVec(opts CounterOpts, labelNames []string) *prometheus.GaugeVec {
184 Logger.Info("Register new gauge vector with opts: %v labelNames: %v", opts, labelNames)
186 return promauto.NewGaugeVec(prometheus.GaugeOpts(opts), labelNames)
189 func (m *Metrics) RegisterGaugeVecGroup(opts []CounterOpts, labelNames []string, subsytem string) (c map[string]GaugeVec) {
190 c = make(map[string]GaugeVec)
191 for _, opt := range opts {
194 entry.Opts.Namespace = m.Namespace
195 entry.Opts.Subsystem = subsytem
196 entry.Vec = m.registerGaugeVec(entry.Opts, labelNames)
203 func (m *Metrics) GetGaugeGroupFromVectsWithPrefix(prefix string, labels []string, vects ...map[string]GaugeVec) (c map[string]Gauge) {
204 c = make(map[string]Gauge)
205 for _, vec := range vects {
206 for name, opt := range vec {
207 c[prefix+name] = opt.Vec.WithLabelValues(labels...)
208 Logger.Info("Register new gauge for vector with opts: %v labels: %v", opt.Opts, labels)
214 func (m *Metrics) GetGaugeGroupFromVects(labels []string, vects ...map[string]GaugeVec) (c map[string]Gauge) {
215 return m.GetGaugeGroupFromVectsWithPrefix("", labels, vects...)
222 func (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 {
232 func (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 {
245 func (m *Metrics) GroupCacheGet(id string) *MetricGroupsCache {
246 entry, ok := m.MetricGroupsCacheMap[id]
253 func (m *Metrics) GroupCacheAddCounters(id string, vals map[string]Counter) {
254 entry, ok := m.MetricGroupsCacheMap[id]
256 entry = &MetricGroupsCache{}
257 m.MetricGroupsCacheMap[id] = entry
259 m.MetricGroupsCacheMap[id].Counters = m.CombineCounterGroups(m.MetricGroupsCacheMap[id].Counters, vals)
262 func (m *Metrics) GroupCacheAddGauges(id string, vals map[string]Gauge) {
263 entry, ok := m.MetricGroupsCacheMap[id]
265 entry = &MetricGroupsCache{}
266 m.MetricGroupsCacheMap[id] = entry
268 m.MetricGroupsCacheMap[id].Gauges = m.CombineGaugeGroups(m.MetricGroupsCacheMap[id].Gauges, vals)