...
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 = "¤¤¤"
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 {
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
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
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