...

Source file src/github.com/cybertec-postgresql/pgwatch/v3/internal/metrics/yaml.go

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

     1  package metrics
     2  
     3  import (
     4  	"context"
     5  	_ "embed"
     6  	"io/fs"
     7  	"maps"
     8  	"os"
     9  	"path/filepath"
    10  	"strings"
    11  
    12  	"gopkg.in/yaml.v3"
    13  )
    14  
    15  func NewYAMLMetricReaderWriter(ctx context.Context, path string) (ReaderWriter, error) {
    16  	if path == "" {
    17  		return NewDefaultMetricReader(ctx)
    18  	}
    19  	return &fileMetricReader{
    20  		ctx:  ctx,
    21  		path: path,
    22  	}, nil
    23  }
    24  
    25  type fileMetricReader struct {
    26  	ctx  context.Context
    27  	path string
    28  }
    29  
    30  func (fmr *fileMetricReader) WriteMetrics(metricDefs *Metrics) error {
    31  	yamlData, _ := yaml.Marshal(metricDefs)
    32  	return os.WriteFile(fmr.path, yamlData, 0644)
    33  }
    34  
    35  //go:embed metrics.yaml
    36  var defaultMetricsYAML []byte
    37  
    38  func (fmr *fileMetricReader) GetMetrics() (metrics *Metrics, err error) {
    39  	metrics = &Metrics{MetricDefs{}, PresetDefs{}}
    40  	if fmr.path == "" {
    41  		err = yaml.Unmarshal(defaultMetricsYAML, metrics)
    42  		return
    43  	}
    44  
    45  	fi, err := os.Stat(fmr.path)
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  	switch mode := fi.Mode(); {
    50  	case mode.IsDir():
    51  		err = filepath.WalkDir(fmr.path, func(path string, d fs.DirEntry, err error) error {
    52  			if err != nil {
    53  				return err
    54  			}
    55  			ext := strings.ToLower(filepath.Ext(d.Name()))
    56  			if d.IsDir() || ext != ".yaml" && ext != ".yml" {
    57  				return nil
    58  			}
    59  			var m *Metrics
    60  			if m, err = fmr.getMetrics(path); err == nil {
    61  				maps.Copy(metrics.PresetDefs, m.PresetDefs)
    62  				maps.Copy(metrics.MetricDefs, m.MetricDefs)
    63  			}
    64  			return err
    65  		})
    66  	case mode.IsRegular():
    67  		metrics, err = fmr.getMetrics(fmr.path)
    68  	}
    69  	return
    70  }
    71  
    72  func (fmr *fileMetricReader) getMetrics(metricsFilePath string) (metrics *Metrics, err error) {
    73  	var yamlFile []byte
    74  	if yamlFile, err = os.ReadFile(metricsFilePath); err != nil {
    75  		return
    76  	}
    77  	metrics = &Metrics{MetricDefs{}, PresetDefs{}}
    78  	err = yaml.Unmarshal(yamlFile, &metrics)
    79  	return
    80  }
    81  
    82  func (fmr *fileMetricReader) DeleteMetric(metricName string) error {
    83  	metrics, err := fmr.GetMetrics()
    84  	if err != nil {
    85  		return err
    86  	}
    87  	delete(metrics.MetricDefs, metricName)
    88  	return fmr.WriteMetrics(metrics)
    89  }
    90  
    91  func (fmr *fileMetricReader) UpdateMetric(metricName string, metric Metric) error {
    92  	metrics, err := fmr.GetMetrics()
    93  	if err != nil {
    94  		return err
    95  	}
    96  	metrics.MetricDefs[metricName] = metric
    97  	return fmr.WriteMetrics(metrics)
    98  }
    99  
   100  func (fmr *fileMetricReader) CreateMetric(metricName string, metric Metric) error {
   101  	metrics, err := fmr.GetMetrics()
   102  	if err != nil {
   103  		return err
   104  	}
   105  	// Check if metric already exists
   106  	if _, exists := metrics.MetricDefs[metricName]; exists {
   107  		return ErrMetricExists
   108  	}
   109  	metrics.MetricDefs[metricName] = metric
   110  	return fmr.WriteMetrics(metrics)
   111  }
   112  
   113  func (fmr *fileMetricReader) DeletePreset(presetName string) error {
   114  	metrics, err := fmr.GetMetrics()
   115  	if err != nil {
   116  		return err
   117  	}
   118  	delete(metrics.PresetDefs, presetName)
   119  	return fmr.WriteMetrics(metrics)
   120  }
   121  
   122  func (fmr *fileMetricReader) UpdatePreset(presetName string, preset Preset) error {
   123  	metrics, err := fmr.GetMetrics()
   124  	if err != nil {
   125  		return err
   126  	}
   127  	metrics.PresetDefs[presetName] = preset
   128  	return fmr.WriteMetrics(metrics)
   129  }
   130  
   131  func (fmr *fileMetricReader) CreatePreset(presetName string, preset Preset) error {
   132  	metrics, err := fmr.GetMetrics()
   133  	if err != nil {
   134  		return err
   135  	}
   136  	// Check if preset already exists
   137  	if _, exists := metrics.PresetDefs[presetName]; exists {
   138  		return ErrPresetExists
   139  	}
   140  	metrics.PresetDefs[presetName] = preset
   141  	return fmr.WriteMetrics(metrics)
   142  }
   143