github.com/verrazzano/verrazzano@v1.7.1/tools/psr/backend/workers/http/get/get.go (about)

     1  // Copyright (c) 2022, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  package get
     5  
     6  import (
     7  	"fmt"
     8  	"net/http"
     9  	"sync/atomic"
    10  
    11  	"github.com/prometheus/client_golang/prometheus"
    12  	"github.com/verrazzano/verrazzano/pkg/log/vzlog"
    13  	"github.com/verrazzano/verrazzano/tools/psr/backend/config"
    14  	"github.com/verrazzano/verrazzano/tools/psr/backend/metrics"
    15  	"github.com/verrazzano/verrazzano/tools/psr/backend/osenv"
    16  	"github.com/verrazzano/verrazzano/tools/psr/backend/spi"
    17  )
    18  
    19  var httpGetFunc = http.Get
    20  
    21  const (
    22  	// metricsPrefix is the prefix that is automatically pre-pended to all metrics exported by this worker.
    23  	metricsPrefix = "http_get"
    24  
    25  	// ServiceName specifies the name of the service in the local cluster
    26  	// By default, the ServiceName is not specified
    27  	ServiceName = "SERVICE_NAME"
    28  
    29  	// ServiceNamespace specifies the namespace of the service in the local cluster
    30  	// By default, the ServiceNamespace is not specified
    31  	ServiceNamespace = "SERVICE_NAMESPACE"
    32  
    33  	// ServicePort specifies the port of the service in the local cluster
    34  	// By default, the ServicePort is not specified
    35  	ServicePort = "SERVICE_PORT"
    36  
    37  	// Path specifies the path in the URL
    38  	// By default, the path is not specified
    39  	Path = "PATH"
    40  )
    41  
    42  type worker struct {
    43  	metricDescList []prometheus.Desc
    44  	*workerMetrics
    45  }
    46  
    47  var _ spi.Worker = worker{}
    48  
    49  // workerMetrics holds the metrics produced by the worker. Metrics must be thread safe.
    50  type workerMetrics struct {
    51  	getRequestsCountTotal          metrics.MetricItem
    52  	getRequestsSucceededCountTotal metrics.MetricItem
    53  	getRequestsFailedCountTotal    metrics.MetricItem
    54  }
    55  
    56  func NewHTTPGetWorker() (spi.Worker, error) {
    57  	w := worker{workerMetrics: &workerMetrics{
    58  		getRequestsCountTotal: metrics.MetricItem{
    59  			Name: "request_count_total",
    60  			Help: "The total number of GET requests",
    61  			Type: prometheus.CounterValue,
    62  		},
    63  		getRequestsSucceededCountTotal: metrics.MetricItem{
    64  			Name: "request_succeeded_count_total",
    65  			Help: "The total number of successful GET requests",
    66  			Type: prometheus.CounterValue,
    67  		},
    68  		getRequestsFailedCountTotal: metrics.MetricItem{
    69  			Name: "request_failed_count_total",
    70  			Help: "The total number of failed GET requests",
    71  			Type: prometheus.CounterValue,
    72  		},
    73  	}}
    74  
    75  	if err := config.PsrEnv.LoadFromEnv(w.GetEnvDescList()); err != nil {
    76  		return w, err
    77  	}
    78  
    79  	metricsLabels := map[string]string{
    80  		config.PsrWorkerTypeMetricsName: config.PsrEnv.GetEnv(config.PsrWorkerType),
    81  	}
    82  
    83  	w.metricDescList = metrics.BuildMetricDescList([]*metrics.MetricItem{
    84  		&w.getRequestsCountTotal,
    85  		&w.getRequestsSucceededCountTotal,
    86  		&w.getRequestsFailedCountTotal,
    87  	}, metricsLabels, w.GetWorkerDesc().MetricsPrefix)
    88  	return w, nil
    89  }
    90  
    91  // GetWorkerDesc returns the WorkerDesc for the worker
    92  func (w worker) GetWorkerDesc() spi.WorkerDesc {
    93  	return spi.WorkerDesc{
    94  		WorkerType:    config.WorkerTypeHTTPGet,
    95  		Description:   "The get worker makes GET request on the given endpoint",
    96  		MetricsPrefix: metricsPrefix,
    97  	}
    98  }
    99  
   100  func (w worker) GetEnvDescList() []osenv.EnvVarDesc {
   101  	return []osenv.EnvVarDesc{
   102  		{Key: ServiceName, DefaultVal: "", Required: true},
   103  		{Key: ServiceNamespace, DefaultVal: "", Required: true},
   104  		{Key: ServicePort, DefaultVal: "", Required: true},
   105  		{Key: Path, DefaultVal: "", Required: true},
   106  	}
   107  }
   108  
   109  func (w worker) GetMetricDescList() []prometheus.Desc {
   110  	return w.metricDescList
   111  }
   112  
   113  func (w worker) GetMetricList() []prometheus.Metric {
   114  	return []prometheus.Metric{
   115  		w.getRequestsCountTotal.BuildMetric(),
   116  		w.getRequestsSucceededCountTotal.BuildMetric(),
   117  		w.getRequestsFailedCountTotal.BuildMetric(),
   118  	}
   119  }
   120  
   121  func (w worker) WantLoopInfoLogged() bool {
   122  	return false
   123  }
   124  
   125  func (w worker) PreconditionsMet() (bool, error) {
   126  	return true, nil
   127  }
   128  
   129  func (w worker) DoWork(conf config.CommonConfig, log vzlog.VerrazzanoLogger) error {
   130  	var lc, ls, lf int64
   131  	//increment getRequestsCountTotal
   132  	lc = atomic.AddInt64(&w.workerMetrics.getRequestsCountTotal.Val, 1)
   133  	resp, err := httpGetFunc("http://" + config.PsrEnv.GetEnv(ServiceName) +
   134  		"." + config.PsrEnv.GetEnv(ServiceNamespace) +
   135  		".svc.cluster.local:" +
   136  		config.PsrEnv.GetEnv(ServicePort) +
   137  		"/" + config.PsrEnv.GetEnv(Path))
   138  	if err != nil {
   139  		atomic.AddInt64(&w.workerMetrics.getRequestsFailedCountTotal.Val, 1)
   140  		return err
   141  	}
   142  	if resp == nil {
   143  		atomic.AddInt64(&w.workerMetrics.getRequestsFailedCountTotal.Val, 1)
   144  		return fmt.Errorf("GET request to endpoint received a nil response")
   145  	}
   146  	if resp.StatusCode == 200 {
   147  		ls = atomic.AddInt64(&w.workerMetrics.getRequestsSucceededCountTotal.Val, 1)
   148  	} else {
   149  		lf = atomic.AddInt64(&w.workerMetrics.getRequestsFailedCountTotal.Val, 1)
   150  	}
   151  	logMsg := fmt.Sprintf("HttpGet worker total requests %v, "+
   152  		" total successful requests %v, total failed requests %v",
   153  		lc, ls, lf)
   154  	log.Debugf(logMsg)
   155  	return nil
   156  }