github.com/gocrane/crane@v0.11.0/pkg/recommendation/recommender/resource/observe.go (about)

     1  package resource
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  
     7  	v1 "k8s.io/api/core/v1"
     8  	"k8s.io/apimachinery/pkg/api/resource"
     9  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    10  
    11  	"github.com/gocrane/crane/pkg/metrics"
    12  	"github.com/gocrane/crane/pkg/recommendation/framework"
    13  )
    14  
    15  // Observe enhance the observability.
    16  func (rr *ResourceRecommender) Observe(ctx *framework.RecommendationContext) error {
    17  	// get new PodTemplate
    18  	var newObject map[string]interface{}
    19  	if err := json.Unmarshal([]byte(ctx.Recommendation.Status.RecommendedInfo), &newObject); err != nil {
    20  		return err
    21  	}
    22  
    23  	podTemplateObject, found, err := unstructured.NestedMap(newObject, "spec", "template")
    24  	if !found || err != nil {
    25  		return fmt.Errorf("get template from unstructed object failed. ")
    26  	}
    27  
    28  	var newPodTemplate v1.PodTemplateSpec
    29  	err = framework.ObjectConversion(podTemplateObject, &newPodTemplate)
    30  	if err != nil {
    31  		return err
    32  	}
    33  
    34  	resourceNameList := []v1.ResourceName{v1.ResourceCPU, v1.ResourceMemory}
    35  	for _, container := range newPodTemplate.Spec.Containers {
    36  		for _, resourceName := range resourceNameList {
    37  			err = rr.recordResourceRecommendation(ctx, container.Name, resourceName, container.Resources.Requests[resourceName])
    38  			if err != nil {
    39  				return err
    40  			}
    41  		}
    42  	}
    43  
    44  	return nil
    45  }
    46  
    47  func (rr *ResourceRecommender) recordResourceRecommendation(ctx *framework.RecommendationContext, containerName string, resName v1.ResourceName, quantity resource.Quantity) error {
    48  	labels := map[string]string{
    49  		"apiversion": ctx.Recommendation.Spec.TargetRef.APIVersion,
    50  		"owner_kind": ctx.Recommendation.Spec.TargetRef.Kind,
    51  		"namespace":  ctx.Recommendation.Spec.TargetRef.Namespace,
    52  		"owner_name": ctx.Recommendation.Spec.TargetRef.Name,
    53  		"container":  containerName,
    54  		"resource":   resName.String(),
    55  	}
    56  
    57  	switch resName {
    58  	case v1.ResourceCPU:
    59  		metrics.ResourceRecommendation.With(labels).Set(float64(quantity.MilliValue()) / 1000.)
    60  	case v1.ResourceMemory:
    61  		metrics.ResourceRecommendation.With(labels).Set(float64(quantity.Value()))
    62  	}
    63  
    64  	return nil
    65  }