go.ligato.io/vpp-agent/v3@v3.5.0/pkg/metrics/registry.go (about) 1 // Copyright (c) 2019 Cisco and/or its affiliates. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at: 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package metrics 16 17 import ( 18 "fmt" 19 "reflect" 20 "sync" 21 22 "go.ligato.io/vpp-agent/v3/pkg/models" 23 ) 24 25 var ( 26 mu sync.RWMutex 27 registeredMetrics = make(map[string]Retriever) 28 ) 29 30 // Retriever defines function that returns metrics data 31 type Retriever func() interface{} 32 33 // Register registers given type with retriever to metrics. 34 func Register(metricType interface{}, retrieverFunc Retriever) { 35 model, err := models.DefaultRegistry.GetModelFor(metricType) 36 if err != nil { 37 panic(fmt.Sprintf("type %T not registered as model", metricType)) 38 } 39 if model.Spec().Class != "metrics" { 40 panic(fmt.Sprintf("model %v not registered with class metrics", model.Name())) 41 } 42 mu.Lock() 43 defer mu.Unlock() 44 if _, ok := registeredMetrics[model.Name()]; ok { 45 panic(fmt.Sprintf("duplicate registration for metrics model %s", model.Name())) 46 } 47 registeredMetrics[model.Name()] = retrieverFunc 48 } 49 50 // Retrieve calls registered retriever for given metric and sets returned data to metric. 51 func Retrieve(metric interface{}) error { 52 model, err := models.DefaultRegistry.GetModelFor(metric) 53 if err != nil { 54 return fmt.Errorf("type %T not registered as model", metric) 55 } 56 mu.RLock() 57 retriever, ok := registeredMetrics[model.Name()] 58 if !ok { 59 mu.RUnlock() 60 return fmt.Errorf("metric %v does not have registered retriever", model.Name()) 61 } 62 mu.RUnlock() 63 data := retriever() 64 reflect.ValueOf(metric).Elem().Set(reflect.ValueOf(data).Elem()) 65 return nil 66 }