github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/metrics/step_result.go (about)

     1  package metrics
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"time"
     7  
     8  	"github.com/kyma-project/kyma-environment-broker/internal"
     9  
    10  	"github.com/kyma-project/kyma-environment-broker/internal/process"
    11  	"github.com/pivotal-cf/brokerapi/v8/domain"
    12  	"github.com/prometheus/client_golang/prometheus"
    13  )
    14  
    15  // StepResultCollector provides the following metrics:
    16  // - compass_keb_provisioning_step_result{"operation_id",  "instance_id", "step_name", "global_account_id", "plan_id"}
    17  // - compass_keb_deprovisioning_step_result{"operation_id",  "instance_id", "step_name", "global_account_id", "plan_id"}
    18  // These gauges show the status of the operation step.
    19  // The value of the gauge could be:
    20  // 0 - Failed
    21  // 1 - Succeeded
    22  // 2 - In progress
    23  type StepResultCollector struct {
    24  	provisioningResultGauge   *prometheus.GaugeVec
    25  	deprovisioningResultGauge *prometheus.GaugeVec
    26  }
    27  
    28  func NewStepResultCollector() *StepResultCollector {
    29  	return &StepResultCollector{
    30  		provisioningResultGauge: prometheus.NewGaugeVec(prometheus.GaugeOpts{
    31  			Namespace: prometheusNamespace,
    32  			Subsystem: prometheusSubsystem,
    33  			Name:      "provisioning_step_result",
    34  			Help:      "Result of the provisioning step",
    35  		}, []string{"operation_id", "instance_id", "step_name", "global_account_id", "plan_id"}),
    36  		deprovisioningResultGauge: prometheus.NewGaugeVec(prometheus.GaugeOpts{
    37  			Namespace: prometheusNamespace,
    38  			Subsystem: prometheusSubsystem,
    39  			Name:      "deprovisioning_step_result",
    40  			Help:      "Result of the deprovisioning step",
    41  		}, []string{"operation_id", "instance_id", "step_name", "global_account_id", "plan_id"}),
    42  	}
    43  }
    44  
    45  func (c *StepResultCollector) Describe(ch chan<- *prometheus.Desc) {
    46  	c.provisioningResultGauge.Describe(ch)
    47  	c.deprovisioningResultGauge.Describe(ch)
    48  }
    49  
    50  func (c *StepResultCollector) Collect(ch chan<- prometheus.Metric) {
    51  	c.provisioningResultGauge.Collect(ch)
    52  	c.deprovisioningResultGauge.Collect(ch)
    53  }
    54  
    55  func (c *StepResultCollector) OnProvisioningStepProcessed(ctx context.Context, ev interface{}) error {
    56  	stepProcessed, ok := ev.(process.ProvisioningStepProcessed)
    57  	if !ok {
    58  		return fmt.Errorf("expected ProvisioningStepProcessed but got %+v", ev)
    59  	}
    60  
    61  	var resultValue float64
    62  	switch {
    63  	case stepProcessed.Operation.State == domain.Succeeded:
    64  		resultValue = resultSucceeded
    65  	case stepProcessed.When > 0 && stepProcessed.Error == nil:
    66  		resultValue = resultInProgress
    67  	case stepProcessed.When == 0 && stepProcessed.Error == nil:
    68  		resultValue = resultSucceeded
    69  	case stepProcessed.Error != nil:
    70  		resultValue = resultFailed
    71  	}
    72  	op := stepProcessed.Operation
    73  	pp := op.ProvisioningParameters
    74  	c.provisioningResultGauge.WithLabelValues(
    75  		op.ID,
    76  		op.InstanceID,
    77  		stepProcessed.StepName,
    78  		pp.ErsContext.GlobalAccountID,
    79  		pp.PlanID).Set(resultValue)
    80  
    81  	return nil
    82  }
    83  
    84  func (c *StepResultCollector) OnDeprovisioningStepProcessed(ctx context.Context, ev interface{}) error {
    85  	stepProcessed, ok := ev.(process.DeprovisioningStepProcessed)
    86  	if !ok {
    87  		return fmt.Errorf("expected DeprovisioningStepProcessed but got %+v", ev)
    88  	}
    89  
    90  	var resultValue float64
    91  	switch {
    92  	case stepProcessed.When > 0 && stepProcessed.Error == nil:
    93  		resultValue = resultInProgress
    94  	case stepProcessed.When == 0 && stepProcessed.Error == nil:
    95  		resultValue = resultSucceeded
    96  	case stepProcessed.Error != nil:
    97  		resultValue = resultFailed
    98  	}
    99  
   100  	// Create_Runtime step always returns operation, 1 second, nil if everything is ok
   101  	// this code is a workaround and should be removed when the step engine is refactored
   102  	if stepProcessed.StepName == "Create_Runtime" && stepProcessed.When == time.Second {
   103  		resultValue = resultSucceeded
   104  	}
   105  
   106  	op := stepProcessed.Operation
   107  	pp := op.ProvisioningParameters
   108  	c.deprovisioningResultGauge.WithLabelValues(
   109  		op.ID,
   110  		op.InstanceID,
   111  		stepProcessed.StepName,
   112  		pp.ErsContext.GlobalAccountID,
   113  		pp.PlanID).Set(resultValue)
   114  	return nil
   115  }
   116  
   117  func (c *StepResultCollector) OnOperationStepProcessed(ctx context.Context, ev interface{}) error {
   118  	stepProcessed, ok := ev.(process.OperationStepProcessed)
   119  	if !ok {
   120  		return fmt.Errorf("expected OperationStepProcessed but got %+v", ev)
   121  	}
   122  
   123  	switch {
   124  	case stepProcessed.Operation.Type == internal.OperationTypeProvision:
   125  		provisioningStepProcessed := process.ProvisioningStepProcessed{
   126  			Operation:     internal.ProvisioningOperation{Operation: stepProcessed.Operation},
   127  			StepProcessed: stepProcessed.StepProcessed,
   128  		}
   129  		err := c.OnProvisioningStepProcessed(ctx, provisioningStepProcessed)
   130  		if err != nil {
   131  			return err
   132  		}
   133  	case stepProcessed.Operation.Type == internal.OperationTypeDeprovision:
   134  		deprovisioningStepProcessed := process.DeprovisioningStepProcessed{
   135  			Operation:     internal.DeprovisioningOperation{Operation: stepProcessed.Operation},
   136  			StepProcessed: stepProcessed.StepProcessed,
   137  		}
   138  		err := c.OnDeprovisioningStepProcessed(ctx, deprovisioningStepProcessed)
   139  		if err != nil {
   140  			return err
   141  		}
   142  	default:
   143  		return fmt.Errorf("expected OperationStep of types [%s, %s] but got %+v", internal.OperationTypeProvision, internal.OperationTypeDeprovision, stepProcessed.Operation.Type)
   144  	}
   145  
   146  	return nil
   147  }