...

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

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

     1  package reaper
     2  
     3  import (
     4  	"context"
     5  	"strings"
     6  	"time"
     7  
     8  	"errors"
     9  
    10  	"github.com/cybertec-postgresql/pgwatch/v3/internal/metrics"
    11  )
    12  
    13  const (
    14  	recoPrefix                        = "reco_" // special handling for metrics with such prefix, data stored in RECO_METRIC_NAME
    15  	recoMetricName                    = "recommendations"
    16  	specialMetricChangeEvents         = "change_events"
    17  	specialMetricServerLogEventCounts = "server_log_event_counts"
    18  	specialMetricPgpoolStats          = "pgpool_stats"
    19  	specialMetricInstanceUp           = "instance_up"
    20  	specialMetricDbSize               = "db_size"     // can be transparently switched to db_size_approx on instances with very slow FS access (Azure Single Server)
    21  	specialMetricTableStats           = "table_stats" // can be transparently switched to table_stats_approx on instances with very slow FS (Azure Single Server)
    22  
    23  )
    24  
    25  var specialMetrics = map[string]bool{recoMetricName: true, specialMetricChangeEvents: true, specialMetricServerLogEventCounts: true}
    26  
    27  func GetAllRecoMetricsForVersion() (metrics.MetricDefs, error) {
    28  	mvpMap := make(metrics.MetricDefs)
    29  	metricDefs.RLock()
    30  	defer metricDefs.RUnlock()
    31  	for name, m := range metricDefs.MetricDefs {
    32  		if strings.HasPrefix(name, recoPrefix) {
    33  			mvpMap[name] = m
    34  		}
    35  	}
    36  	return mvpMap, nil
    37  }
    38  
    39  func GetRecommendations(ctx context.Context, dbUnique string, vme MonitoredDatabaseSettings) (metrics.Measurements, error) {
    40  	retData := make(metrics.Measurements, 0)
    41  	startTimeEpochNs := time.Now().UnixNano()
    42  
    43  	recoMetrics, err := GetAllRecoMetricsForVersion()
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  	for _, mvp := range recoMetrics {
    48  		data, e := QueryMeasurements(ctx, dbUnique, mvp.GetSQL(vme.Version))
    49  		if err != nil {
    50  			err = errors.Join(err, e)
    51  			continue
    52  		}
    53  		for _, d := range data {
    54  			d[metrics.EpochColumnName] = startTimeEpochNs
    55  			d["major_ver"] = vme.Version / 10
    56  			retData = append(retData, d)
    57  		}
    58  	}
    59  	if len(retData) == 0 { // insert a dummy entry minimally so that Grafana can show at least a dropdown
    60  		dummy := metrics.NewMeasurement(startTimeEpochNs)
    61  		dummy["tag_reco_topic"] = "dummy"
    62  		dummy["tag_object_name"] = "-"
    63  		dummy["recommendation"] = "no recommendations"
    64  		dummy["major_ver"] = vme.Version / 10
    65  		retData = append(retData, dummy)
    66  	}
    67  	return retData, err
    68  }
    69