...
1 package reaper
2
3 import (
4 "context"
5 "os"
6
7 "slices"
8
9 "github.com/cybertec-postgresql/pgwatch/v3/internal/metrics"
10 "github.com/cybertec-postgresql/pgwatch/v3/internal/sources"
11 )
12
13 func DoesEmergencyTriggerfileExist(fname string) bool {
14
15
16
17
18 if fname == "" {
19 return false
20 }
21 _, err := os.Stat(fname)
22 return err == nil
23 }
24
25 const (
26 metricCPULoad = "cpu_load"
27 metricPsutilCPU = "psutil_cpu"
28 metricPsutilDisk = "psutil_disk"
29 metricPsutilDiskIoTotal = "psutil_disk_io_total"
30 metricPsutilMem = "psutil_mem"
31 )
32
33 const (
34 sqlPgDirs = `select current_setting('data_directory') as dd, current_setting('log_directory') as ld`
35 sqlTsDirs = `select spcname::text as name, pg_catalog.pg_tablespace_location(oid) as location from pg_catalog.pg_tablespace where not spcname like any(array[E'pg\\_%'])`
36 )
37
38 var directlyFetchableOSMetrics = []string{metricPsutilCPU, metricPsutilDisk, metricPsutilDiskIoTotal, metricPsutilMem, metricCPULoad}
39
40 func IsDirectlyFetchableMetric(metric string) bool {
41 return slices.Contains(directlyFetchableOSMetrics, metric)
42 }
43
44 func (r *Reaper) FetchStatsDirectlyFromOS(ctx context.Context, md *sources.SourceConn, metricName string) (*metrics.MeasurementEnvelope, error) {
45 var data, dataDirs, dataTblspDirs metrics.Measurements
46 var err error
47
48 switch metricName {
49 case metricCPULoad:
50 data, err = GetLoadAvgLocal()
51 case metricPsutilCPU:
52 data, err = GetGoPsutilCPU(md.GetMetricInterval(metricName))
53 case metricPsutilDisk:
54 if dataDirs, err = QueryMeasurements(ctx, md.Name, sqlPgDirs); err != nil {
55 return nil, err
56 }
57 if dataTblspDirs, err = QueryMeasurements(ctx, md.Name, sqlTsDirs); err != nil {
58 return nil, err
59 }
60 data, err = GetGoPsutilDiskPG(dataDirs, dataTblspDirs)
61 case metricPsutilDiskIoTotal:
62 data, err = GetGoPsutilDiskTotals()
63 case metricPsutilMem:
64 data, err = GetGoPsutilMem()
65 }
66 if err != nil {
67 return nil, err
68 }
69 m, _ := metricDefs.GetMetricDef(metricName)
70 return &metrics.MeasurementEnvelope{
71 DBName: md.Name,
72 SourceType: string(md.Kind),
73 MetricName: metricName,
74 CustomTags: md.CustomTags,
75 Data: data,
76 MetricDef: m,
77 RealDbname: md.RealDbname,
78 SystemIdentifier: md.SystemIdentifier,
79 }, nil
80 }
81