...

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

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

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