github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/clients/pkg/logentry/metric/histograms.go (about)

     1  package metric
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/mitchellh/mapstructure"
     7  	"github.com/prometheus/client_golang/prometheus"
     8  	"github.com/prometheus/common/model"
     9  )
    10  
    11  type HistogramConfig struct {
    12  	Value   *string   `mapstructure:"value"`
    13  	Buckets []float64 `mapstructure:"buckets"`
    14  }
    15  
    16  func validateHistogramConfig(config *HistogramConfig) error {
    17  	return nil
    18  }
    19  
    20  func parseHistogramConfig(config interface{}) (*HistogramConfig, error) {
    21  	cfg := &HistogramConfig{}
    22  	err := mapstructure.Decode(config, cfg)
    23  	if err != nil {
    24  		return nil, err
    25  	}
    26  	return cfg, nil
    27  }
    28  
    29  // Histograms is a vector of histograms for a each log stream.
    30  type Histograms struct {
    31  	*metricVec
    32  	Cfg *HistogramConfig
    33  }
    34  
    35  // NewHistograms creates a new histogram vec.
    36  func NewHistograms(name, help string, config interface{}, maxIdleSec int64) (*Histograms, error) {
    37  	cfg, err := parseHistogramConfig(config)
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  	err = validateHistogramConfig(cfg)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  	return &Histograms{
    46  		metricVec: newMetricVec(func(labels map[string]string) prometheus.Metric {
    47  			return &expiringHistogram{prometheus.NewHistogram(prometheus.HistogramOpts{
    48  				Help:        help,
    49  				Name:        name,
    50  				ConstLabels: labels,
    51  				Buckets:     cfg.Buckets,
    52  			}),
    53  				0,
    54  			}
    55  		}, maxIdleSec),
    56  		Cfg: cfg,
    57  	}, nil
    58  }
    59  
    60  // With returns the histogram associated with a stream labelset.
    61  func (h *Histograms) With(labels model.LabelSet) prometheus.Histogram {
    62  	return h.metricVec.With(labels).(prometheus.Histogram)
    63  }
    64  
    65  type expiringHistogram struct {
    66  	prometheus.Histogram
    67  	lastModSec int64
    68  }
    69  
    70  // Observe adds a single observation to the histogram.
    71  func (h *expiringHistogram) Observe(val float64) {
    72  	h.Histogram.Observe(val)
    73  	h.lastModSec = time.Now().Unix()
    74  }
    75  
    76  // HasExpired implements Expirable
    77  func (h *expiringHistogram) HasExpired(currentTimeSec int64, maxAgeSec int64) bool {
    78  	return currentTimeSec-h.lastModSec >= maxAgeSec
    79  }