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  }