From 1a48e087a92173139dd0095c44b54923f1dffb4a Mon Sep 17 00:00:00 2001 From: mervynwang Date: Wed, 14 May 2025 14:39:48 +0800 Subject: [PATCH 1/3] support recommend with pod metric --- pkg/controller/recommendation/updater.go | 1 + pkg/features/features.go | 4 + pkg/metricnaming/naming.go | 16 ++ pkg/recommend/types/types.go | 6 + .../recommender/resource/recommend.go | 266 +++++++++++++----- pkg/utils/expression_prom_default.go | 6 +- 6 files changed, 233 insertions(+), 66 deletions(-) diff --git a/pkg/controller/recommendation/updater.go b/pkg/controller/recommendation/updater.go index 37b0ff08e..3af86b88a 100644 --- a/pkg/controller/recommendation/updater.go +++ b/pkg/controller/recommendation/updater.go @@ -61,6 +61,7 @@ func (c *RecommendationController) UpdateRecommendation(ctx context.Context, rec switch string(recommendation.Spec.Type) { case recommender.ResourceRecommender: if proposedRecommendation.ResourceRequest != nil { + proposedRecommendation.ResourceRequest.Pod = nil resourceValue, err := yaml.Marshal(proposedRecommendation.ResourceRequest) if err != nil { return false, fmt.Errorf("marshal ResourceRequest failed: %v. ", err) diff --git a/pkg/features/features.go b/pkg/features/features.go index 18003578a..fef769914 100644 --- a/pkg/features/features.go +++ b/pkg/features/features.go @@ -36,6 +36,9 @@ const ( // QOSInitializer enables the qos initialization featrues. QOSInitializer featuregate.Feature = "QOSInitializer" + + // EnablePodRecommendation enables the pod recommendation features. + EnablePodRecommendation featuregate.Feature = "EnablePodRecommendation" ) var defaultFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{ @@ -49,6 +52,7 @@ var defaultFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{ CraneCPUManager: {Default: false, PreRelease: featuregate.Alpha}, QOSInitializer: {Default: false, PreRelease: featuregate.Alpha}, CraneDashboardControl: {Default: false, PreRelease: featuregate.Alpha}, + EnablePodRecommendation: {Default: false, PreRelease: featuregate.Alpha}, } func init() { diff --git a/pkg/metricnaming/naming.go b/pkg/metricnaming/naming.go index 1a1547286..2b25d095f 100644 --- a/pkg/metricnaming/naming.go +++ b/pkg/metricnaming/naming.go @@ -76,6 +76,22 @@ func ResourceToWorkloadMetricNamer(target *corev1.ObjectReference, resourceName } } +func ResourceToPodMetricNamer(namespace, podName string, resourceName corev1.ResourceName, caller string) MetricNamer { + // pod + return &GeneralMetricNamer{ + CallerName: caller, + Metric: &metricquery.Metric{ + Type: metricquery.PodMetricType, + MetricName: resourceName.String(), + Pod: &metricquery.PodNamerInfo{ + Namespace: namespace, + Name: podName, + Selector: labels.Everything(), + }, + }, + } +} + func ResourceToContainerMetricNamer(namespace, apiVersion, workloadKind, workloadName, containerName string, resourceName corev1.ResourceName, caller string) MetricNamer { // container return &GeneralMetricNamer{ diff --git a/pkg/recommend/types/types.go b/pkg/recommend/types/types.go index a9c0af536..d4260d399 100644 --- a/pkg/recommend/types/types.go +++ b/pkg/recommend/types/types.go @@ -53,6 +53,7 @@ type EffectiveHorizontalPodAutoscalerRecommendation struct { } type ResourceRequestRecommendation struct { + Pod *PodRecommendation `json:"pod,omitempty"` Containers []ContainerRecommendation `json:"containers,omitempty"` } @@ -61,4 +62,9 @@ type ContainerRecommendation struct { Target ResourceList `json:"target,omitempty"` } +type PodRecommendation struct { + PodName string `json:"podName,omitempty"` + Target ResourceList `json:"target,omitempty"` +} + type ResourceList map[corev1.ResourceName]string diff --git a/pkg/recommendation/recommender/resource/recommend.go b/pkg/recommendation/recommender/resource/recommend.go index f03f8fc5a..8f3412a66 100644 --- a/pkg/recommendation/recommender/resource/recommend.go +++ b/pkg/recommendation/recommender/resource/recommend.go @@ -9,14 +9,19 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/util/errors" + utilfeature "k8s.io/apiserver/pkg/util/feature" recommendermodel "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/recommender/model" "k8s.io/klog/v2" "sigs.k8s.io/yaml" predictionapi "github.com/gocrane/api/prediction/v1alpha1" + "github.com/gocrane/crane/pkg/common" + "github.com/gocrane/crane/pkg/features" "github.com/gocrane/crane/pkg/metricnaming" "github.com/gocrane/crane/pkg/oom" + "github.com/gocrane/crane/pkg/prediction" "github.com/gocrane/crane/pkg/prediction/config" "github.com/gocrane/crane/pkg/recommend/types" "github.com/gocrane/crane/pkg/recommendation/framework" @@ -90,6 +95,8 @@ func (rr *ResourceRecommender) Recommend(ctx *framework.RecommendationContext) e } resourceRecommendation := &types.ResourceRequestRecommendation{} + namespace := ctx.Object.GetNamespace() + caller := fmt.Sprintf(callerFormat, klog.KObj(ctx.Recommendation), ctx.Recommendation.UID) var newContainers []corev1.Container var oldContainers []corev1.Container @@ -99,82 +106,56 @@ func (rr *ResourceRecommender) Recommend(ctx *framework.RecommendationContext) e return err } - namespace := ctx.Object.GetNamespace() - for _, c := range ctx.Pods[0].Spec.Containers { - cr := types.ContainerRecommendation{ - ContainerName: c.Name, - Target: map[corev1.ResourceName]string{}, - } - - caller := fmt.Sprintf(callerFormat, klog.KObj(ctx.Recommendation), ctx.Recommendation.UID) - metricNamer := metricnaming.ResourceToContainerMetricNamer(namespace, ctx.Recommendation.Spec.TargetRef.APIVersion, - ctx.Recommendation.Spec.TargetRef.Kind, ctx.Recommendation.Spec.TargetRef.Name, c.Name, corev1.ResourceCPU, caller) - klog.Infof("%s: CPU query for resource request recommendation: %s", ctx.String(), metricNamer.BuildUniqueKey()) - cpuConfig := rr.makeCpuConfig() - tsList, err := utils.QueryPredictedValuesOnce(ctx.Recommendation, predictor, caller, cpuConfig, metricNamer) + // pod + if utilfeature.DefaultFeatureGate.Enabled(features.EnablePodRecommendation) { + cpuTsList, memoryTsList, usePodMetrics, err := rr.getPodCpuAndMemoryTsList(ctx, namespace, caller, predictor) if err != nil { - return err + klog.Warningf("getPodCpuAndMemoryTsList err: %v", err) } - if len(tsList) < 1 || len(tsList[0].Samples) < 1 { - return fmt.Errorf("no value retured for queryExpr: %s", metricNamer.BuildUniqueKey()) - } - // Check timestamp is completed - if rr.HistoryCompletionCheck { - completion, existDays, err := utils.DetectTimestampCompletion(tsList, rr.CpuModelHistoryLength, time.Now()) - if !completion || err != nil { - return fmt.Errorf("%s: cpu timestamps are not completed, expect %s actual %d days", metricNamer.BuildUniqueKey(), rr.CpuModelHistoryLength, existDays) + if usePodMetrics { + klog.V(4).Infof("use pod metrics for pod %s", ctx.Pods[0].Name) + pr := types.PodRecommendation{ + PodName: ctx.Pods[0].Name, + Target: map[corev1.ResourceName]string{}, } - } - v := int64(tsList[0].Samples[0].Value * 1000) - cpuQuantity := resource.NewMilliQuantity(v, resource.DecimalSI) - klog.Infof("%s: container %s recommended cpu %s", ctx.String(), c.Name, cpuQuantity.String()) + cpuQuantity, memQuantity, err := rr.recommendCpuAndMemResources(ctx, cpuTsList, memoryTsList, oomRecords, namespace, ctx.Object.GetName(), ctx.Pods[0].Name) + if err != nil { + klog.Errorf("recommendCpuAndMemResources %v", err) + } - metricNamer = metricnaming.ResourceToContainerMetricNamer(namespace, ctx.Recommendation.Spec.TargetRef.APIVersion, - ctx.Recommendation.Spec.TargetRef.Kind, ctx.Recommendation.Spec.TargetRef.Name, c.Name, corev1.ResourceMemory, caller) - klog.Infof("%s Memory query for resource request recommendation: %s", ctx.String(), metricNamer.BuildUniqueKey()) - memConfig := rr.makeMemConfig() - tsList, err = utils.QueryPredictedValuesOnce(ctx.Recommendation, predictor, caller, memConfig, metricNamer) + if cpuQuantity != nil { + pr.Target[corev1.ResourceCPU] = cpuQuantity.String() + } + if memQuantity != nil { + pr.Target[corev1.ResourceMemory] = memQuantity.String() + } + + resourceRecommendation.Pod = &pr + } else { + klog.V(4).Infof("not use pod metrics for pod %s", ctx.Pods[0].Name) + } + } + + // containers + for _, c := range ctx.Pods[0].Spec.Containers { + cpuTsList, memTsList, err := rr.getContainerCpuAndMemoryTsList(ctx, predictor, caller, namespace, c.Name) if err != nil { return err } - if len(tsList) < 1 || len(tsList[0].Samples) < 1 { - return fmt.Errorf("no value retured for queryExpr: %s", metricNamer.BuildUniqueKey()) - } - // Check timestamp is completed - if rr.HistoryCompletionCheck { - completion, existDays, err := utils.DetectTimestampCompletion(tsList, rr.MemHistoryLength, time.Now()) - if !completion || err != nil { - return fmt.Errorf("%s: memory timestamps are not completed, expect %s actual %d days ", metricNamer.BuildUniqueKey(), rr.MemHistoryLength, existDays) - } - } - v = int64(tsList[0].Samples[0].Value) - if v <= 0 { - return fmt.Errorf("no enough metrics") + cpuQuantity, memQuantity, err := rr.recommendCpuAndMemResources(ctx, cpuTsList, memTsList, oomRecords, namespace, ctx.Object.GetName(), c.Name) + if err != nil { + return err } - memQuantity := resource.NewQuantity(v, resource.BinarySI) - klog.Infof("%s: container %s recommended memory %s", ctx.String(), c.Name, memQuantity.String()) - - // Use oom protected memory if exist - if rr.OOMProtection { - oomProtectMem := rr.MemoryOOMProtection(oomRecords, namespace, ctx.Object.GetName(), c.Name) - if oomProtectMem != nil && !oomProtectMem.IsZero() && oomProtectMem.Cmp(*memQuantity) > 0 { - klog.Infof("%s: container %s using oomProtect Memory %s", ctx.String(), c.Name, oomProtectMem.String()) - memQuantity = oomProtectMem - } + if cpuQuantity == nil || memQuantity == nil { + return fmt.Errorf("resource recommendation failed for container %s: cpu=%v, memory=%v", c.Name, cpuQuantity != nil, memQuantity != nil) } - // Resource Specification enabled - if rr.Specification { - normalizedCpu, normalizedMem := GetNormalizedResource(cpuQuantity, memQuantity, rr.SpecificationConfigs) - klog.Infof("GetNormalizedResource currentCpu %s normalizedCpu %s currentMem %s normalizedMem %s", cpuQuantity.String(), normalizedCpu.String(), memQuantity.String(), normalizedMem.String()) - if normalizedCpu.Value() > 0 && normalizedMem.Value() > 0 { - cpuQuantity = &normalizedCpu - memQuantity = &normalizedMem - } + cr := types.ContainerRecommendation{ + ContainerName: c.Name, + Target: map[corev1.ResourceName]string{}, } - cr.Target[corev1.ResourceCPU] = cpuQuantity.String() cr.Target[corev1.ResourceMemory] = memQuantity.String() @@ -269,3 +250,162 @@ func (rr *ResourceRecommender) MemoryOOMProtection(oomRecords []oom.OOMRecord, n return nil } + +// getContainerCpuAndMemoryTsList gets container metrics data +func (rr *ResourceRecommender) getContainerCpuAndMemoryTsList(ctx *framework.RecommendationContext, + predictor prediction.Interface, + caller string, + namespace, containerName string) ([]*common.TimeSeries, []*common.TimeSeries, error) { + + // cpu + cpuNamer := metricnaming.ResourceToContainerMetricNamer(namespace, + ctx.Recommendation.Spec.TargetRef.APIVersion, + ctx.Recommendation.Spec.TargetRef.Kind, + ctx.Recommendation.Spec.TargetRef.Name, + containerName, + corev1.ResourceCPU, + caller) + + cpuTs, err := utils.QueryPredictedValuesOnce(ctx.Recommendation, predictor, caller, rr.makeCpuConfig(), cpuNamer) + if err != nil { + return nil, nil, err + } + + // memory + memNamer := metricnaming.ResourceToContainerMetricNamer(namespace, + ctx.Recommendation.Spec.TargetRef.APIVersion, + ctx.Recommendation.Spec.TargetRef.Kind, + ctx.Recommendation.Spec.TargetRef.Name, + containerName, + corev1.ResourceMemory, + caller) + + memTs, err := utils.QueryPredictedValuesOnce(ctx.Recommendation, predictor, caller, rr.makeMemConfig(), memNamer) + if err != nil { + return nil, nil, err + } + + return cpuTs, memTs, nil +} + +func (rr *ResourceRecommender) getPodCpuAndMemoryTsList(ctx *framework.RecommendationContext, namespace, caller string, predictor prediction.Interface) ([]*common.TimeSeries, []*common.TimeSeries, bool, error) { + var errs []error + cpuOK, memOK := true, true + + // cpu + cpuMetricNamer := metricnaming.ResourceToPodMetricNamer(namespace, + ctx.Pods[0].Name, + corev1.ResourceCPU, + caller) + cpuTsList, err := utils.QueryPredictedValuesOnce(ctx.Recommendation, predictor, caller, rr.makeCpuConfig(), cpuMetricNamer) + if err != nil { + cpuOK = false + errs = append(errs, err) + } + + // memory + memoryMetricNamer := metricnaming.ResourceToPodMetricNamer(namespace, + ctx.Pods[0].Name, + corev1.ResourceMemory, + caller) + memTsList, err := utils.QueryPredictedValuesOnce(ctx.Recommendation, predictor, caller, rr.makeMemConfig(), memoryMetricNamer) + if err != nil { + memOK = false + errs = append(errs, err) + } + + if !cpuOK && !memOK { + return nil, nil, false, errors.NewAggregate(errs) + } + + return cpuTsList, memTsList, true, errors.NewAggregate(errs) +} + +// recommendCpuAndMemResources recommends CPU and memory resources based on historical monitoring data, OOM records, and resource specification normalization +func (rr *ResourceRecommender) recommendCpuAndMemResources(ctx *framework.RecommendationContext, + cpuTsList []*common.TimeSeries, + memTsList []*common.TimeSeries, + oomRecords []oom.OOMRecord, + namespace, workloadName, containerName string) (*resource.Quantity, *resource.Quantity, error) { + + var errs []error + cpuOK, memOK := true, true + + // cpu + cpuQuantity, err := rr.recommendSingleResource(ctx, cpuTsList, rr.CpuModelHistoryLength, corev1.ResourceCPU, containerName) + if err != nil { + cpuOK = false + errs = append(errs, err) + } + + // memory + memQuantity, err := rr.recommendSingleResource(ctx, memTsList, rr.MemHistoryLength, corev1.ResourceMemory, containerName) + if err != nil { + memOK = false + errs = append(errs, err) + } + + if !cpuOK && !memOK { + return nil, nil, errors.NewAggregate(errs) + } + + // adjust memory recommendations by analyzing historical OOM events + if memOK && rr.OOMProtection { + if oomMem := rr.MemoryOOMProtection(oomRecords, namespace, workloadName, containerName); oomMem != nil { + if !oomMem.IsZero() && oomMem.Cmp(*memQuantity) > 0 { + klog.Infof("%s: %s using oomProtect Memory %s", ctx.String(), containerName, oomMem.String()) + memQuantity = oomMem + } + } + } + + // standardize resource recommendations to predefined specifications + if rr.Specification { + if cpuOK && memOK { + normalizedCpu, normalizedMem := GetNormalizedResource(cpuQuantity, memQuantity, rr.SpecificationConfigs) + klog.Infof("GetNormalizedResource currentCpu %s normalizedCpu %s currentMem %s normalizedMem %s", + cpuQuantity.String(), normalizedCpu.String(), memQuantity.String(), normalizedMem.String()) + if normalizedCpu.Value() > 0 && normalizedMem.Value() > 0 { + cpuQuantity = &normalizedCpu + memQuantity = &normalizedMem + } + } else { + return nil, nil, fmt.Errorf("cpu or memory recommendation failed, cannot standardize resource recommendations to predefined specifications") + } + } + + return cpuQuantity, memQuantity, nil +} + +func (rr *ResourceRecommender) recommendSingleResource(ctx *framework.RecommendationContext, + tsList []*common.TimeSeries, + historyLength string, + resourceType corev1.ResourceName, + containerName string) (*resource.Quantity, error) { + + if len(tsList) == 0 || len(tsList[0].Samples) == 0 { + return nil, fmt.Errorf("no metrics data for %s", resourceType) + } + + if rr.HistoryCompletionCheck { + completion, existDays, err := utils.DetectTimestampCompletion(tsList, historyLength, time.Now()) + if !completion || err != nil { + return nil, fmt.Errorf("%s timestamps not completed: expect %s actual %d days", resourceType, historyLength, existDays) + } + } + + value := tsList[0].Samples[0].Value + var quantity *resource.Quantity + if resourceType == corev1.ResourceCPU { + value *= 1000 + quantity = resource.NewMilliQuantity(int64(value), resource.DecimalSI) + } else if resourceType == corev1.ResourceMemory { + quantity = resource.NewQuantity(int64(value), resource.BinarySI) + if value <= 0 { + return nil, fmt.Errorf("invalid %s value: %f", resourceType, value) + } + } + + klog.Infof("%s: %s recommended %s %s", ctx.String(), containerName, resourceType, quantity.String()) + return quantity, nil +} diff --git a/pkg/utils/expression_prom_default.go b/pkg/utils/expression_prom_default.go index c97faf863..ddd2c56d1 100644 --- a/pkg/utils/expression_prom_default.go +++ b/pkg/utils/expression_prom_default.go @@ -29,9 +29,9 @@ const ( NodeMemUsageUtilizationExprTemplate = `sum(label_replace(container_memory_usage_bytes{instance="%s", namespace!="",container!="POD", container!="",image!=""EXTENSION_LABELS_HOLDER}, "node", "$1", "instance", "(^[^:]+)") * on (node) group_left() max(kube_node_labels{label_beta_kubernetes_io_instance_type!~"eklet", label_node_kubernetes_io_instance_type!~"eklet"EXTENSION_LABELS_HOLDER}) by (node)) by (node) / sum(kube_node_status_capacity{node="%s", resource="memory", unit="byte"EXTENSION_LABELS_HOLDER} * on (node) group_left() max(kube_node_labels{label_beta_kubernetes_io_instance_type!~"eklet", label_node_kubernetes_io_instance_type!~"eklet"EXTENSION_LABELS_HOLDER}) by (node)) by (node) ` // PodCpuUsageExprTemplate is used to query pod cpu usage by promql, param is namespace,pod, duration str - PodCpuUsageExprTemplate = `sum(irate(container_cpu_usage_seconds_total{container!="POD",namespace="%s",pod="%s"EXTENSION_LABELS_HOLDER}[%s]))` + PodCpuUsageExprTemplate = `sum(irate(pod_cpu_seconds_total{mode!~"idle|iowait",namespace="%s",pod="%s"EXTENSION_LABELS_HOLDER}[%s]))` // PodMemUsageExprTemplate is used to query pod cpu usage by promql, param is namespace,pod - PodMemUsageExprTemplate = `sum(container_memory_working_set_bytes{container!="POD",namespace="%s",pod="%s"EXTENSION_LABELS_HOLDER})` + PodMemUsageExprTemplate = `pod_memory_MemTotal_bytes{namespace="%s",pod="%s"EXTENSION_LABELS_HOLDER} - pod_memory_MemFree_bytes{namespace="%s",pod="%s"EXTENSION_LABELS_HOLDER}` // ContainerCpuUsageExprTemplate is used to query container cpu usage by promql, param is namespace,pod,container duration str ContainerCpuUsageExprTemplate = `irate(container_cpu_usage_seconds_total{container!="POD",namespace="%s",pod=~"%s",container="%s"EXTENSION_LABELS_HOLDER}[%s])` @@ -117,7 +117,7 @@ func GetPodCpuUsageExpression(namespace string, name string) string { } func GetPodMemUsageExpression(namespace string, name string) string { - return fmtSprintfInternal(PodMemUsageExprTemplate, namespace, name) + return fmtSprintfInternal(PodMemUsageExprTemplate, namespace, name, namespace, name) } func GetNodeCpuUsageExpression(nodeName string) string { From 0eeaee6aa2c8e9f5afa5f408bb11a3f8493f2d2a Mon Sep 17 00:00:00 2001 From: mervynwang Date: Wed, 25 Jun 2025 20:24:48 +0800 Subject: [PATCH 2/3] fix cpu recommend zero --- pkg/prediction/percentile/prediction.go | 2 +- pkg/recommendation/recommender/resource/recommend.go | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/prediction/percentile/prediction.go b/pkg/prediction/percentile/prediction.go index 651dfd242..e705062c2 100644 --- a/pkg/prediction/percentile/prediction.go +++ b/pkg/prediction/percentile/prediction.go @@ -71,7 +71,7 @@ func (p *percentilePrediction) getPredictedValuesFromSignals(queryExpr string, s if cfg.aggregated { signal := signals[keyAll] - if signal != nil { + if signal != nil && signal.totalSamplesCount > 0 { sample := common.Sample{ Value: estimator.GetEstimation(signal.histogram), Timestamp: now, diff --git a/pkg/recommendation/recommender/resource/recommend.go b/pkg/recommendation/recommender/resource/recommend.go index 8f3412a66..0f8b6693d 100644 --- a/pkg/recommendation/recommender/resource/recommend.go +++ b/pkg/recommendation/recommender/resource/recommend.go @@ -131,7 +131,9 @@ func (rr *ResourceRecommender) Recommend(ctx *framework.RecommendationContext) e pr.Target[corev1.ResourceMemory] = memQuantity.String() } - resourceRecommendation.Pod = &pr + if len(pr.Target) != 0 { + resourceRecommendation.Pod = &pr + } } else { klog.V(4).Infof("not use pod metrics for pod %s", ctx.Pods[0].Name) } From d822e364b874b7b99acfb35f94931abaca8faaf3 Mon Sep 17 00:00:00 2001 From: mervynwang Date: Thu, 24 Jul 2025 15:25:14 +0800 Subject: [PATCH 3/3] modify go.yaml && fix unit test --- .github/workflows/go.yml | 20 ++++++++++---------- pkg/utils/expression_prom_deafult_test.go | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index b4d75a72e..a065da079 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -29,20 +29,20 @@ jobs: # Cache go build cache, used to speedup go test - name: Go Build Cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.go-cache-paths.outputs.go-build }} key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }} # Cache go mod cache, used to speedup builds - name: Go Mod Cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.go-cache-paths.outputs.go-mod }} key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }} - name: Go Lint Cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: | ~/.cache/golangci-lint @@ -66,7 +66,7 @@ jobs: sed -i 's/black/whitesmoke/g' coverage.html - name: Upload a Build Artifact - uses: actions/upload-artifact@v3.0.0 + uses: actions/upload-artifact@v4 with: # Artifact name name: coverage.html # optional, default is artifact @@ -92,14 +92,14 @@ jobs: # Cache go build cache, used to speedup go test - name: Go Build Cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.go-cache-paths.outputs.go-build }} key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }} # Cache go mod cache, used to speedup builds - name: Go Mod Cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.go-cache-paths.outputs.go-mod }} key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }} @@ -125,14 +125,14 @@ jobs: # Cache go build cache, used to speedup go test - name: Go Build Cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.go-cache-paths.outputs.go-build }} key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }} # Cache go mod cache, used to speedup builds - name: Go Mod Cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.go-cache-paths.outputs.go-mod }} key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }} @@ -158,14 +158,14 @@ jobs: # Cache go build cache, used to speedup go test - name: Go Build Cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.go-cache-paths.outputs.go-build }} key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }} # Cache go mod cache, used to speedup builds - name: Go Mod Cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.go-cache-paths.outputs.go-mod }} key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }} diff --git a/pkg/utils/expression_prom_deafult_test.go b/pkg/utils/expression_prom_deafult_test.go index a95c813c6..dddeba968 100644 --- a/pkg/utils/expression_prom_deafult_test.go +++ b/pkg/utils/expression_prom_deafult_test.go @@ -144,7 +144,7 @@ func TestGetPodCpuUsageExpression(t *testing.T) { description: "GetPodCpuUsageExpression", namespace: "default", name: "test-pod-001", - expect: "sum(irate(container_cpu_usage_seconds_total{container!=\"POD\",namespace=\"default\",pod=\"test-pod-001\"}[3m]))", + expect: "sum(irate(pod_cpu_seconds_total{mode!~\"idle|iowait\",namespace=\"default\",pod=\"test-pod-001\"}[3m]))", } requests := GetPodCpuUsageExpression(test.namespace, test.name) @@ -163,7 +163,7 @@ func TestGetPodMemUsageExpression(t *testing.T) { description: "GetPodMemUsageExpression", namespace: "default", name: "test-pod-001", - expect: "sum(container_memory_working_set_bytes{container!=\"POD\",namespace=\"default\",pod=\"test-pod-001\"})", + expect: "pod_memory_MemTotal_bytes{namespace=\"default\",pod=\"test-pod-001\"} - pod_memory_MemFree_bytes{namespace=\"default\",pod=\"test-pod-001\"}", } requests := GetPodMemUsageExpression(test.namespace, test.name)