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 }