...

Source file src/github.com/cybertec-postgresql/pgwatch/v5/internal/reaper/metric.go

Documentation: github.com/cybertec-postgresql/pgwatch/v5/internal/reaper

     1  package reaper
     2  
     3  import (
     4  	"fmt"
     5  	"maps"
     6  	"sync"
     7  	"time"
     8  
     9  	"github.com/cybertec-postgresql/pgwatch/v5/internal/metrics"
    10  	"github.com/cybertec-postgresql/pgwatch/v5/internal/sinks"
    11  	"github.com/sirupsen/logrus"
    12  )
    13  
    14  const dbMetricJoinStr = "¤¤¤" // just some unlikely string for a DB name to avoid using maps of maps for DB+metric data
    15  
    16  type ConcurrentMetricDefs struct {
    17  	*metrics.Metrics
    18  	sync.RWMutex
    19  }
    20  
    21  func NewConcurrentMetricDefs() *ConcurrentMetricDefs {
    22  	return &ConcurrentMetricDefs{
    23  		Metrics: &metrics.Metrics{
    24  			MetricDefs: make(metrics.MetricDefs),
    25  			PresetDefs: make(metrics.PresetDefs),
    26  		},
    27  	}
    28  }
    29  
    30  func (cmd *ConcurrentMetricDefs) GetMetricDef(name string) (m metrics.Metric, ok bool) {
    31  	cmd.RLock()
    32  	defer cmd.RUnlock()
    33  	m, ok = cmd.MetricDefs[name]
    34  	return
    35  }
    36  
    37  func (cmd *ConcurrentMetricDefs) GetPresetDef(name string) (m metrics.Preset, ok bool) {
    38  	cmd.RLock()
    39  	defer cmd.RUnlock()
    40  	m, ok = cmd.PresetDefs[name]
    41  	return
    42  }
    43  
    44  func (cmd *ConcurrentMetricDefs) GetPresetMetrics(name string) (m metrics.MetricIntervals) {
    45  	cmd.RLock()
    46  	defer cmd.RUnlock()
    47  	return cmd.PresetDefs[name].Metrics
    48  }
    49  
    50  func (cmd *ConcurrentMetricDefs) Assign(newDefs *metrics.Metrics) {
    51  	cmd.Lock()
    52  	defer cmd.Unlock()
    53  	cmd.MetricDefs = maps.Clone(newDefs.MetricDefs)
    54  	cmd.PresetDefs = maps.Clone(newDefs.PresetDefs)
    55  }
    56  
    57  type ChangeDetectionResults struct { // for passing around DDL/index/config change detection results
    58  	Target  string
    59  	Created int
    60  	Altered int
    61  	Dropped int
    62  }
    63  
    64  func (cdr *ChangeDetectionResults) Total() int {
    65  	return cdr.Created + cdr.Altered + cdr.Dropped
    66  }
    67  
    68  func (cdr *ChangeDetectionResults) String() string {
    69  	return fmt.Sprintf("%s: %d/%d/%d", cdr.Target, cdr.Created, cdr.Altered, cdr.Dropped)
    70  }
    71  
    72  type ExistingPartitionInfo struct {
    73  	StartTime time.Time
    74  	EndTime   time.Time
    75  }
    76  
    77  // LoadMetrics loads metric definitions from the reader
    78  func (r *Reaper) LoadMetrics() (err error) {
    79  	var newDefs *metrics.Metrics
    80  	if newDefs, err = r.MetricsReaderWriter.GetMetrics(); err != nil {
    81  		return
    82  	}
    83  	metricDefs.Assign(newDefs)
    84  	if definer, ok := r.SinksWriter.(sinks.MetricsDefiner); ok {
    85  		err := definer.DefineMetrics(newDefs)
    86  		if err != nil {
    87  			r.logger.Error(err)
    88  		}
    89  	}
    90  	r.logger.
    91  		WithField("metrics", len(newDefs.MetricDefs)).
    92  		WithField("presets", len(newDefs.PresetDefs)).
    93  		Log(func() logrus.Level {
    94  			if len(newDefs.PresetDefs)*len(newDefs.MetricDefs) == 0 {
    95  				return logrus.WarnLevel
    96  			}
    97  			return logrus.InfoLevel
    98  		}(), "metrics and presets refreshed")
    99  	// update the monitored sources with real metric definitions from presets
   100  	for _, md := range r.monitoredSources {
   101  		if md.PresetMetrics > "" {
   102  			md.Metrics = metricDefs.GetPresetMetrics(md.PresetMetrics)
   103  		}
   104  		if md.PresetMetricsStandby > "" {
   105  			md.MetricsStandby = metricDefs.GetPresetMetrics(md.PresetMetricsStandby)
   106  		}
   107  	}
   108  	return
   109  }
   110