github.com/openshift/installer@v1.4.17/pkg/metrics/builder/builder.go (about)

     1  package builder
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"sort"
     7  
     8  	"github.com/prometheus/client_golang/prometheus"
     9  )
    10  
    11  // MetricBuilder is the basic metric type that must be used by any potential metric added to
    12  // the system. It allows user to create a prom collector which will be used to push.
    13  type MetricBuilder struct {
    14  	// labels contains the list of all label keys that the collector object will have.
    15  	labels []string
    16  	// labelKeyValues stores values for label keys that will be added to the metric
    17  	// Prometheus metrics are designed as follows:
    18  	// metric_name {metric_label_key1:value1, key2:value2, ....} metric_value
    19  	// labelKeyValues stores the key/value pairs of the Prometheus metric.
    20  	labelKeyValues map[string]string
    21  	// desc describes the metric that is being created. This field will be shown on Prometheus
    22  	// dashboard as a help text.
    23  	desc string
    24  	// name describes the name of the metric that needs to be pushed.
    25  	name string
    26  	// value stores the value of the metric that needs to be pushed. Collected from the installer.
    27  	value float64
    28  	// buckets keeps a list of bucket values that will be used during the creation of a Histogram
    29  	// object.
    30  	buckets []float64
    31  	// metricType defines what type of a collector object should the PromCollector function return.
    32  	metricType MetricType
    33  }
    34  
    35  // MetricOpts contains the properties that are required to create a MetricBuilder object.
    36  type MetricOpts struct {
    37  	// labels contains the list of all label keys that the collector object will have.
    38  	Labels []string
    39  	// desc describes the metric that is being created. This field will be shown on Prometheus
    40  	// dashboard as a help text.
    41  	Desc string
    42  	// name describes the name of the metric that needs to be pushed.
    43  	Name string
    44  	// buckets keeps a list of bucket values that will be used during the creation of a Histogram
    45  	// object.
    46  	Buckets []float64
    47  	// metricType defines what type of a collector object should the PromCollector function return.
    48  	MetricType MetricType
    49  }
    50  
    51  // MetricType defines what types of metrics can be created. Restricted by the types of the Prometheus
    52  // Collector types.
    53  type MetricType string
    54  
    55  const (
    56  	// Histogram denotes that the type of the collector object should be a Prometheus Histogram.
    57  	Histogram MetricType = "Histogram"
    58  	// Counter denotes that the type of the collector object should be a Prometheus Counter.
    59  	Counter MetricType = "Counter"
    60  )
    61  
    62  // PromCollector function creates the required prometheus collector object with the values
    63  // it has in the MetricBuilder calling object.
    64  func (m MetricBuilder) PromCollector() (prometheus.Collector, error) {
    65  	switch m.metricType {
    66  	case Counter:
    67  		return m.buildCounter(), nil
    68  	case Histogram:
    69  		return m.buildHistogram(), nil
    70  	default:
    71  		return nil, fmt.Errorf(`invalid metric builder type "%s". cannot create collector`, m.metricType)
    72  	}
    73  }
    74  
    75  // buildCounter returns a prometheus counter object with the value and labels set
    76  // in the MetricBuilder object.
    77  func (m *MetricBuilder) buildCounter() prometheus.Collector {
    78  	collector := prometheus.NewCounter(
    79  		prometheus.CounterOpts{
    80  			Name:        m.name,
    81  			Help:        m.desc,
    82  			ConstLabels: m.labelKeyValues,
    83  		},
    84  	)
    85  	collector.Add(m.value)
    86  	return collector
    87  }
    88  
    89  // buildHistogram returns a prometheus Histogram object with the value, labels and buckets set
    90  // in the MetricBuilder object.
    91  func (m *MetricBuilder) buildHistogram() prometheus.Collector {
    92  	collector := prometheus.NewHistogram(
    93  		prometheus.HistogramOpts{
    94  			Name:        m.name,
    95  			Help:        m.desc,
    96  			Buckets:     m.buckets,
    97  			ConstLabels: m.labelKeyValues,
    98  		},
    99  	)
   100  	collector.Observe(m.value)
   101  	return collector
   102  }
   103  
   104  // NewMetricBuilder creates a new MetricBuilder object with the default values for the field.
   105  func NewMetricBuilder(opts MetricOpts, value float64, labelKeyValues map[string]string) (*MetricBuilder, error) {
   106  	if opts.Labels == nil {
   107  		return nil, errors.New("labels cannot be empty")
   108  	}
   109  	if labelKeyValues == nil {
   110  		labelKeyValues = make(map[string]string)
   111  	}
   112  	if opts.Name == "" {
   113  		return nil, errors.New("name cannot be empty")
   114  	}
   115  	if opts.MetricType == "" {
   116  		return nil, errors.New("metricType cannot be empty")
   117  	}
   118  	sort.Strings(opts.Labels)
   119  	return &MetricBuilder{
   120  		labels:         opts.Labels,
   121  		name:           opts.Name,
   122  		metricType:     opts.MetricType,
   123  		desc:           opts.Desc,
   124  		buckets:        opts.Buckets,
   125  		value:          value,
   126  		labelKeyValues: labelKeyValues,
   127  	}, nil
   128  }
   129  
   130  // SetValue is a setter function that assigns value to the metric builder.
   131  func (m *MetricBuilder) SetValue(value float64) {
   132  	m.value = value
   133  }
   134  
   135  // AddLabelValue takes in a key and value and sets it to the map in metric builder.
   136  func (m *MetricBuilder) AddLabelValue(key string, value string) error {
   137  	if i := sort.SearchStrings(m.labels, key); i < len(m.labels) && m.labels[i] == key {
   138  		m.labelKeyValues[key] = value
   139  		return nil
   140  	}
   141  	return fmt.Errorf("key %q not in metricBuilder labels %v", key, m.labels)
   142  }