...

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  	"fmt"
     5  	"maps"
     6  	"sync"
     7  	"time"
     8  
     9  	"github.com/cybertec-postgresql/pgwatch/v3/internal/metrics"
    10  	"github.com/cybertec-postgresql/pgwatch/v3/internal/sinks"
    11  	"github.com/sirupsen/logrus"
    12  )
    13  
    14  const (
    15  	monitoredDbsDatastoreSyncIntervalSeconds = 600              // write actively monitored DBs listing to metrics store after so many seconds
    16  	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
    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  	Target  string
    64  	Created int
    65  	Altered int
    66  	Dropped int
    67  }
    68  
    69  func (cdr *ChangeDetectionResults) Total() int {
    70  	return cdr.Created + cdr.Altered + cdr.Dropped
    71  }
    72  
    73  func (cdr *ChangeDetectionResults) String() string {
    74  	return fmt.Sprintf("%s: %d/%d/%d", cdr.Target, cdr.Created, cdr.Altered, cdr.Dropped)
    75  }
    76  
    77  type ExistingPartitionInfo struct {
    78  	StartTime time.Time
    79  	EndTime   time.Time
    80  }
    81  
    82  // LoadMetrics loads metric definitions from the reader
    83  func (r *Reaper) LoadMetrics() (err error) {
    84  	var newDefs *metrics.Metrics
    85  	if newDefs, err = r.MetricsReaderWriter.GetMetrics(); err != nil {
    86  		return
    87  	}
    88  	metricDefs.Assign(newDefs)
    89  	if definer, ok := r.SinksWriter.(sinks.MetricsDefiner); ok {
    90  		err := definer.DefineMetrics(newDefs)
    91  		if err != nil {
    92  			r.logger.Error(err)
    93  		}
    94  	}
    95  	r.logger.
    96  		WithField("metrics", len(newDefs.MetricDefs)).
    97  		WithField("presets", len(newDefs.PresetDefs)).
    98  		Log(func() logrus.Level {
    99  			if len(newDefs.PresetDefs)*len(newDefs.MetricDefs) == 0 {
   100  				return logrus.WarnLevel
   101  			}
   102  			return logrus.InfoLevel
   103  		}(), "metrics and presets refreshed")
   104  	// update the monitored sources with real metric definitions from presets
   105  	for _, md := range r.monitoredSources {
   106  		if md.PresetMetrics > "" {
   107  			md.Metrics = metricDefs.GetPresetMetrics(md.PresetMetrics)
   108  		}
   109  		if md.PresetMetricsStandby > "" {
   110  			md.MetricsStandby = metricDefs.GetPresetMetrics(md.PresetMetricsStandby)
   111  		}
   112  	}
   113  	return
   114  }
   115