diff --git a/cmd/optimize/configure_test.go b/cmd/optimize/configure_test.go index 0cafd0f6..a650dbd5 100644 --- a/cmd/optimize/configure_test.go +++ b/cmd/optimize/configure_test.go @@ -18,6 +18,7 @@ import ( "io" "net/http" "net/http/httptest" + "os" "slices" "strings" "testing" @@ -33,10 +34,22 @@ var validPaths []string = []string{ "knowledge-store/v1/objects/:optimizer?filter=data.target.k8sDeployment.workloadId+eq+%22VfJUeLlJOUyRrgi8ABDBMQ%22", } +var WORKLOAD_UQL_RESP_FILE string = "testdata/configure_test_workload.json" +var REPORT_UQL_RESP_FILE string = "testdata/configure_test_report.json" + func TestConfigureMultipleMatches(t *testing.T) { + workloadResponse, err := os.ReadFile(WORKLOAD_UQL_RESP_FILE) + if err != nil { + t.Fatalf("failed to load test data from %v: %v", WORKLOAD_UQL_RESP_FILE, err) + return + } + reportResponse, err := os.ReadFile(REPORT_UQL_RESP_FILE) + if err != nil { + t.Fatalf("failed to load test data from %v: %v", REPORT_UQL_RESP_FILE, err) + return + } // HTTP server hit by calls made duringtest testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - t.Log(r.Method) if !slices.Contains(validPaths, r.URL.Path) { t.Errorf("Unexpected path requeested: %s", r.URL.Path) } @@ -69,7 +82,7 @@ func TestConfigureMultipleMatches(t *testing.T) { w.WriteHeader(http.StatusBadRequest) } if respErr != nil { - t.Errorf("error writing response: %v", err) + t.Errorf("error writing response: %v", respErr) } })) @@ -86,544 +99,3 @@ func TestConfigureMultipleMatches(t *testing.T) { t.Fatalf("failed to confiugre multimatch workload: %v", err) } } - -var workloadResponse string = ` - [ - { - "type": "model", - "model": { - "name": "m:main", - "resultType": "LISTING", - "fields": [ - { - "alias": "id", - "type": "string", - "hints": { - "kind": "entity", - "field": "id", - "type": "k8s:deployment" - }, - "properties": { - "functionType": "DIMENSION", - "orderable": true, - "fieldCoordinates": { - "from": "2:6", - "to": "2:7" - }, - "querySnippet": "id" - } - }, - { - "alias": "isActive", - "type": "boolean", - "hints": { - "kind": "entity", - "field": "isActive", - "type": "k8s:deployment" - }, - "properties": { - "functionType": "DIMENSION", - "orderable": true, - "fieldCoordinates": { - "from": "2:10", - "to": "2:17" - }, - "querySnippet": "isActive" - } - } - ] - } - }, - { - "type": "data", - "model": { - "$jsonPath": "$..[?(@.type == 'model')]..[?(@.name == 'm:main')]", - "$model": "m:main" - }, - "metadata": { - "since": "2024-04-12T19:50:15.847747259Z", - "until": "2024-04-19T19:50:15.847747259Z" - }, - "main": true, - "dataset": "d:main", - "data": [ - [ - "k8s:deployment:VfJUeLlJOUyRrgi8ABDBMQ", - true - ], - [ - "k8s:deployment:GY6sVnqLPbCtHwDpX0JARw", - false - ], - [ - "k8s:deployment:Cky9fa+OMeWBRhYR0miVeg", - false - ] - ] - } - ] - ` - -var reportResponse string = ` -[ - { - "type": "model", - "model": { - "name": "m:main", - "resultType": "AGGREGATION", - "fields": [ - { - "alias": "events", - "type": "timeseries", - "hints": { - "kind": "entity", - "field": "events", - "type": "k8s:deployment" - }, - "properties": { - "functionType": "AGGREGATION", - "orderable": false, - "fieldCoordinates": { - "from": "2:6", - "to": "2:43" - }, - "querySnippet": "events(k8sprofiler:report){attributes}" - }, - "form": "reference", - "model": { - "name": "m:events", - "resultType": "LISTING", - "fields": [ - { - "alias": "attributes", - "type": "complex", - "hints": { - "kind": "event", - "field": "attributes", - "type": "k8sprofiler:report" - }, - "properties": { - "functionType": "DIMENSION", - "orderable": false, - "fieldCoordinates": { - "from": "2:33", - "to": "2:42" - }, - "querySnippet": "attributes" - }, - "form": "inline", - "model": { - "name": "m:attributes", - "resultType": "LISTING", - "fields": [ - { - "alias": "name", - "type": "string", - "hints": { - "field": "name" - }, - "properties": { - "functionType": "DIMENSION", - "orderable": false - } - }, - { - "alias": "value", - "type": "any", - "hints": { - "field": "value" - }, - "properties": { - "functionType": "DIMENSION", - "orderable": false - } - } - ] - } - } - ] - } - } - ] - } - }, - { - "type": "data", - "model": { - "$jsonPath": "$..[?(@.type == 'model')]..[?(@.name == 'm:main')]", - "$model": "m:main" - }, - "metadata": { - "since": "2024-04-12T20:14:09.431916763Z", - "until": "2024-04-19T20:14:09.431916763Z" - }, - "main": true, - "dataset": "d:main", - "data": [ - [ - { - "$dataset": "d:events-1", - "$jsonPath": "$..[?(@.type == 'data' && @.dataset == 'd:events-1')]" - } - ] - ] - }, - { - "type": "data", - "model": { - "$jsonPath": "$..[?(@.type == 'model')]..[?(@.name == 'm:events')]", - "$model": "m:events" - }, - "metadata": { - "schema": { - "fields": { - "attributes.appd.event.type": "KEY", - "attributes.appd.isevent": "KEY", - "attributes.k8s.cluster.id": "KEY", - "attributes.k8s.deployment.uid": "KEY", - "attributes.report_contents.cautions.high_utilization.order": "DOUBLE", - "attributes.report_contents.cautions.idle.order": "DOUBLE", - "attributes.report_contents.cautions.low_replica_count.order": "DOUBLE", - "attributes.report_contents.cautions.pod_qos_best_effort.order": "DOUBLE", - "attributes.report_contents.cautions.pod_qos_burstable.order": "DOUBLE", - "attributes.report_contents.cautions.utilization_exceeds_allocation.order": "DOUBLE", - "attributes.report_contents.cautions.utilization_significantly_exceeds_allocation.order": "DOUBLE", - "attributes.report_contents.conclusion.excessive_cost.order": "DOUBLE", - "attributes.report_contents.conclusion.ok.order": "DOUBLE", - "attributes.report_contents.conclusion.reliability_risk.order": "DOUBLE", - "attributes.report_contents.efficiency_rate": "DOUBLE", - "attributes.report_contents.main_container_name": "KEY", - "attributes.report_contents.opportunities.improve_efficiency.order": "DOUBLE", - "attributes.report_contents.opportunities.improve_efficiency_range_multiple.max_multiple": "DOUBLE", - "attributes.report_contents.opportunities.improve_efficiency_range_multiple.min_multiple": "DOUBLE", - "attributes.report_contents.opportunities.improve_efficiency_range_multiple.order": "DOUBLE", - "attributes.report_contents.opportunities.improve_efficiency_range_percent.max_percent": "DOUBLE", - "attributes.report_contents.opportunities.improve_efficiency_range_percent.min_percent": "DOUBLE", - "attributes.report_contents.opportunities.improve_efficiency_range_percent.order": "DOUBLE", - "attributes.report_contents.opportunities.improve_performance.order": "DOUBLE", - "attributes.report_contents.optimizability_rank": "DOUBLE", - "attributes.report_contents.optimizable": "KEY", - "attributes.report_contents.optimization_blockers.apm_metrics_deficient.order": "DOUBLE", - "attributes.report_contents.optimization_blockers.apm_metrics_deficient.overridable": "KEY", - "attributes.report_contents.optimization_blockers.apm_metrics_missing.order": "DOUBLE", - "attributes.report_contents.optimization_blockers.apm_metrics_missing.overridable": "KEY", - "attributes.report_contents.optimization_blockers.cpu_not_specified.order": "DOUBLE", - "attributes.report_contents.optimization_blockers.cpu_resources_change.order": "DOUBLE", - "attributes.report_contents.optimization_blockers.cpu_resources_change.overridable": "KEY", - "attributes.report_contents.optimization_blockers.error_rate_high.order": "DOUBLE", - "attributes.report_contents.optimization_blockers.error_rate_high.overridable": "KEY", - "attributes.report_contents.optimization_blockers.insufficient_fixed_scaling.order": "DOUBLE", - "attributes.report_contents.optimization_blockers.insufficient_fixed_scaling.overridable": "KEY", - "attributes.report_contents.optimization_blockers.insufficient_relative_scaling.order": "DOUBLE", - "attributes.report_contents.optimization_blockers.insufficient_relative_scaling.overridable": "KEY", - "attributes.report_contents.optimization_blockers.k8s_metrics_deficient.order": "DOUBLE", - "attributes.report_contents.optimization_blockers.k8s_metrics_deficient.overridable": "KEY", - "attributes.report_contents.optimization_blockers.mem_resources_change.order": "DOUBLE", - "attributes.report_contents.optimization_blockers.mem_resources_change.overridable": "KEY", - "attributes.report_contents.optimization_blockers.no_orchestration_agent.order": "DOUBLE", - "attributes.report_contents.optimization_blockers.no_orchestration_agent.overridable": "KEY", - "attributes.report_contents.optimization_blockers.no_scaling.order": "DOUBLE", - "attributes.report_contents.optimization_blockers.no_scaling.overridable": "KEY", - "attributes.report_contents.optimization_blockers.no_traffic.order": "DOUBLE", - "attributes.report_contents.optimization_blockers.resources_not_specified.order": "DOUBLE", - "attributes.report_contents.optimization_configuration.guardrails.cpu.max": "DOUBLE", - "attributes.report_contents.optimization_configuration.guardrails.cpu.min": "DOUBLE", - "attributes.report_contents.optimization_configuration.guardrails.cpu.pinned": "KEY", - "attributes.report_contents.optimization_configuration.guardrails.memory.max": "DOUBLE", - "attributes.report_contents.optimization_configuration.guardrails.memory.min": "DOUBLE", - "attributes.report_contents.optimization_configuration.guardrails.memory.pinned": "KEY", - "attributes.report_contents.optimization_configuration.slo.error_percent.target": "DOUBLE", - "attributes.report_contents.optimization_configuration.slo.median_response_time.target": "DOUBLE", - "attributes.report_contents.recommendations.define_resources.order": "DOUBLE", - "attributes.report_contents.recommendations.optimize_efficiency.order": "DOUBLE", - "attributes.report_contents.recommendations.optimize_reliability.order": "DOUBLE", - "attributes.report_contents.reliability_risk": "KEY", - "attributes.report_metadata.confidence_percent": "DOUBLE", - "attributes.report_metadata.ended_at": "KEY", - "attributes.report_metadata.eval_resolution": "DOUBLE", - "attributes.report_metadata.started_at": "KEY", - "attributes.report_support_data.avg_replica_count": "DOUBLE", - "attributes.report_support_data.cpu_limits": "DOUBLE", - "attributes.report_support_data.cpu_requests": "DOUBLE", - "attributes.report_support_data.cpu_seconds_throttled": "DOUBLE", - "attributes.report_support_data.cpu_usage": "DOUBLE", - "attributes.report_support_data.cpu_utilization": "DOUBLE", - "attributes.report_support_data.many_replicas": "KEY", - "attributes.report_support_data.memory_limits": "DOUBLE", - "attributes.report_support_data.memory_requests": "DOUBLE", - "attributes.report_support_data.memory_usage": "DOUBLE", - "attributes.report_support_data.memory_utilization": "DOUBLE", - "attributes.report_support_data.pod_qos_class": "KEY", - "attributes.report_support_data.resource_burst_detected": "KEY", - "attributes.report_support_data.resource_spec_guaranteed": "KEY", - "attributes.report_support_data.resource_spec_limits_present": "KEY", - "attributes.report_support_data.resource_spec_present": "KEY", - "attributes.report_support_data.resource_utilization_detected": "KEY", - "attributes.report_support_data.single_replica": "KEY", - "attributes.resource_metadata.cluster_id": "KEY", - "attributes.resource_metadata.cluster_name": "KEY", - "attributes.resource_metadata.namespace_name": "KEY", - "attributes.resource_metadata.workload_name": "KEY", - "attributes.resource_metadata.workload_type": "KEY", - "attributes.telemetry.sdk.name": "KEY", - "entity.ids": "KEY", - "entity.types": "KEY", - "entityMetadata.id": "KEY", - "entityMetadata.type.name": "KEY", - "entityMetadata.type.namespace.name": "KEY", - "entityMetadata.type.namespace.version": "DOUBLE", - "source.name": "KEY", - "tags.cluster": "KEY", - "tags.namespace": "KEY", - "tags.workload.name": "KEY", - "type": "KEY", - "attributes.report_contents.optimization_blockers.unequal_load_distribution.order": "DOUBLE", - "attributes.report_contents.optimization_blockers.unequal_load_distribution.overridable": "KEY", - "attributes.report_contents.opportunities.improve_efficiency_upto_percent.max_percent": "DOUBLE", - "attributes.report_contents.opportunities.improve_efficiency_upto_percent.order": "DOUBLE", - "attributes.report_contents.optimization_blockers.mem_not_specified.order": "DOUBLE" - } - }, - "statistics": { - "totalDocs": 11434, - "numDocs": 4662, - "numHits": 9, - "numDocsProcessed": 3347, - "numHitsProcessed": 7 - } - }, - "dataset": "d:events-1", - "_links": { - "next": { - "href": "/monitoring/v1/query/continue?cursor=ewogICJ0eXBlIiA6ICJldmVudCIsCiAgImRvY3VtZW50SWQiIDogIkNOSFd4cVB2TVJJNkNqQnJPSE53Y205bWFXeGxjaTFoWW1RNU9HRmxPQzFoTlRoa0xUUTFOekl0WVRnd055MDVZV0kwWm1FNU9HWTBOalFRUGhqOTlvZXhCaGliQVNELy8vLy9Edz09IiwKICAicXVlcnkiIDogIkZFVENIIGV2ZW50cyhrOHNwcm9maWxlcjpyZXBvcnQpe2F0dHJpYnV0ZXN9IExJTUlUUyBldmVudHMuY291bnQoMSkgT1JERVIgZXZlbnRzLmRlc2MoKSBTSU5DRSAyMDI0LTA0LTEyVDIwOjE0OjA5LjQzMTkxNjc2M1ogVU5USUwgMjAyNC0wNC0xOVQyMDoxNDowOS40MzE5MTY3NjNaIEZST00gZW50aXRpZXMoazhzOmRlcGxveW1lbnQ6VmZKVWVMbEpPVXlScmdpOEFCREJNUSkiCn0%3D" - } - }, - "data": [ - [ - [ - [ - "appd.event.type", - "k8sprofiler:report" - ], - [ - "appd.isevent", - "true" - ], - [ - "k8s.cluster.id", - "00000000-0000-0000-0000-000000000000" - ], - [ - "k8s.deployment.uid", - "00000000-0000-0000-0000-000000000000" - ], - [ - "report_contents.cautions.pod_qos_burstable.order", - "0.0" - ], - [ - "report_contents.conclusion.excessive_cost.order", - "0.0" - ], - [ - "report_contents.efficiency_rate", - "17.0" - ], - [ - "report_contents.main_container_name", - "loadgenerator" - ], - [ - "report_contents.opportunities.improve_efficiency_range_multiple.max_multiple", - "2.7" - ], - [ - "report_contents.opportunities.improve_efficiency_range_multiple.min_multiple", - "2.0" - ], - [ - "report_contents.opportunities.improve_efficiency_range_multiple.order", - "0.0" - ], - [ - "report_contents.optimizability_rank", - "-100.0" - ], - [ - "report_contents.optimizable", - "false" - ], - [ - "report_contents.optimization_blockers.insufficient_fixed_scaling.order", - "0.0" - ], - [ - "report_contents.optimization_blockers.insufficient_fixed_scaling.overridable", - "true" - ], - [ - "report_contents.optimization_blockers.insufficient_relative_scaling.order", - "0.0" - ], - [ - "report_contents.optimization_blockers.insufficient_relative_scaling.overridable", - "true" - ], - [ - "report_contents.optimization_configuration.guardrails.cpu.max", - "1.625" - ], - [ - "report_contents.optimization_configuration.guardrails.cpu.min", - "0.375" - ], - [ - "report_contents.optimization_configuration.guardrails.cpu.pinned", - "false" - ], - [ - "report_contents.optimization_configuration.guardrails.memory.max", - "1.5" - ], - [ - "report_contents.optimization_configuration.guardrails.memory.min", - "0.375" - ], - [ - "report_contents.optimization_configuration.guardrails.memory.pinned", - "false" - ], - [ - "report_contents.optimization_configuration.slo.error_percent.target", - "0.0" - ], - [ - "report_contents.optimization_configuration.slo.median_response_time.target", - "0.0" - ], - [ - "report_contents.recommendations.optimize_efficiency.order", - "0.0" - ], - [ - "report_contents.reliability_risk", - "low" - ], - [ - "report_metadata.confidence_percent", - "100.0" - ], - [ - "report_metadata.ended_at", - "2024-04-19T03:40:48Z" - ], - [ - "report_metadata.eval_resolution", - "3600.0" - ], - [ - "report_metadata.started_at", - "2024-04-12T03:40:48Z" - ], - [ - "report_support_data.avg_replica_count", - "1.0297619047619047" - ], - [ - "report_support_data.cpu_limits", - "1.0" - ], - [ - "report_support_data.cpu_requests", - "0.8" - ], - [ - "report_support_data.cpu_seconds_throttled", - "0.0" - ], - [ - "report_support_data.cpu_usage", - "0.08220992678125476" - ], - [ - "report_support_data.cpu_utilization", - "10.0" - ], - [ - "report_support_data.many_replicas", - "false" - ], - [ - "report_support_data.memory_limits", - "1.073741824E9" - ], - [ - "report_support_data.memory_requests", - "8.05306368E8" - ], - [ - "report_support_data.memory_usage", - "2.28728946E8" - ], - [ - "report_support_data.memory_utilization", - "28.000000000000004" - ], - [ - "report_support_data.pod_qos_class", - "burstable" - ], - [ - "report_support_data.resource_burst_detected", - "false" - ], - [ - "report_support_data.resource_spec_guaranteed", - "false" - ], - [ - "report_support_data.resource_spec_limits_present", - "true" - ], - [ - "report_support_data.resource_spec_present", - "true" - ], - [ - "report_support_data.resource_utilization_detected", - "true" - ], - [ - "report_support_data.single_replica", - "false" - ], - [ - "resource_metadata.cluster_id", - "9b4115a8-6ee9-4dcb-b8c6-39126a01367d" - ], - [ - "resource_metadata.cluster_name", - "optimize-c1-qe" - ], - [ - "resource_metadata.namespace_name", - "bofa-24-02" - ], - [ - "resource_metadata.workload_name", - "frontend" - ], - [ - "resource_metadata.workload_type", - "Deployment" - ], - [ - "telemetry.sdk.name", - "k8sprofiler" - ] - ] - ] - ] - } -] -` diff --git a/cmd/optimize/optimize.go b/cmd/optimize/optimize.go index 30bd8890..f5c6b3ef 100644 --- a/cmd/optimize/optimize.go +++ b/cmd/optimize/optimize.go @@ -30,6 +30,7 @@ via the report subcommand.`, func NewSubCmd() *cobra.Command { optimizeCmd.AddCommand(NewCmdConfigure()) + optimizeCmd.AddCommand(NewCmdReport()) return optimizeCmd } diff --git a/cmd/optimize/report.go b/cmd/optimize/report.go index 44ba5b21..98291e4f 100644 --- a/cmd/optimize/report.go +++ b/cmd/optimize/report.go @@ -28,6 +28,12 @@ import ( "github.com/cisco-open/fsoc/output" ) +type reportFlags struct { + commonFlags + workloadId string + eligible bool +} + // TODO clarify blocker structure and pre-format type reportRow struct { WorkloadId string @@ -41,13 +47,7 @@ type templateValues struct { WorkloadFilters string } -var ( - tempVals templateValues - cluster string - namespace string - workloadName string - eligible bool -) +var tempVals templateValues var reportTemplate = template.Must(template.New("").Parse(` SINCE -1w @@ -56,134 +56,135 @@ FROM entities(k8s:deployment{{with .WorkloadId}}:{{.}}{{end}}){{with .WorkloadFi LIMITS events.count(1) `)) -// reportCmd represents the report command -var reportCmd = &cobra.Command{ - Use: "report", - Short: "List workloads and optimization eligibility", - Long: ` -List workloads and optimization eligibility - -If no flags are provided, all deployment workloads will be listed -You can optionally filter workloads to by cluster, namespace and/or name -You may specify also particular workloadId to fetch details for a single workload (recommended with -o detail or -o yaml) -`, - Example: `fsoc optimize report --namespace kube-system`, - Args: cobra.NoArgs, - RunE: listReports, - TraverseChildren: true, - Annotations: map[string]string{ - output.TableFieldsAnnotation: "WorkloadId: .WorkloadId, Name: .WorkloadAttributes[\"k8s.workload.name\"], Eligible: .ProfileAttributes[\"report_contents.optimizable\"], LastProfiled: .ProfileTimestamp", - output.DetailFieldsAnnotation: "WorkloadId: .WorkloadId, Cluster: .WorkloadAttributes[\"k8s.cluster.name\"], Namespace: .WorkloadAttributes[\"k8s.namespace.name\"], Name: .WorkloadAttributes[\"k8s.workload.name\"], Eligible: .ProfileAttributes[\"report_contents.optimizable\"], Blockers: (.ProfileAttributes // {}) | with_entries(select(.key | startswith(\"report_contents.optimization_blockers\"))), LastProfiled: .ProfileTimestamp", - }, -} - -func init() { - optimizeCmd.AddCommand(reportCmd) - reportCmd.Flags().StringVarP(&cluster, "cluster", "c", "", "Filter reports by kubernetes cluster name") - reportCmd.Flags().StringVarP(&namespace, "namespace", "n", "", "Filter reports by kubernetes namespace") - reportCmd.Flags().StringVarP(&workloadName, "workload-name", "w", "", "Filter reports by name of kubernetes workload") +func NewCmdReport() *cobra.Command { + reportFlags := &reportFlags{} + var reportCmd = &cobra.Command{ + Use: "report", + Short: "List workloads and optimization eligibility", + Long: ` + List workloads and optimization eligibility + + If no flags are provided, all deployment workloads will be listed + You can optionally filter workloads to by cluster, namespace and/or name + You may specify also particular workloadId to fetch details for a single workload (recommended with -o detail or -o yaml) + `, + Example: `fsoc optimize report --namespace kube-system`, + Args: cobra.NoArgs, + RunE: listReports(reportFlags), + TraverseChildren: true, + Annotations: map[string]string{ + output.TableFieldsAnnotation: "WorkloadId: .WorkloadId, Name: .WorkloadAttributes[\"k8s.workload.name\"], Eligible: .ProfileAttributes[\"report_contents.optimizable\"], LastProfiled: .ProfileTimestamp", + output.DetailFieldsAnnotation: "WorkloadId: .WorkloadId, Cluster: .WorkloadAttributes[\"k8s.cluster.name\"], Namespace: .WorkloadAttributes[\"k8s.namespace.name\"], Name: .WorkloadAttributes[\"k8s.workload.name\"], Eligible: .ProfileAttributes[\"report_contents.optimizable\"], Blockers: (.ProfileAttributes // {}) | with_entries(select(.key | startswith(\"report_contents.optimization_blockers\"))), LastProfiled: .ProfileTimestamp", + }, + } + reportCmd.Flags().StringVarP(&reportFlags.Cluster, "cluster", "c", "", "Filter reports by kubernetes cluster name") + reportCmd.Flags().StringVarP(&reportFlags.Namespace, "namespace", "n", "", "Filter reports by kubernetes namespace") + reportCmd.Flags().StringVarP(&reportFlags.WorkloadName, "workload-name", "w", "", "Filter reports by name of kubernetes workload") - reportCmd.Flags().StringVarP(&tempVals.WorkloadId, "workload-id", "i", "", "Retrieve a specific report by its workload's ID (best used with -o detail)") + reportCmd.Flags().StringVarP(&reportFlags.workloadId, "workload-id", "i", "", "Retrieve a specific report by its workload's ID (best used with -o detail)") reportCmd.MarkFlagsMutuallyExclusive("workload-id", "cluster") reportCmd.MarkFlagsMutuallyExclusive("workload-id", "namespace") reportCmd.MarkFlagsMutuallyExclusive("workload-id", "workload-name") - reportCmd.Flags().BoolVarP(&eligible, "eligible", "e", false, "Only list reports for eligbile workloads") + reportCmd.Flags().BoolVarP(&reportFlags.eligible, "eligible", "e", false, "Only list reports for eligbile workloads") registerReportCompletion(reportCmd, profilerReportFlagCluster) registerReportCompletion(reportCmd, profilerReportFlagNamespace) registerReportCompletion(reportCmd, profilerReportFlagWorkloadName) - + return reportCmd } -func listReports(cmd *cobra.Command, args []string) error { - filtersList := make([]string, 0, 3) - if cluster != "" { - filtersList = append(filtersList, fmt.Sprintf("attributes(\"k8s.cluster.name\") = %q", cluster)) - } - if namespace != "" { - filtersList = append(filtersList, fmt.Sprintf("attributes(\"k8s.namespace.name\") = %q", namespace)) - } - if workloadName != "" { - filtersList = append(filtersList, fmt.Sprintf("attributes(\"k8s.workload.name\") = %q", workloadName)) - } - tempVals.WorkloadFilters = strings.Join(filtersList, " && ") - tempVals.WorkloadId, _ = strings.CutPrefix(tempVals.WorkloadId, "k8s:deployment:") - - var query string - var buff bytes.Buffer - if err := reportTemplate.Execute(&buff, tempVals); err != nil { - return fmt.Errorf("reportTemplate.Execute: %w", err) - } - query = buff.String() - - resp, err := uql.ClientV1.ExecuteQuery(&uql.Query{Str: query}) - if err != nil { - return fmt.Errorf("uql.ClientV1.ExecuteQuery: %w", err) - } - - if resp.HasErrors() { - log.Error("Execution of report query encountered errors. Returned data may not be complete!") - for _, e := range resp.Errors() { - log.Errorf("%s: %s", e.Title, e.Detail) +func listReports(flags *reportFlags) func(cmd *cobra.Command, args []string) error { + return func(cmd *cobra.Command, args []string) error { + filtersList := make([]string, 0, 3) + if flags.Cluster != "" { + filtersList = append(filtersList, fmt.Sprintf("attributes(\"k8s.cluster.name\") = %q", flags.Cluster)) } - } - - mainDataSet := resp.Main() - if mainDataSet == nil { - output.PrintCmdStatus(cmd, "No results found for given input\n") - return nil - } + if flags.Namespace != "" { + filtersList = append(filtersList, fmt.Sprintf("attributes(\"k8s.namespace.name\") = %q", flags.Namespace)) + } + if flags.WorkloadName != "" { + filtersList = append(filtersList, fmt.Sprintf("attributes(\"k8s.workload.name\") = %q", flags.WorkloadName)) + } + tempVals.WorkloadFilters = strings.Join(filtersList, " && ") + tempVals.WorkloadId, _ = strings.CutPrefix(flags.workloadId, "k8s:deployment:") - reportRows, err := extractReportData(mainDataSet) - if err != nil { - return fmt.Errorf("extractReportData: %w", err) - } + var query string + var buff bytes.Buffer + if err := reportTemplate.Execute(&buff, tempVals); err != nil { + return fmt.Errorf("reportTemplate.Execute: %w", err) + } + query = buff.String() - _, next_ok := mainDataSet.Links["next"] - for page := 2; next_ok; page++ { - resp, err = uql.ClientV1.ContinueQuery(mainDataSet, "next") + resp, err := uql.ClientV1.ExecuteQuery(&uql.Query{Str: query}) if err != nil { - return fmt.Errorf("page %v uql.ClientV1.ContinueQuery: %w", page, err) + return fmt.Errorf("uql.ClientV1.ExecuteQuery: %w", err) } if resp.HasErrors() { - log.Errorf("Continuation of report query (page %v) encountered errors. Returned data may not be complete!", page) + log.Error("Execution of report query encountered errors. Returned data may not be complete!") for _, e := range resp.Errors() { log.Errorf("%s: %s", e.Title, e.Detail) } } - mainDataSet = resp.Main() + mainDataSet := resp.Main() if mainDataSet == nil { - log.Errorf("Continuation of report query (page %v) has nil main data. Returned data may not be complete!", page) - break + output.PrintCmdStatus(cmd, "No results found for given input\n") + return nil } - newRows, err := extractReportData(mainDataSet) + reportRows, err := extractReportData(mainDataSet, flags.eligible) if err != nil { - return fmt.Errorf("page %v extractReportData: %w", page, err) + return fmt.Errorf("extractReportData: %w", err) } - reportRows = append(reportRows, newRows...) - _, next_ok = mainDataSet.Links["next"] - } + _, next_ok := mainDataSet.Links["next"] + for page := 2; next_ok; page++ { + resp, err = uql.ClientV1.ContinueQuery(mainDataSet, "next") + if err != nil { + return fmt.Errorf("page %v uql.ClientV1.ContinueQuery: %w", page, err) + } - if len(reportRows) < 1 { - output.PrintCmdStatus(cmd, "No results found for given input\n") - return nil - } + if resp.HasErrors() { + log.Errorf("Continuation of report query (page %v) encountered errors. Returned data may not be complete!", page) + for _, e := range resp.Errors() { + log.Errorf("%s: %s", e.Title, e.Detail) + } + } + + mainDataSet = resp.Main() + if mainDataSet == nil { + log.Errorf("Continuation of report query (page %v) has nil main data. Returned data may not be complete!", page) + break + } - output.PrintCmdOutput(cmd, struct { - Items []reportRow `json:"items"` - Total int `json:"total"` - }{Items: reportRows, Total: len(reportRows)}) + newRows, err := extractReportData(mainDataSet, flags.eligible) + if err != nil { + return fmt.Errorf("page %v extractReportData: %w", page, err) + } - return nil + reportRows = append(reportRows, newRows...) + _, next_ok = mainDataSet.Links["next"] + } + + if len(reportRows) < 1 { + output.PrintCmdStatus(cmd, "No results found for given input\n") + return nil + } + + output.PrintCmdOutput(cmd, struct { + Items []reportRow `json:"items"` + Total int `json:"total"` + }{Items: reportRows, Total: len(reportRows)}) + + return nil + } } -func extractReportData(dataset *uql.DataSet) ([]reportRow, error) { +func extractReportData(dataset *uql.DataSet, eligible bool) ([]reportRow, error) { resp_data := &dataset.Data + var err error results := make([]reportRow, 0, len(*resp_data)) for index, row := range *resp_data { if len(row) < 3 { @@ -201,17 +202,20 @@ func extractReportData(dataset *uql.DataSet) ([]reportRow, error) { if !ok { return results, fmt.Errorf("workload entity attributes uql.DataSet type assertion failed (main dataset row %v): %+v", index, row) } - var err error - reportRow.WorkloadAttributes, err = sliceToMap(workloadAttributeDataset.Data) - if err != nil { - return results, fmt.Errorf("(main dataset row %v) sliceToMap(workloadAttributeDataset.Data): %w", index, err) + if workloadAttributeDataset == nil { + log.Warnf("(main dataset row %v) got nil data for entity attributes on %v", index, workloadId) + } else { + reportRow.WorkloadAttributes, err = sliceToMap(workloadAttributeDataset.Data) + if err != nil { + return results, fmt.Errorf("(main dataset row %v) sliceToMap(workloadAttributeDataset.Data): %w", index, err) + } } profileAttributesDataSet, ok := row[2].(*uql.DataSet) if !ok { return results, fmt.Errorf("profile event attributes uql.DataSet type assertion failed (main dataset row %v): %+v", index, row) } - if len(profileAttributesDataSet.Data) > 0 { + if profileAttributesDataSet != nil && len(profileAttributesDataSet.Data) > 0 { // uql LIMITS events.count(1) means we're only interested in the first (and only) row of returned events firstRow := profileAttributesDataSet.Data[0] if len(firstRow) < 2 { diff --git a/cmd/optimize/report_test.go b/cmd/optimize/report_test.go new file mode 100644 index 00000000..4c41ed89 --- /dev/null +++ b/cmd/optimize/report_test.go @@ -0,0 +1,57 @@ +// Copyright 2023 Cisco Systems, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package optimize + +import ( + "net/http" + "net/http/httptest" + "os" + "testing" + + "github.com/spf13/cobra" + + "github.com/cisco-open/fsoc/test" +) + +func TestReportsNoEventsData(t *testing.T) { + reportResponse, err := os.ReadFile("testdata/report_test.json") + if err != nil { + t.Fatalf("failed to load test data: %v", err) + return + } + + // HTTP server hit by calls made duringtest + testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/monitoring/v1/query/execute" { + t.Errorf("Unexpected path requeested: %s", r.URL.Path) + } + w.WriteHeader(http.StatusOK) + _, err := w.Write(reportResponse) + if err != nil { + t.Errorf("error writing response: %v", err) + } + })) + + defer test.SetActiveConfigProfileServer(testServer.URL)() + + testFlags := &reportFlags{} + testFlags.Cluster = "optimize-c1-qe" + testFlags.Namespace = "bofa-24-02" + testFlags.WorkloadName = "frontend" + listFunc := listReports(testFlags) + if err := listFunc(&cobra.Command{}, nil); err != nil { + t.Fatalf("failed to confiugre multimatch workload: %v", err) + } +} diff --git a/cmd/optimize/testdata/configure_test_report.json b/cmd/optimize/testdata/configure_test_report.json new file mode 100644 index 00000000..3437a58d --- /dev/null +++ b/cmd/optimize/testdata/configure_test_report.json @@ -0,0 +1,461 @@ +[ + { + "type": "model", + "model": { + "name": "m:main", + "resultType": "AGGREGATION", + "fields": [ + { + "alias": "events", + "type": "timeseries", + "hints": { + "kind": "entity", + "field": "events", + "type": "k8s:deployment" + }, + "properties": { + "functionType": "AGGREGATION", + "orderable": false, + "fieldCoordinates": { + "from": "2:6", + "to": "2:43" + }, + "querySnippet": "events(k8sprofiler:report){attributes}" + }, + "form": "reference", + "model": { + "name": "m:events", + "resultType": "LISTING", + "fields": [ + { + "alias": "attributes", + "type": "complex", + "hints": { + "kind": "event", + "field": "attributes", + "type": "k8sprofiler:report" + }, + "properties": { + "functionType": "DIMENSION", + "orderable": false, + "fieldCoordinates": { + "from": "2:33", + "to": "2:42" + }, + "querySnippet": "attributes" + }, + "form": "inline", + "model": { + "name": "m:attributes", + "resultType": "LISTING", + "fields": [ + { + "alias": "name", + "type": "string", + "hints": { + "field": "name" + }, + "properties": { + "functionType": "DIMENSION", + "orderable": false + } + }, + { + "alias": "value", + "type": "any", + "hints": { + "field": "value" + }, + "properties": { + "functionType": "DIMENSION", + "orderable": false + } + } + ] + } + } + ] + } + } + ] + } + }, + { + "type": "data", + "model": { + "$jsonPath": "$..[?(@.type == 'model')]..[?(@.name == 'm:main')]", + "$model": "m:main" + }, + "metadata": { + "since": "2024-04-12T20:14:09.431916763Z", + "until": "2024-04-19T20:14:09.431916763Z" + }, + "main": true, + "dataset": "d:main", + "data": [ + [ + { + "$dataset": "d:events-1", + "$jsonPath": "$..[?(@.type == 'data' && @.dataset == 'd:events-1')]" + } + ] + ] + }, + { + "type": "data", + "model": { + "$jsonPath": "$..[?(@.type == 'model')]..[?(@.name == 'm:events')]", + "$model": "m:events" + }, + "metadata": { + "schema": { + "fields": { + "attributes.appd.event.type": "KEY", + "attributes.appd.isevent": "KEY", + "attributes.k8s.cluster.id": "KEY", + "attributes.k8s.deployment.uid": "KEY", + "attributes.report_contents.cautions.high_utilization.order": "DOUBLE", + "attributes.report_contents.cautions.idle.order": "DOUBLE", + "attributes.report_contents.cautions.low_replica_count.order": "DOUBLE", + "attributes.report_contents.cautions.pod_qos_best_effort.order": "DOUBLE", + "attributes.report_contents.cautions.pod_qos_burstable.order": "DOUBLE", + "attributes.report_contents.cautions.utilization_exceeds_allocation.order": "DOUBLE", + "attributes.report_contents.cautions.utilization_significantly_exceeds_allocation.order": "DOUBLE", + "attributes.report_contents.conclusion.excessive_cost.order": "DOUBLE", + "attributes.report_contents.conclusion.ok.order": "DOUBLE", + "attributes.report_contents.conclusion.reliability_risk.order": "DOUBLE", + "attributes.report_contents.efficiency_rate": "DOUBLE", + "attributes.report_contents.main_container_name": "KEY", + "attributes.report_contents.opportunities.improve_efficiency.order": "DOUBLE", + "attributes.report_contents.opportunities.improve_efficiency_range_multiple.max_multiple": "DOUBLE", + "attributes.report_contents.opportunities.improve_efficiency_range_multiple.min_multiple": "DOUBLE", + "attributes.report_contents.opportunities.improve_efficiency_range_multiple.order": "DOUBLE", + "attributes.report_contents.opportunities.improve_efficiency_range_percent.max_percent": "DOUBLE", + "attributes.report_contents.opportunities.improve_efficiency_range_percent.min_percent": "DOUBLE", + "attributes.report_contents.opportunities.improve_efficiency_range_percent.order": "DOUBLE", + "attributes.report_contents.opportunities.improve_performance.order": "DOUBLE", + "attributes.report_contents.optimizability_rank": "DOUBLE", + "attributes.report_contents.optimizable": "KEY", + "attributes.report_contents.optimization_blockers.apm_metrics_deficient.order": "DOUBLE", + "attributes.report_contents.optimization_blockers.apm_metrics_deficient.overridable": "KEY", + "attributes.report_contents.optimization_blockers.apm_metrics_missing.order": "DOUBLE", + "attributes.report_contents.optimization_blockers.apm_metrics_missing.overridable": "KEY", + "attributes.report_contents.optimization_blockers.cpu_not_specified.order": "DOUBLE", + "attributes.report_contents.optimization_blockers.cpu_resources_change.order": "DOUBLE", + "attributes.report_contents.optimization_blockers.cpu_resources_change.overridable": "KEY", + "attributes.report_contents.optimization_blockers.error_rate_high.order": "DOUBLE", + "attributes.report_contents.optimization_blockers.error_rate_high.overridable": "KEY", + "attributes.report_contents.optimization_blockers.insufficient_fixed_scaling.order": "DOUBLE", + "attributes.report_contents.optimization_blockers.insufficient_fixed_scaling.overridable": "KEY", + "attributes.report_contents.optimization_blockers.insufficient_relative_scaling.order": "DOUBLE", + "attributes.report_contents.optimization_blockers.insufficient_relative_scaling.overridable": "KEY", + "attributes.report_contents.optimization_blockers.k8s_metrics_deficient.order": "DOUBLE", + "attributes.report_contents.optimization_blockers.k8s_metrics_deficient.overridable": "KEY", + "attributes.report_contents.optimization_blockers.mem_resources_change.order": "DOUBLE", + "attributes.report_contents.optimization_blockers.mem_resources_change.overridable": "KEY", + "attributes.report_contents.optimization_blockers.no_orchestration_agent.order": "DOUBLE", + "attributes.report_contents.optimization_blockers.no_orchestration_agent.overridable": "KEY", + "attributes.report_contents.optimization_blockers.no_scaling.order": "DOUBLE", + "attributes.report_contents.optimization_blockers.no_scaling.overridable": "KEY", + "attributes.report_contents.optimization_blockers.no_traffic.order": "DOUBLE", + "attributes.report_contents.optimization_blockers.resources_not_specified.order": "DOUBLE", + "attributes.report_contents.optimization_configuration.guardrails.cpu.max": "DOUBLE", + "attributes.report_contents.optimization_configuration.guardrails.cpu.min": "DOUBLE", + "attributes.report_contents.optimization_configuration.guardrails.cpu.pinned": "KEY", + "attributes.report_contents.optimization_configuration.guardrails.memory.max": "DOUBLE", + "attributes.report_contents.optimization_configuration.guardrails.memory.min": "DOUBLE", + "attributes.report_contents.optimization_configuration.guardrails.memory.pinned": "KEY", + "attributes.report_contents.optimization_configuration.slo.error_percent.target": "DOUBLE", + "attributes.report_contents.optimization_configuration.slo.median_response_time.target": "DOUBLE", + "attributes.report_contents.recommendations.define_resources.order": "DOUBLE", + "attributes.report_contents.recommendations.optimize_efficiency.order": "DOUBLE", + "attributes.report_contents.recommendations.optimize_reliability.order": "DOUBLE", + "attributes.report_contents.reliability_risk": "KEY", + "attributes.report_metadata.confidence_percent": "DOUBLE", + "attributes.report_metadata.ended_at": "KEY", + "attributes.report_metadata.eval_resolution": "DOUBLE", + "attributes.report_metadata.started_at": "KEY", + "attributes.report_support_data.avg_replica_count": "DOUBLE", + "attributes.report_support_data.cpu_limits": "DOUBLE", + "attributes.report_support_data.cpu_requests": "DOUBLE", + "attributes.report_support_data.cpu_seconds_throttled": "DOUBLE", + "attributes.report_support_data.cpu_usage": "DOUBLE", + "attributes.report_support_data.cpu_utilization": "DOUBLE", + "attributes.report_support_data.many_replicas": "KEY", + "attributes.report_support_data.memory_limits": "DOUBLE", + "attributes.report_support_data.memory_requests": "DOUBLE", + "attributes.report_support_data.memory_usage": "DOUBLE", + "attributes.report_support_data.memory_utilization": "DOUBLE", + "attributes.report_support_data.pod_qos_class": "KEY", + "attributes.report_support_data.resource_burst_detected": "KEY", + "attributes.report_support_data.resource_spec_guaranteed": "KEY", + "attributes.report_support_data.resource_spec_limits_present": "KEY", + "attributes.report_support_data.resource_spec_present": "KEY", + "attributes.report_support_data.resource_utilization_detected": "KEY", + "attributes.report_support_data.single_replica": "KEY", + "attributes.resource_metadata.cluster_id": "KEY", + "attributes.resource_metadata.cluster_name": "KEY", + "attributes.resource_metadata.namespace_name": "KEY", + "attributes.resource_metadata.workload_name": "KEY", + "attributes.resource_metadata.workload_type": "KEY", + "attributes.telemetry.sdk.name": "KEY", + "entity.ids": "KEY", + "entity.types": "KEY", + "entityMetadata.id": "KEY", + "entityMetadata.type.name": "KEY", + "entityMetadata.type.namespace.name": "KEY", + "entityMetadata.type.namespace.version": "DOUBLE", + "source.name": "KEY", + "tags.cluster": "KEY", + "tags.namespace": "KEY", + "tags.workload.name": "KEY", + "type": "KEY", + "attributes.report_contents.optimization_blockers.unequal_load_distribution.order": "DOUBLE", + "attributes.report_contents.optimization_blockers.unequal_load_distribution.overridable": "KEY", + "attributes.report_contents.opportunities.improve_efficiency_upto_percent.max_percent": "DOUBLE", + "attributes.report_contents.opportunities.improve_efficiency_upto_percent.order": "DOUBLE", + "attributes.report_contents.optimization_blockers.mem_not_specified.order": "DOUBLE" + } + }, + "statistics": { + "totalDocs": 11434, + "numDocs": 4662, + "numHits": 9, + "numDocsProcessed": 3347, + "numHitsProcessed": 7 + } + }, + "dataset": "d:events-1", + "_links": { + "next": { + "href": "/monitoring/v1/query/continue?cursor=ewogICJ0eXBlIiA6ICJldmVudCIsCiAgImRvY3VtZW50SWQiIDogIkNOSFd4cVB2TVJJNkNqQnJPSE53Y205bWFXeGxjaTFoWW1RNU9HRmxPQzFoTlRoa0xUUTFOekl0WVRnd055MDVZV0kwWm1FNU9HWTBOalFRUGhqOTlvZXhCaGliQVNELy8vLy9Edz09IiwKICAicXVlcnkiIDogIkZFVENIIGV2ZW50cyhrOHNwcm9maWxlcjpyZXBvcnQpe2F0dHJpYnV0ZXN9IExJTUlUUyBldmVudHMuY291bnQoMSkgT1JERVIgZXZlbnRzLmRlc2MoKSBTSU5DRSAyMDI0LTA0LTEyVDIwOjE0OjA5LjQzMTkxNjc2M1ogVU5USUwgMjAyNC0wNC0xOVQyMDoxNDowOS40MzE5MTY3NjNaIEZST00gZW50aXRpZXMoazhzOmRlcGxveW1lbnQ6VmZKVWVMbEpPVXlScmdpOEFCREJNUSkiCn0%3D" + } + }, + "data": [ + [ + [ + [ + "appd.event.type", + "k8sprofiler:report" + ], + [ + "appd.isevent", + "true" + ], + [ + "k8s.cluster.id", + "00000000-0000-0000-0000-000000000000" + ], + [ + "k8s.deployment.uid", + "00000000-0000-0000-0000-000000000000" + ], + [ + "report_contents.cautions.pod_qos_burstable.order", + "0.0" + ], + [ + "report_contents.conclusion.excessive_cost.order", + "0.0" + ], + [ + "report_contents.efficiency_rate", + "17.0" + ], + [ + "report_contents.main_container_name", + "loadgenerator" + ], + [ + "report_contents.opportunities.improve_efficiency_range_multiple.max_multiple", + "2.7" + ], + [ + "report_contents.opportunities.improve_efficiency_range_multiple.min_multiple", + "2.0" + ], + [ + "report_contents.opportunities.improve_efficiency_range_multiple.order", + "0.0" + ], + [ + "report_contents.optimizability_rank", + "-100.0" + ], + [ + "report_contents.optimizable", + "false" + ], + [ + "report_contents.optimization_blockers.insufficient_fixed_scaling.order", + "0.0" + ], + [ + "report_contents.optimization_blockers.insufficient_fixed_scaling.overridable", + "true" + ], + [ + "report_contents.optimization_blockers.insufficient_relative_scaling.order", + "0.0" + ], + [ + "report_contents.optimization_blockers.insufficient_relative_scaling.overridable", + "true" + ], + [ + "report_contents.optimization_configuration.guardrails.cpu.max", + "1.625" + ], + [ + "report_contents.optimization_configuration.guardrails.cpu.min", + "0.375" + ], + [ + "report_contents.optimization_configuration.guardrails.cpu.pinned", + "false" + ], + [ + "report_contents.optimization_configuration.guardrails.memory.max", + "1.5" + ], + [ + "report_contents.optimization_configuration.guardrails.memory.min", + "0.375" + ], + [ + "report_contents.optimization_configuration.guardrails.memory.pinned", + "false" + ], + [ + "report_contents.optimization_configuration.slo.error_percent.target", + "0.0" + ], + [ + "report_contents.optimization_configuration.slo.median_response_time.target", + "0.0" + ], + [ + "report_contents.recommendations.optimize_efficiency.order", + "0.0" + ], + [ + "report_contents.reliability_risk", + "low" + ], + [ + "report_metadata.confidence_percent", + "100.0" + ], + [ + "report_metadata.ended_at", + "2024-04-19T03:40:48Z" + ], + [ + "report_metadata.eval_resolution", + "3600.0" + ], + [ + "report_metadata.started_at", + "2024-04-12T03:40:48Z" + ], + [ + "report_support_data.avg_replica_count", + "1.0297619047619047" + ], + [ + "report_support_data.cpu_limits", + "1.0" + ], + [ + "report_support_data.cpu_requests", + "0.8" + ], + [ + "report_support_data.cpu_seconds_throttled", + "0.0" + ], + [ + "report_support_data.cpu_usage", + "0.08220992678125476" + ], + [ + "report_support_data.cpu_utilization", + "10.0" + ], + [ + "report_support_data.many_replicas", + "false" + ], + [ + "report_support_data.memory_limits", + "1.073741824E9" + ], + [ + "report_support_data.memory_requests", + "8.05306368E8" + ], + [ + "report_support_data.memory_usage", + "2.28728946E8" + ], + [ + "report_support_data.memory_utilization", + "28.000000000000004" + ], + [ + "report_support_data.pod_qos_class", + "burstable" + ], + [ + "report_support_data.resource_burst_detected", + "false" + ], + [ + "report_support_data.resource_spec_guaranteed", + "false" + ], + [ + "report_support_data.resource_spec_limits_present", + "true" + ], + [ + "report_support_data.resource_spec_present", + "true" + ], + [ + "report_support_data.resource_utilization_detected", + "true" + ], + [ + "report_support_data.single_replica", + "false" + ], + [ + "resource_metadata.cluster_id", + "9b4115a8-6ee9-4dcb-b8c6-39126a01367d" + ], + [ + "resource_metadata.cluster_name", + "optimize-c1-qe" + ], + [ + "resource_metadata.namespace_name", + "bofa-24-02" + ], + [ + "resource_metadata.workload_name", + "frontend" + ], + [ + "resource_metadata.workload_type", + "Deployment" + ], + [ + "telemetry.sdk.name", + "k8sprofiler" + ] + ] + ] + ] + } +] \ No newline at end of file diff --git a/cmd/optimize/testdata/configure_test_workload.json b/cmd/optimize/testdata/configure_test_workload.json new file mode 100644 index 00000000..5f00d5e4 --- /dev/null +++ b/cmd/optimize/testdata/configure_test_workload.json @@ -0,0 +1,74 @@ +[ + { + "type": "model", + "model": { + "name": "m:main", + "resultType": "LISTING", + "fields": [ + { + "alias": "id", + "type": "string", + "hints": { + "kind": "entity", + "field": "id", + "type": "k8s:deployment" + }, + "properties": { + "functionType": "DIMENSION", + "orderable": true, + "fieldCoordinates": { + "from": "2:6", + "to": "2:7" + }, + "querySnippet": "id" + } + }, + { + "alias": "isActive", + "type": "boolean", + "hints": { + "kind": "entity", + "field": "isActive", + "type": "k8s:deployment" + }, + "properties": { + "functionType": "DIMENSION", + "orderable": true, + "fieldCoordinates": { + "from": "2:10", + "to": "2:17" + }, + "querySnippet": "isActive" + } + } + ] + } + }, + { + "type": "data", + "model": { + "$jsonPath": "$..[?(@.type == 'model')]..[?(@.name == 'm:main')]", + "$model": "m:main" + }, + "metadata": { + "since": "2024-04-12T19:50:15.847747259Z", + "until": "2024-04-19T19:50:15.847747259Z" + }, + "main": true, + "dataset": "d:main", + "data": [ + [ + "k8s:deployment:VfJUeLlJOUyRrgi8ABDBMQ", + true + ], + [ + "k8s:deployment:GY6sVnqLPbCtHwDpX0JARw", + false + ], + [ + "k8s:deployment:Cky9fa+OMeWBRhYR0miVeg", + false + ] + ] + } +] \ No newline at end of file diff --git a/cmd/optimize/testdata/report_test.json b/cmd/optimize/testdata/report_test.json new file mode 100644 index 00000000..673a0038 --- /dev/null +++ b/cmd/optimize/testdata/report_test.json @@ -0,0 +1,2779 @@ +[ + { + "type": "model", + "model": { + "name": "m:main", + "resultType": "AGGREGATION", + "fields": [ + { + "alias": "id", + "type": "string", + "hints": { + "kind": "entity", + "field": "id", + "type": "k8s:deployment" + }, + "properties": { + "functionType": "DIMENSION", + "orderable": true, + "fieldCoordinates": { + "from": "2:6", + "to": "2:7" + }, + "querySnippet": "id" + } + }, + { + "alias": "attributes", + "type": "complex", + "hints": { + "kind": "entity", + "field": "attributes", + "type": "k8s:deployment" + }, + "properties": { + "functionType": "DIMENSION", + "orderable": false, + "fieldCoordinates": { + "from": "2:10", + "to": "2:19" + }, + "querySnippet": "attributes" + }, + "form": "reference", + "model": { + "name": "m:attributes", + "resultType": "LISTING", + "fields": [ + { + "alias": "name", + "type": "string", + "hints": { + "field": "name" + }, + "properties": { + "functionType": "DIMENSION", + "orderable": false + } + }, + { + "alias": "value", + "type": "any", + "hints": { + "field": "value" + }, + "properties": { + "functionType": "DIMENSION", + "orderable": false + } + } + ] + } + }, + { + "alias": "events", + "type": "timeseries", + "hints": { + "kind": "entity", + "field": "events", + "type": "k8s:deployment" + }, + "properties": { + "functionType": "AGGREGATION", + "orderable": false, + "fieldCoordinates": { + "from": "2:22", + "to": "2:70" + }, + "querySnippet": "events(k8sprofiler:report){attributes, timestamp}" + }, + "form": "reference", + "model": { + "name": "m:events", + "resultType": "LISTING", + "fields": [ + { + "alias": "attributes", + "type": "complex", + "hints": { + "kind": "event", + "field": "attributes", + "type": "k8sprofiler:report" + }, + "properties": { + "functionType": "DIMENSION", + "orderable": false, + "fieldCoordinates": { + "from": "2:49", + "to": "2:58" + }, + "querySnippet": "attributes" + }, + "form": "inline", + "model": { + "name": "m:attributes_2", + "resultType": "LISTING", + "fields": [ + { + "alias": "name", + "type": "string", + "hints": { + "field": "name" + }, + "properties": { + "functionType": "DIMENSION", + "orderable": false + } + }, + { + "alias": "value", + "type": "any", + "hints": { + "field": "value" + }, + "properties": { + "functionType": "DIMENSION", + "orderable": false + } + } + ] + } + }, + { + "alias": "timestamp", + "type": "timestamp", + "hints": { + "kind": "event", + "field": "timestamp", + "type": "k8sprofiler:report" + }, + "properties": { + "functionType": "DIMENSION", + "orderable": true, + "fieldCoordinates": { + "from": "2:61", + "to": "2:69" + }, + "querySnippet": "timestamp", + "ordering": { + "direction": "DESC", + "orderIndex": 0 + } + } + } + ] + } + } + ] + } + }, + { + "type": "data", + "model": { + "$jsonPath": "$..[?(@.type == 'model')]..[?(@.name == 'm:attributes')]", + "$model": "m:attributes" + }, + "dataset": "d:attributes-1", + "data": [ + [ + "healthrule:71a40f41-1684-4b51-8a6f-33fcc7439c68", + "3" + ], + [ + "health.status", + 3 + ], + [ + "troubleshooting:model_training_status", + "READY" + ], + [ + "k8s.cluster.name", + "optimize-c1-qe" + ], + [ + "status", + 3 + ], + [ + "k8s.deployment.progressing", + "True" + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.created_at", + "2024-04-22T00:45:25Z" + ], + [ + "k8sprofiler:optimize.optimization.blockers_count", + 2 + ], + [ + "optimize.instant_recommendation.impact.cost_savings.currency", + "USD" + ], + [ + "model_training_status", + "READY" + ], + [ + "k8s.workload.kind", + "Deployment" + ], + [ + "k8s.workload.resources.limits.memory", + 1.073741824E9 + ], + [ + "optimize:optimize.instant_recommendation.created_at", + "2024-04-22T00:45:31Z" + ], + [ + "alerting:health.status", + 3 + ], + [ + "optimize.k8sprofiler.report.efficiency_rate", + 20.0 + ], + [ + "k8s.workload.liveness_probe", + "{}\n" + ], + [ + "optimize.k8sprofiler.report.created_at", + "2024-04-22T00:45:25Z" + ], + [ + "k8sprofiler:optimize.optimization.optimizable", + false + ], + [ + "optimize.instant_recommendation.impact.cost_savings.value", + 12.32414879078605 + ], + [ + "optimize:optimize.instant_recommendation.valid", + true + ], + [ + "healthrule:63fc2edbe875f636297d7b82", + "1" + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "annotation_deployment.kubernetes.io/revision", + "1" + ], + [ + "optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "k8s.deployment.paused", + false + ], + [ + "k8s.workload.startup_probe", + "{}\n" + ], + [ + "optimize.optimization.blockers_count", + 2 + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.efficiency_rate", + 20.0 + ], + [ + "k8s.object.uid", + "6c718079-245b-40be-b03a-26bc71309358" + ], + [ + "optimize.optimization.optimizable", + false + ], + [ + "k8s.namespace.name", + "bofa-24-02" + ], + [ + "healthrule:ea7bbdfd-706b-4527-b6ca-2aabb48d270b", + "1" + ], + [ + "k8s.deployment.available", + "True" + ], + [ + "k8s.workload.readiness_probe", + "{}\n" + ], + [ + "k8s.workload.name", + "loadgenerator" + ], + [ + "adConfig:09484e94-96b7-4991-be5c-305911e652f2", + "09484e94-96b7-4991-be5c-305911e652f2" + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_ratio", + 0.37289321708170287 + ], + [ + "k8s.workload.resources.requests.memory", + 8.05306368E8 + ], + [ + "troubleshooting:anomaly.status", + 1 + ], + [ + "k8s.cluster.id", + "9b4115a8-6ee9-4dcb-b8c6-39126a01367d" + ], + [ + "optimize.optimization.cautions_count", + 2 + ], + [ + "k8s.workload.resources.requests.cpu", + 0.8 + ], + [ + "health:status", + 3 + ], + [ + "k8sprofiler:optimize.optimization.cautions_count", + 2 + ], + [ + "k8s.object.created_at", + 1705453985000 + ], + [ + "anomaly.status", + 1 + ], + [ + "optimize.instant_recommendation.created_at", + "2024-04-22T00:45:31Z" + ], + [ + "healthrule:63fc2edce875f636297d7b8e", + "0" + ], + [ + "optimize.instant_recommendation.valid", + true + ], + [ + "optimize.instant_recommendation.impact.cost_ratio", + 0.37289321708170287 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.value", + 12.32414879078605 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.currency", + "USD" + ], + [ + "healthrule:a3ffccd8-afc9-4b47-acc0-a3ac9378f613", + "3" + ], + [ + "k8s.workload.resources.limits.cpu", + 1.0 + ] + ] + }, + { + "type": "data", + "model": { + "$jsonPath": "$..[?(@.type == 'model')]..[?(@.name == 'm:attributes')]", + "$model": "m:attributes" + }, + "dataset": "d:attributes-3", + "data": [ + [ + "healthrule:71a40f41-1684-4b51-8a6f-33fcc7439c68", + "3" + ], + [ + "health.status", + 1 + ], + [ + "troubleshooting:model_training_status", + "READY" + ], + [ + "k8s.cluster.name", + "optimize-c1-qe" + ], + [ + "status", + 3 + ], + [ + "k8s.deployment.progressing", + "True" + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.created_at", + "2024-04-20T01:08:25Z" + ], + [ + "k8sprofiler:optimize.optimization.blockers_count", + 4 + ], + [ + "optimize.instant_recommendation.impact.cost_savings.currency", + "USD" + ], + [ + "model_training_status", + "READY" + ], + [ + "k8s.workload.kind", + "Deployment" + ], + [ + "k8s.workload.resources.limits.memory", + 1.073741824E9 + ], + [ + "optimize:optimize.instant_recommendation.created_at", + "2024-04-22T00:46:09Z" + ], + [ + "alerting:health.status", + 1 + ], + [ + "optimize.k8sprofiler.report.efficiency_rate", + 18.0 + ], + [ + "k8s.workload.liveness_probe", + "frontend: |\n probehandler:\n exec: null\n httpget:\n path: /ready\n port:\n type: 0\n intval: 8080\n strval: \"\"\n host: \"\"\n scheme: HTTP\n httpheaders: []\n tcpsocket: null\n grpc: null\n initialdelayseconds: 60\n timeoutseconds: 30\n periodseconds: 15\n successthreshold: 1\n failurethreshold: 3\n terminationgraceperiodseconds: null\n" + ], + [ + "optimize.k8sprofiler.report.created_at", + "2024-04-20T01:08:25Z" + ], + [ + "k8sprofiler:optimize.optimization.optimizable", + false + ], + [ + "optimize.instant_recommendation.impact.cost_savings.value", + 12.966294991939012 + ], + [ + "optimize:optimize.instant_recommendation.valid", + true + ], + [ + "healthrule:63fc2edbe875f636297d7b82", + "1" + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "annotation_deployment.kubernetes.io/revision", + "1" + ], + [ + "optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "k8s.deployment.paused", + false + ], + [ + "k8s.workload.startup_probe", + "{}\n" + ], + [ + "optimize.optimization.blockers_count", + 4 + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.efficiency_rate", + 18.0 + ], + [ + "k8s.object.uid", + "f9be9cf3-acb7-4b8c-8cfb-b3c4bef14ce9" + ], + [ + "optimize.optimization.optimizable", + false + ], + [ + "k8s.namespace.name", + "bofa-24-02" + ], + [ + "healthrule:ea7bbdfd-706b-4527-b6ca-2aabb48d270b", + "1" + ], + [ + "k8s.deployment.available", + "True" + ], + [ + "k8s.workload.readiness_probe", + "frontend: |\n probehandler:\n exec: null\n httpget:\n path: /ready\n port:\n type: 0\n intval: 8080\n strval: \"\"\n host: \"\"\n scheme: HTTP\n httpheaders: []\n tcpsocket: null\n grpc: null\n initialdelayseconds: 10\n timeoutseconds: 10\n periodseconds: 5\n successthreshold: 1\n failurethreshold: 3\n terminationgraceperiodseconds: null\n" + ], + [ + "k8s.workload.name", + "frontend" + ], + [ + "adConfig:09484e94-96b7-4991-be5c-305911e652f2", + "09484e94-96b7-4991-be5c-305911e652f2" + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_ratio", + 0.5789738070238257 + ], + [ + "k8s.workload.resources.requests.memory", + 1.073741824E9 + ], + [ + "troubleshooting:anomaly.status", + 1 + ], + [ + "k8s.cluster.id", + "9b4115a8-6ee9-4dcb-b8c6-39126a01367d" + ], + [ + "optimize.optimization.cautions_count", + 0 + ], + [ + "k8s.workload.resources.requests.cpu", + 1.0 + ], + [ + "health:status", + 3 + ], + [ + "k8sprofiler:optimize.optimization.cautions_count", + 0 + ], + [ + "k8s.object.created_at", + 1705453982000 + ], + [ + "anomaly.status", + 1 + ], + [ + "optimize.instant_recommendation.created_at", + "2024-04-22T00:46:09Z" + ], + [ + "healthrule:63fc2edce875f636297d7b8e", + "0" + ], + [ + "optimize.instant_recommendation.valid", + true + ], + [ + "optimize.instant_recommendation.impact.cost_ratio", + 0.5789738070238257 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.value", + 12.966294991939012 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.currency", + "USD" + ], + [ + "healthrule:a3ffccd8-afc9-4b47-acc0-a3ac9378f613", + "1" + ], + [ + "k8s.workload.resources.limits.cpu", + 1.0 + ] + ] + }, + { + "type": "data", + "model": { + "$jsonPath": "$..[?(@.type == 'model')]..[?(@.name == 'm:attributes')]", + "$model": "m:attributes" + }, + "dataset": "d:attributes-5", + "data": [ + [ + "healthrule:71a40f41-1684-4b51-8a6f-33fcc7439c68", + "3" + ], + [ + "health.status", + 3 + ], + [ + "troubleshooting:model_training_status", + "READY" + ], + [ + "k8s.cluster.name", + "optimize-c1-qe" + ], + [ + "status", + 0 + ], + [ + "k8s.deployment.progressing", + "True" + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.created_at", + "2024-04-22T00:46:21Z" + ], + [ + "k8sprofiler:optimize.optimization.blockers_count", + 2 + ], + [ + "optimize.instant_recommendation.impact.cost_savings.currency", + "USD" + ], + [ + "model_training_status", + "READY" + ], + [ + "k8s.workload.kind", + "Deployment" + ], + [ + "k8s.workload.resources.limits.memory", + 1.610612736E9 + ], + [ + "optimize:optimize.instant_recommendation.created_at", + "2024-04-22T00:46:32Z" + ], + [ + "alerting:health.status", + 3 + ], + [ + "optimize.k8sprofiler.report.efficiency_rate", + 11.0 + ], + [ + "k8s.workload.liveness_probe", + "{}\n" + ], + [ + "optimize.k8sprofiler.report.created_at", + "2024-04-22T00:46:21Z" + ], + [ + "k8sprofiler:optimize.optimization.optimizable", + false + ], + [ + "optimize.instant_recommendation.impact.cost_savings.value", + 16.611515326288696 + ], + [ + "optimize:optimize.instant_recommendation.valid", + true + ], + [ + "healthrule:63fc2edbe875f636297d7b82", + "1" + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "annotation_deployment.kubernetes.io/revision", + "1" + ], + [ + "optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "k8s.deployment.paused", + false + ], + [ + "k8s.workload.startup_probe", + "{}\n" + ], + [ + "optimize.optimization.blockers_count", + 2 + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.efficiency_rate", + 11.0 + ], + [ + "k8s.object.uid", + "60de5aa5-8f53-4d34-9d1b-f2a3045ef1ac" + ], + [ + "optimize.optimization.optimizable", + false + ], + [ + "k8s.namespace.name", + "bofa-24-02" + ], + [ + "healthrule:ea7bbdfd-706b-4527-b6ca-2aabb48d270b", + "1" + ], + [ + "k8s.deployment.available", + "True" + ], + [ + "k8s.workload.readiness_probe", + "ledgerwriter: |\n probehandler:\n exec: null\n httpget:\n path: /ready\n port:\n type: 0\n intval: 8080\n strval: \"\"\n host: \"\"\n scheme: HTTP\n httpheaders: []\n tcpsocket: null\n grpc: null\n initialdelayseconds: 60\n timeoutseconds: 10\n periodseconds: 5\n successthreshold: 1\n failurethreshold: 3\n terminationgraceperiodseconds: null\n" + ], + [ + "k8s.workload.name", + "ledgerwriter" + ], + [ + "adConfig:09484e94-96b7-4991-be5c-305911e652f2", + "09484e94-96b7-4991-be5c-305911e652f2" + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_ratio", + 0.20310635754893852 + ], + [ + "k8s.workload.resources.requests.memory", + 1.610612736E9 + ], + [ + "troubleshooting:anomaly.status", + 1 + ], + [ + "k8s.cluster.id", + "9b4115a8-6ee9-4dcb-b8c6-39126a01367d" + ], + [ + "optimize.optimization.cautions_count", + 1 + ], + [ + "k8s.workload.resources.requests.cpu", + 0.75 + ], + [ + "health:status", + 0 + ], + [ + "k8sprofiler:optimize.optimization.cautions_count", + 1 + ], + [ + "k8s.object.created_at", + 1705453984000 + ], + [ + "anomaly.status", + 1 + ], + [ + "optimize.instant_recommendation.created_at", + "2024-04-22T00:46:32Z" + ], + [ + "healthrule:63fc2edce875f636297d7b8e", + "0" + ], + [ + "optimize.instant_recommendation.valid", + true + ], + [ + "optimize.instant_recommendation.impact.cost_ratio", + 0.20310635754893852 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.value", + 16.611515326288696 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.currency", + "USD" + ], + [ + "healthrule:a3ffccd8-afc9-4b47-acc0-a3ac9378f613", + "1" + ], + [ + "k8s.workload.resources.limits.cpu", + 0.75 + ] + ] + }, + { + "type": "data", + "model": { + "$jsonPath": "$..[?(@.type == 'model')]..[?(@.name == 'm:attributes')]", + "$model": "m:attributes" + }, + "dataset": "d:attributes-7", + "data": [ + [ + "healthrule:71a40f41-1684-4b51-8a6f-33fcc7439c68", + "1" + ], + [ + "health.status", + 1 + ], + [ + "troubleshooting:model_training_status", + "READY" + ], + [ + "k8s.cluster.name", + "optimize-c1-qe" + ], + [ + "status", + 1 + ], + [ + "k8s.deployment.progressing", + "True" + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.created_at", + "2024-04-22T00:46:46Z" + ], + [ + "k8sprofiler:optimize.optimization.blockers_count", + 4 + ], + [ + "optimize.instant_recommendation.impact.cost_savings.currency", + "USD" + ], + [ + "model_training_status", + "READY" + ], + [ + "k8s.workload.kind", + "Deployment" + ], + [ + "k8s.workload.resources.limits.memory", + 1.610612736E9 + ], + [ + "optimize:optimize.instant_recommendation.created_at", + "2024-04-22T00:46:55Z" + ], + [ + "alerting:health.status", + 1 + ], + [ + "optimize.k8sprofiler.report.efficiency_rate", + 26.0 + ], + [ + "k8s.workload.liveness_probe", + "{}\n" + ], + [ + "optimize.k8sprofiler.report.created_at", + "2024-04-22T00:46:46Z" + ], + [ + "k8sprofiler:optimize.optimization.optimizable", + false + ], + [ + "optimize.instant_recommendation.impact.cost_savings.value", + 23.032365820522067 + ], + [ + "optimize:optimize.instant_recommendation.valid", + true + ], + [ + "healthrule:63fc2edbe875f636297d7b82", + "1" + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "annotation_deployment.kubernetes.io/revision", + "1" + ], + [ + "optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "k8s.deployment.paused", + false + ], + [ + "k8s.workload.startup_probe", + "{}\n" + ], + [ + "optimize.optimization.blockers_count", + 4 + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.efficiency_rate", + 26.0 + ], + [ + "k8s.object.uid", + "77e476cf-7ffc-4f6c-a3d5-a0bae697b73b" + ], + [ + "optimize.optimization.optimizable", + false + ], + [ + "k8s.namespace.name", + "bofa-24-02" + ], + [ + "healthrule:ea7bbdfd-706b-4527-b6ca-2aabb48d270b", + "1" + ], + [ + "k8s.deployment.available", + "True" + ], + [ + "k8s.workload.readiness_probe", + "userservice: |\n probehandler:\n exec: null\n httpget:\n path: /ready\n port:\n type: 0\n intval: 8080\n strval: \"\"\n host: \"\"\n scheme: HTTP\n httpheaders: []\n tcpsocket: null\n grpc: null\n initialdelayseconds: 10\n timeoutseconds: 10\n periodseconds: 5\n successthreshold: 1\n failurethreshold: 3\n terminationgraceperiodseconds: null\n" + ], + [ + "k8s.workload.name", + "userservice" + ], + [ + "adConfig:09484e94-96b7-4991-be5c-305911e652f2", + "09484e94-96b7-4991-be5c-305911e652f2" + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_ratio", + 0.688631742698434 + ], + [ + "k8s.workload.resources.requests.memory", + 5.36870912E8 + ], + [ + "troubleshooting:anomaly.status", + 1 + ], + [ + "k8s.cluster.id", + "9b4115a8-6ee9-4dcb-b8c6-39126a01367d" + ], + [ + "optimize.optimization.cautions_count", + 1 + ], + [ + "k8s.workload.resources.requests.cpu", + 0.5 + ], + [ + "health:status", + 1 + ], + [ + "k8sprofiler:optimize.optimization.cautions_count", + 1 + ], + [ + "k8s.object.created_at", + 1705453986000 + ], + [ + "anomaly.status", + 1 + ], + [ + "optimize.instant_recommendation.created_at", + "2024-04-22T00:46:55Z" + ], + [ + "healthrule:63fc2edce875f636297d7b8e", + "0" + ], + [ + "optimize.instant_recommendation.valid", + true + ], + [ + "optimize.instant_recommendation.impact.cost_ratio", + 0.688631742698434 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.value", + 23.032365820522067 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.currency", + "USD" + ], + [ + "healthrule:a3ffccd8-afc9-4b47-acc0-a3ac9378f613", + "1" + ], + [ + "k8s.workload.resources.limits.cpu", + 1.5 + ] + ] + }, + { + "type": "data", + "model": { + "$jsonPath": "$..[?(@.type == 'model')]..[?(@.name == 'm:attributes')]", + "$model": "m:attributes" + }, + "dataset": "d:attributes-9", + "data": [ + [ + "healthrule:71a40f41-1684-4b51-8a6f-33fcc7439c68", + "3" + ], + [ + "health.status", + 0 + ], + [ + "troubleshooting:model_training_status", + "READY" + ], + [ + "k8s.cluster.name", + "optimize-c1-qe" + ], + [ + "status", + 0 + ], + [ + "k8s.deployment.progressing", + "True" + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.created_at", + "2024-04-22T00:47:20Z" + ], + [ + "k8sprofiler:optimize.optimization.blockers_count", + 2 + ], + [ + "optimize.instant_recommendation.impact.cost_savings.currency", + "USD" + ], + [ + "model_training_status", + "READY" + ], + [ + "k8s.workload.kind", + "Deployment" + ], + [ + "k8s.workload.resources.limits.memory", + 1.610612736E9 + ], + [ + "optimize:optimize.instant_recommendation.created_at", + "2024-04-22T00:47:27Z" + ], + [ + "alerting:health.status", + 0 + ], + [ + "optimize.k8sprofiler.report.efficiency_rate", + 12.0 + ], + [ + "k8s.workload.liveness_probe", + "transactionhistory: |\n probehandler:\n exec: null\n httpget:\n path: /healthy\n port:\n type: 0\n intval: 8080\n strval: \"\"\n host: \"\"\n scheme: HTTP\n httpheaders: []\n tcpsocket: null\n grpc: null\n initialdelayseconds: 120\n timeoutseconds: 10\n periodseconds: 5\n successthreshold: 1\n failurethreshold: 3\n terminationgraceperiodseconds: null\n" + ], + [ + "optimize.k8sprofiler.report.created_at", + "2024-04-22T00:47:20Z" + ], + [ + "k8sprofiler:optimize.optimization.optimizable", + false + ], + [ + "optimize.instant_recommendation.impact.cost_savings.value", + 16.2317165355026 + ], + [ + "optimize:optimize.instant_recommendation.valid", + true + ], + [ + "healthrule:63fc2edbe875f636297d7b82", + "1" + ], + [ + "annotation_deployment.kubernetes.io/revision", + "1" + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "k8s.deployment.paused", + false + ], + [ + "k8s.workload.startup_probe", + "{}\n" + ], + [ + "optimize.optimization.blockers_count", + 2 + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.efficiency_rate", + 12.0 + ], + [ + "k8s.object.uid", + "58f34340-38c2-41da-b897-e14265f296e6" + ], + [ + "optimize.optimization.optimizable", + false + ], + [ + "k8s.namespace.name", + "bofa-24-02" + ], + [ + "healthrule:ea7bbdfd-706b-4527-b6ca-2aabb48d270b", + "1" + ], + [ + "k8s.deployment.available", + "True" + ], + [ + "k8s.workload.readiness_probe", + "transactionhistory: |\n probehandler:\n exec: null\n httpget:\n path: /ready\n port:\n type: 0\n intval: 8080\n strval: \"\"\n host: \"\"\n scheme: HTTP\n httpheaders: []\n tcpsocket: null\n grpc: null\n initialdelayseconds: 60\n timeoutseconds: 10\n periodseconds: 5\n successthreshold: 1\n failurethreshold: 3\n terminationgraceperiodseconds: null\n" + ], + [ + "k8s.workload.name", + "transactionhistory" + ], + [ + "adConfig:09484e94-96b7-4991-be5c-305911e652f2", + "09484e94-96b7-4991-be5c-305911e652f2" + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_ratio", + 0.22132620299007438 + ], + [ + "k8s.workload.resources.requests.memory", + 1.610612736E9 + ], + [ + "troubleshooting:anomaly.status", + 1 + ], + [ + "k8s.cluster.id", + "9b4115a8-6ee9-4dcb-b8c6-39126a01367d" + ], + [ + "optimize.optimization.cautions_count", + 1 + ], + [ + "k8s.workload.resources.requests.cpu", + 0.75 + ], + [ + "health:status", + 0 + ], + [ + "k8sprofiler:optimize.optimization.cautions_count", + 1 + ], + [ + "k8s.object.created_at", + 1705453986000 + ], + [ + "anomaly.status", + 1 + ], + [ + "optimize.instant_recommendation.created_at", + "2024-04-22T00:47:27Z" + ], + [ + "healthrule:63fc2edce875f636297d7b8e", + "0" + ], + [ + "optimize.instant_recommendation.valid", + true + ], + [ + "optimize.instant_recommendation.impact.cost_ratio", + 0.22132620299007438 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.value", + 16.2317165355026 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.currency", + "USD" + ], + [ + "healthrule:a3ffccd8-afc9-4b47-acc0-a3ac9378f613", + "1" + ], + [ + "k8s.workload.resources.limits.cpu", + 0.75 + ] + ] + }, + { + "type": "data", + "model": { + "$jsonPath": "$..[?(@.type == 'model')]..[?(@.name == 'm:attributes')]", + "$model": "m:attributes" + }, + "dataset": "d:attributes-11", + "data": [ + [ + "optimize.recommendation.state", + "preliminary" + ], + [ + "healthrule:71a40f41-1684-4b51-8a6f-33fcc7439c68", + "3" + ], + [ + "health.status", + 1 + ], + [ + "troubleshooting:model_training_status", + "READY" + ], + [ + "k8s.cluster.name", + "optimize-c1-qe" + ], + [ + "status", + 0 + ], + [ + "optimize:optimize.recommendation.state", + "preliminary" + ], + [ + "k8s.deployment.progressing", + "True" + ], + [ + "optimize:optimize.recommendation.impact.cost_savings.currency", + "USD" + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.created_at", + "2024-04-22T00:47:48Z" + ], + [ + "k8sprofiler:optimize.optimization.blockers_count", + 2 + ], + [ + "optimize.instant_recommendation.impact.cost_savings.currency", + "USD" + ], + [ + "model_training_status", + "READY" + ], + [ + "optimize:optimize.recommendation.impact.cost_savings.value", + 192.34 + ], + [ + "k8s.workload.kind", + "Deployment" + ], + [ + "k8s.workload.resources.limits.memory", + 5.36870912E8 + ], + [ + "optimize:optimize.recommendation.impact.cost_savings.percent", + 0.0 + ], + [ + "optimize:optimize.instant_recommendation.created_at", + "2024-04-22T00:47:55Z" + ], + [ + "optimize:optimize.recommendation.created_at", + "2024-03-14T18:18:11.092Z" + ], + [ + "alerting:health.status", + 1 + ], + [ + "optimize.k8sprofiler.report.efficiency_rate", + 17.0 + ], + [ + "k8s.workload.liveness_probe", + "{}\n" + ], + [ + "optimize.k8sprofiler.report.created_at", + "2024-04-22T00:47:48Z" + ], + [ + "k8sprofiler:optimize.optimization.optimizable", + false + ], + [ + "optimize.instant_recommendation.impact.cost_savings.value", + 6.188847581572167 + ], + [ + "optimize:optimize.instant_recommendation.valid", + true + ], + [ + "healthrule:63fc2edbe875f636297d7b82", + "1" + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "annotation_deployment.kubernetes.io/revision", + "1" + ], + [ + "optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "k8s.deployment.paused", + false + ], + [ + "k8s.workload.startup_probe", + "{}\n" + ], + [ + "optimize.optimization.blockers_count", + 2 + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.efficiency_rate", + 17.0 + ], + [ + "k8s.object.uid", + "4d390975-d68f-421a-bad3-01bc1c74796d" + ], + [ + "optimize.optimization.optimizable", + false + ], + [ + "optimize.recommendation.impact.cost_savings.currency", + "USD" + ], + [ + "optimize.recommendation.impact.cost_savings.percent", + 0.0 + ], + [ + "k8s.namespace.name", + "bofa-24-02" + ], + [ + "healthrule:ea7bbdfd-706b-4527-b6ca-2aabb48d270b", + "1" + ], + [ + "k8s.deployment.available", + "True" + ], + [ + "k8s.workload.readiness_probe", + "contacts: |\n probehandler:\n exec: null\n httpget:\n path: /ready\n port:\n type: 0\n intval: 8080\n strval: \"\"\n host: \"\"\n scheme: HTTP\n httpheaders: []\n tcpsocket: null\n grpc: null\n initialdelayseconds: 10\n timeoutseconds: 10\n periodseconds: 5\n successthreshold: 1\n failurethreshold: 3\n terminationgraceperiodseconds: null\n" + ], + [ + "k8s.workload.name", + "contacts" + ], + [ + "adConfig:09484e94-96b7-4991-be5c-305911e652f2", + "09484e94-96b7-4991-be5c-305911e652f2" + ], + [ + "optimize.recommendation.impact.cost_savings.value", + 192.34 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_ratio", + 0.5 + ], + [ + "k8s.workload.resources.requests.memory", + 5.36870912E8 + ], + [ + "troubleshooting:anomaly.status", + 1 + ], + [ + "k8s.cluster.id", + "9b4115a8-6ee9-4dcb-b8c6-39126a01367d" + ], + [ + "optimize.optimization.cautions_count", + 1 + ], + [ + "k8s.workload.resources.requests.cpu", + 0.5 + ], + [ + "health:status", + 0 + ], + [ + "k8sprofiler:optimize.optimization.cautions_count", + 1 + ], + [ + "k8s.object.created_at", + 1705453981000 + ], + [ + "anomaly.status", + 1 + ], + [ + "optimize.instant_recommendation.created_at", + "2024-04-22T00:47:55Z" + ], + [ + "healthrule:63fc2edce875f636297d7b8e", + "0" + ], + [ + "optimize.recommendation.created_at", + "2024-03-14T18:18:11.092Z" + ], + [ + "optimize.instant_recommendation.valid", + true + ], + [ + "optimize.instant_recommendation.impact.cost_ratio", + 0.5 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.value", + 6.188847581572167 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.currency", + "USD" + ], + [ + "healthrule:a3ffccd8-afc9-4b47-acc0-a3ac9378f613", + "1" + ], + [ + "k8s.workload.resources.limits.cpu", + 0.5 + ] + ] + }, + { + "type": "data", + "model": { + "$jsonPath": "$..[?(@.type == 'model')]..[?(@.name == 'm:attributes')]", + "$model": "m:attributes" + }, + "dataset": "d:attributes-13", + "data": [ + [ + "optimize.recommendation.state", + "verified" + ], + [ + "healthrule:71a40f41-1684-4b51-8a6f-33fcc7439c68", + "3" + ], + [ + "health.status", + 3 + ], + [ + "troubleshooting:model_training_status", + "READY" + ], + [ + "k8s.cluster.name", + "optimize-c1-qe" + ], + [ + "status", + 3 + ], + [ + "optimize:optimize.recommendation.state", + "verified" + ], + [ + "k8s.deployment.progressing", + "True" + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.created_at", + "2024-04-22T00:48:04Z" + ], + [ + "k8sprofiler:optimize.optimization.blockers_count", + 4 + ], + [ + "optimize.instant_recommendation.impact.cost_savings.currency", + "USD" + ], + [ + "model_training_status", + "READY" + ], + [ + "k8s.workload.kind", + "Deployment" + ], + [ + "k8s.workload.resources.limits.memory", + 1.610612736E9 + ], + [ + "optimize:optimize.instant_recommendation.created_at", + "2024-04-22T00:48:14Z" + ], + [ + "optimize:optimize.recommendation.created_at", + "2024-02-15T01:14:21.448Z" + ], + [ + "alerting:health.status", + 3 + ], + [ + "optimize.k8sprofiler.report.efficiency_rate", + 12.0 + ], + [ + "k8s.workload.liveness_probe", + "balancereader: |\n probehandler:\n exec: null\n httpget:\n path: /healthy\n port:\n type: 0\n intval: 8080\n strval: \"\"\n host: \"\"\n scheme: HTTP\n httpheaders: []\n tcpsocket: null\n grpc: null\n initialdelayseconds: 120\n timeoutseconds: 10\n periodseconds: 5\n successthreshold: 1\n failurethreshold: 3\n terminationgraceperiodseconds: null\n" + ], + [ + "optimize.k8sprofiler.report.created_at", + "2024-04-22T00:48:04Z" + ], + [ + "k8sprofiler:optimize.optimization.optimizable", + false + ], + [ + "optimize.instant_recommendation.impact.cost_savings.value", + 15.47211895393041 + ], + [ + "optimize:optimize.instant_recommendation.valid", + true + ], + [ + "healthrule:63fc2edbe875f636297d7b82", + "1" + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "annotation_deployment.kubernetes.io/revision", + "1" + ], + [ + "optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "k8s.deployment.paused", + false + ], + [ + "k8s.workload.startup_probe", + "{}\n" + ], + [ + "optimize.optimization.blockers_count", + 4 + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.efficiency_rate", + 12.0 + ], + [ + "k8s.object.uid", + "aac0d56f-0ee4-4ad4-9153-64f079017873" + ], + [ + "optimize.optimization.optimizable", + false + ], + [ + "k8s.namespace.name", + "bofa-24-02" + ], + [ + "healthrule:ea7bbdfd-706b-4527-b6ca-2aabb48d270b", + "1" + ], + [ + "k8s.deployment.available", + "True" + ], + [ + "k8s.workload.readiness_probe", + "balancereader: |\n probehandler:\n exec: null\n httpget:\n path: /ready\n port:\n type: 0\n intval: 8080\n strval: \"\"\n host: \"\"\n scheme: HTTP\n httpheaders: []\n tcpsocket: null\n grpc: null\n initialdelayseconds: 60\n timeoutseconds: 10\n periodseconds: 5\n successthreshold: 1\n failurethreshold: 3\n terminationgraceperiodseconds: null\n" + ], + [ + "k8s.workload.name", + "balancereader" + ], + [ + "adConfig:09484e94-96b7-4991-be5c-305911e652f2", + "09484e94-96b7-4991-be5c-305911e652f2" + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_ratio", + 0.25776589387234616 + ], + [ + "k8s.workload.resources.requests.memory", + 1.610612736E9 + ], + [ + "troubleshooting:anomaly.status", + 1 + ], + [ + "k8s.cluster.id", + "9b4115a8-6ee9-4dcb-b8c6-39126a01367d" + ], + [ + "optimize.optimization.cautions_count", + 1 + ], + [ + "k8s.workload.resources.requests.cpu", + 0.75 + ], + [ + "health:status", + 3 + ], + [ + "k8sprofiler:optimize.optimization.cautions_count", + 1 + ], + [ + "k8s.object.created_at", + 1705453980000 + ], + [ + "anomaly.status", + 1 + ], + [ + "optimize.instant_recommendation.created_at", + "2024-04-22T00:48:14Z" + ], + [ + "healthrule:63fc2edce875f636297d7b8e", + "0" + ], + [ + "optimize.recommendation.created_at", + "2024-02-15T01:14:21.448Z" + ], + [ + "optimize.instant_recommendation.valid", + true + ], + [ + "optimize.instant_recommendation.impact.cost_ratio", + 0.25776589387234616 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.value", + 15.47211895393041 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.currency", + "USD" + ], + [ + "healthrule:a3ffccd8-afc9-4b47-acc0-a3ac9378f613", + "1" + ], + [ + "k8s.workload.resources.limits.cpu", + 0.75 + ] + ] + }, + { + "type": "data", + "model": { + "$jsonPath": "$..[?(@.type == 'model')]..[?(@.name == 'm:attributes')]", + "$model": "m:attributes" + }, + "dataset": "d:attributes-15", + "data": [ + [ + "k8s.deployment.paused", + false + ], + [ + "k8s.workload.startup_probe", + "{}\n" + ], + [ + "optimize.optimization.blockers_count", + 4 + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.efficiency_rate", + 16.0 + ], + [ + "k8s.object.uid", + "d3c6a873-167c-463e-a14c-040e7b6c1f1a" + ], + [ + "troubleshooting:model_training_status", + "READY" + ], + [ + "optimize.optimization.optimizable", + false + ], + [ + "k8s.cluster.name", + "optimize-c1-qe" + ], + [ + "k8s.namespace.name", + "bofa-24-02" + ], + [ + "k8s.deployment.progressing", + "True" + ], + [ + "k8s.deployment.available", + "True" + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.created_at", + "2024-04-16T05:16:12Z" + ], + [ + "k8sprofiler:optimize.optimization.blockers_count", + 4 + ], + [ + "optimize.instant_recommendation.impact.cost_savings.currency", + "" + ], + [ + "k8s.workload.readiness_probe", + "{}\n" + ], + [ + "model_training_status", + "READY" + ], + [ + "k8s.workload.name", + "servox-fe670f8fa39c4fc2b5f107f1096d9c22" + ], + [ + "adConfig:09484e94-96b7-4991-be5c-305911e652f2", + "09484e94-96b7-4991-be5c-305911e652f2" + ], + [ + "k8s.workload.kind", + "Deployment" + ], + [ + "k8s.workload.resources.limits.memory", + 6.7108864E8 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_ratio", + 0.0 + ], + [ + "optimize:optimize.instant_recommendation.created_at", + "2024-04-16T05:16:28Z" + ], + [ + "troubleshooting:anomaly.status", + 1 + ], + [ + "k8s.workload.resources.requests.memory", + 0.0 + ], + [ + "optimize.k8sprofiler.report.efficiency_rate", + 16.0 + ], + [ + "k8s.workload.liveness_probe", + "{}\n" + ], + [ + "k8s.cluster.id", + "9b4115a8-6ee9-4dcb-b8c6-39126a01367d" + ], + [ + "optimize.k8sprofiler.report.created_at", + "2024-04-16T05:16:12Z" + ], + [ + "k8sprofiler:optimize.optimization.optimizable", + false + ], + [ + "optimize.optimization.cautions_count", + 1 + ], + [ + "k8s.workload.resources.requests.cpu", + 0.0 + ], + [ + "optimize.instant_recommendation.impact.cost_savings.value", + 0.0 + ], + [ + "k8sprofiler:optimize.optimization.cautions_count", + 1 + ], + [ + "k8s.object.created_at", + 1712759623000 + ], + [ + "anomaly.status", + 1 + ], + [ + "optimize.instant_recommendation.created_at", + "2024-04-16T05:16:28Z" + ], + [ + "optimize:optimize.instant_recommendation.valid", + false + ], + [ + "optimize.instant_recommendation.valid", + false + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "annotation_deployment.kubernetes.io/revision", + "1" + ], + [ + "optimize.instant_recommendation.impact.cost_ratio", + 0.0 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.value", + 0.0 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.currency", + "" + ], + [ + "optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "k8s.workload.resources.limits.cpu", + 0.35 + ] + ] + }, + { + "type": "data", + "model": { + "$jsonPath": "$..[?(@.type == 'model')]..[?(@.name == 'm:attributes')]", + "$model": "m:attributes" + }, + "dataset": "d:attributes-17", + "data": [ + [ + "k8s.deployment.paused", + false + ], + [ + "k8s.workload.startup_probe", + "{}\n" + ], + [ + "optimize.optimization.blockers_count", + 3 + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.efficiency_rate", + 11.0 + ], + [ + "healthrule:71a40f41-1684-4b51-8a6f-33fcc7439c68", + "3" + ], + [ + "health.status", + 3 + ], + [ + "k8s.object.uid", + "27316581-d09d-4eba-bc14-66f081679bdc" + ], + [ + "troubleshooting:model_training_status", + "READY" + ], + [ + "optimize.optimization.optimizable", + false + ], + [ + "k8s.cluster.name", + "optimize-c1-qe" + ], + [ + "status", + 3 + ], + [ + "k8s.namespace.name", + "bofa-24-02" + ], + [ + "k8s.deployment.progressing", + "True" + ], + [ + "healthrule:ea7bbdfd-706b-4527-b6ca-2aabb48d270b", + "3" + ], + [ + "k8s.deployment.available", + "True" + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.created_at", + "2024-04-22T00:56:17Z" + ], + [ + "k8sprofiler:optimize.optimization.blockers_count", + 3 + ], + [ + "optimize.instant_recommendation.impact.cost_savings.currency", + "USD" + ], + [ + "k8s.workload.readiness_probe", + "{}\n" + ], + [ + "model_training_status", + "READY" + ], + [ + "k8s.workload.name", + "servox-f564fed7b1b448d3b23978cd44a69e4b" + ], + [ + "adConfig:09484e94-96b7-4991-be5c-305911e652f2", + "09484e94-96b7-4991-be5c-305911e652f2" + ], + [ + "k8s.workload.kind", + "Deployment" + ], + [ + "k8s.workload.resources.limits.memory", + 6.7108864E8 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_ratio", + 0.6342902022980065 + ], + [ + "optimize:optimize.instant_recommendation.created_at", + "2024-04-22T00:56:21Z" + ], + [ + "troubleshooting:anomaly.status", + 0 + ], + [ + "k8s.workload.resources.requests.memory", + 0.0 + ], + [ + "alerting:health.status", + 3 + ], + [ + "optimize.k8sprofiler.report.efficiency_rate", + 11.0 + ], + [ + "k8s.workload.liveness_probe", + "{}\n" + ], + [ + "k8s.cluster.id", + "9b4115a8-6ee9-4dcb-b8c6-39126a01367d" + ], + [ + "optimize.k8sprofiler.report.created_at", + "2024-04-22T00:56:17Z" + ], + [ + "k8sprofiler:optimize.optimization.optimizable", + false + ], + [ + "optimize.optimization.cautions_count", + 1 + ], + [ + "k8s.workload.resources.requests.cpu", + 0.0 + ], + [ + "optimize.instant_recommendation.impact.cost_savings.value", + 3.4742225815721794 + ], + [ + "health:status", + 3 + ], + [ + "k8sprofiler:optimize.optimization.cautions_count", + 1 + ], + [ + "k8s.object.created_at", + 1713302071000 + ], + [ + "anomaly.status", + 0 + ], + [ + "optimize.instant_recommendation.created_at", + "2024-04-22T00:56:21Z" + ], + [ + "optimize:optimize.instant_recommendation.valid", + true + ], + [ + "healthrule:63fc2edce875f636297d7b8e", + "0" + ], + [ + "healthrule:63fc2edbe875f636297d7b82", + "0" + ], + [ + "optimize.instant_recommendation.valid", + true + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "annotation_deployment.kubernetes.io/revision", + "1" + ], + [ + "optimize.instant_recommendation.impact.cost_ratio", + 0.6342902022980065 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.value", + 3.4742225815721794 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.currency", + "USD" + ], + [ + "optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "healthrule:a3ffccd8-afc9-4b47-acc0-a3ac9378f613", + "3" + ], + [ + "k8s.workload.resources.limits.cpu", + 0.35 + ] + ] + }, + { + "type": "data", + "model": { + "$jsonPath": "$..[?(@.type == 'model')]..[?(@.name == 'm:attributes')]", + "$model": "m:attributes" + }, + "dataset": "d:attributes-19", + "data": [ + [ + "k8s.deployment.paused", + false + ], + [ + "k8s.workload.startup_probe", + "{}\n" + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.efficiency_rate", + 0.0 + ], + [ + "optimize.optimization.blockers_count", + 4 + ], + [ + "healthrule:71a40f41-1684-4b51-8a6f-33fcc7439c68", + "3" + ], + [ + "health.status", + 3 + ], + [ + "k8s.object.uid", + "0db97495-528d-431b-8679-0f3fd195790a" + ], + [ + "troubleshooting:model_training_status", + "READY" + ], + [ + "optimize.optimization.optimizable", + false + ], + [ + "k8s.cluster.name", + "optimize-c1-qe" + ], + [ + "status", + 3 + ], + [ + "k8s.namespace.name", + "bofa-24-02" + ], + [ + "k8s.deployment.progressing", + "True" + ], + [ + "healthrule:ea7bbdfd-706b-4527-b6ca-2aabb48d270b", + "1" + ], + [ + "k8s.deployment.available", + "False" + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.created_at", + "2024-03-26T17:49:24Z" + ], + [ + "k8sprofiler:optimize.optimization.blockers_count", + 4 + ], + [ + "optimize.instant_recommendation.impact.cost_savings.currency", + "" + ], + [ + "k8s.workload.readiness_probe", + "{}\n" + ], + [ + "model_training_status", + "READY" + ], + [ + "k8s.workload.name", + "servox-bcf01b4bd8e74e5193fb6bc2c0d2b715" + ], + [ + "adConfig:09484e94-96b7-4991-be5c-305911e652f2", + "09484e94-96b7-4991-be5c-305911e652f2" + ], + [ + "k8s.workload.kind", + "Deployment" + ], + [ + "k8s.workload.resources.limits.memory", + 6.7108864E8 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_ratio", + 1.0 + ], + [ + "optimize:optimize.instant_recommendation.created_at", + "2024-03-26T17:50:44Z" + ], + [ + "troubleshooting:anomaly.status", + 0 + ], + [ + "k8s.workload.resources.requests.memory", + 0.0 + ], + [ + "alerting:health.status", + 3 + ], + [ + "optimize.k8sprofiler.report.efficiency_rate", + 0.0 + ], + [ + "k8s.workload.liveness_probe", + "{}\n" + ], + [ + "k8s.cluster.id", + "9b4115a8-6ee9-4dcb-b8c6-39126a01367d" + ], + [ + "optimize.k8sprofiler.report.created_at", + "2024-03-26T17:49:24Z" + ], + [ + "k8sprofiler:optimize.optimization.optimizable", + false + ], + [ + "optimize.optimization.cautions_count", + 2 + ], + [ + "k8s.workload.resources.requests.cpu", + 0.0 + ], + [ + "optimize.instant_recommendation.impact.cost_savings.value", + 0.0 + ], + [ + "health:status", + 3 + ], + [ + "k8sprofiler:optimize.optimization.cautions_count", + 2 + ], + [ + "k8s.object.created_at", + 1710362213000 + ], + [ + "anomaly.status", + 0 + ], + [ + "optimize.instant_recommendation.created_at", + "2024-03-26T17:50:44Z" + ], + [ + "optimize:optimize.instant_recommendation.valid", + true + ], + [ + "healthrule:63fc2edce875f636297d7b8e", + "2" + ], + [ + "healthrule:63fc2edbe875f636297d7b82", + "0" + ], + [ + "optimize.instant_recommendation.valid", + true + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.reliability_risk", + "high" + ], + [ + "annotation_deployment.kubernetes.io/revision", + "2" + ], + [ + "optimize.instant_recommendation.impact.cost_ratio", + 1.0 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.value", + 0.0 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.currency", + "" + ], + [ + "optimize.k8sprofiler.report.reliability_risk", + "high" + ], + [ + "healthrule:a3ffccd8-afc9-4b47-acc0-a3ac9378f613", + "3" + ], + [ + "k8s.workload.resources.limits.cpu", + 0.35 + ] + ] + }, + { + "type": "data", + "model": { + "$jsonPath": "$..[?(@.type == 'model')]..[?(@.name == 'm:attributes')]", + "$model": "m:attributes" + }, + "dataset": "d:attributes-21", + "data": [ + [ + "k8s.deployment.paused", + false + ], + [ + "k8s.workload.startup_probe", + "{}\n" + ], + [ + "optimize.optimization.blockers_count", + 3 + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.efficiency_rate", + 9.0 + ], + [ + "healthrule:71a40f41-1684-4b51-8a6f-33fcc7439c68", + "3" + ], + [ + "health.status", + 3 + ], + [ + "k8s.object.uid", + "7b6799c6-5bf9-4e2c-874c-c428672c5524" + ], + [ + "troubleshooting:model_training_status", + "READY" + ], + [ + "optimize.optimization.optimizable", + false + ], + [ + "k8s.cluster.name", + "optimize-c1-qe" + ], + [ + "status", + 3 + ], + [ + "k8s.namespace.name", + "bofa-24-02" + ], + [ + "k8s.deployment.progressing", + "True" + ], + [ + "healthrule:ea7bbdfd-706b-4527-b6ca-2aabb48d270b", + "3" + ], + [ + "k8s.deployment.available", + "True" + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.created_at", + "2024-04-20T01:33:02Z" + ], + [ + "k8sprofiler:optimize.optimization.blockers_count", + 3 + ], + [ + "optimize.instant_recommendation.impact.cost_savings.currency", + "" + ], + [ + "k8s.workload.readiness_probe", + "{}\n" + ], + [ + "model_training_status", + "READY" + ], + [ + "k8s.workload.name", + "servox-26668fa17b21405e99b7631388179f39" + ], + [ + "adConfig:09484e94-96b7-4991-be5c-305911e652f2", + "09484e94-96b7-4991-be5c-305911e652f2" + ], + [ + "k8s.workload.kind", + "Deployment" + ], + [ + "k8s.workload.resources.limits.memory", + 6.7108864E8 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_ratio", + 0.0 + ], + [ + "optimize:optimize.instant_recommendation.created_at", + "2024-04-22T00:57:58Z" + ], + [ + "troubleshooting:anomaly.status", + 0 + ], + [ + "k8s.workload.resources.requests.memory", + 0.0 + ], + [ + "alerting:health.status", + 3 + ], + [ + "optimize.k8sprofiler.report.efficiency_rate", + 9.0 + ], + [ + "k8s.workload.liveness_probe", + "{}\n" + ], + [ + "k8s.cluster.id", + "9b4115a8-6ee9-4dcb-b8c6-39126a01367d" + ], + [ + "optimize.k8sprofiler.report.created_at", + "2024-04-20T01:33:02Z" + ], + [ + "k8sprofiler:optimize.optimization.optimizable", + false + ], + [ + "optimize.optimization.cautions_count", + 1 + ], + [ + "k8s.workload.resources.requests.cpu", + 0.0 + ], + [ + "optimize.instant_recommendation.impact.cost_savings.value", + 0.0 + ], + [ + "health:status", + 3 + ], + [ + "k8sprofiler:optimize.optimization.cautions_count", + 1 + ], + [ + "k8s.object.created_at", + 1713450330000 + ], + [ + "anomaly.status", + 0 + ], + [ + "optimize.instant_recommendation.created_at", + "2024-04-22T00:57:58Z" + ], + [ + "optimize:optimize.instant_recommendation.valid", + false + ], + [ + "healthrule:63fc2edce875f636297d7b8e", + "0" + ], + [ + "healthrule:63fc2edbe875f636297d7b82", + "3" + ], + [ + "optimize.instant_recommendation.valid", + false + ], + [ + "k8sprofiler:optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "annotation_deployment.kubernetes.io/revision", + "1" + ], + [ + "optimize.instant_recommendation.impact.cost_ratio", + 0.0 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.value", + 0.0 + ], + [ + "optimize:optimize.instant_recommendation.impact.cost_savings.currency", + "" + ], + [ + "optimize.k8sprofiler.report.reliability_risk", + "low" + ], + [ + "healthrule:a3ffccd8-afc9-4b47-acc0-a3ac9378f613", + "3" + ], + [ + "k8s.workload.resources.limits.cpu", + 0.35 + ] + ] + }, + { + "type": "data", + "model": { + "$jsonPath": "$..[?(@.type == 'model')]..[?(@.name == 'm:main')]", + "$model": "m:main" + }, + "metadata": { + "since": "2024-04-15T17:46:58.837448122Z", + "until": "2024-04-22T17:46:58.837448122Z" + }, + "main": true, + "dataset": "d:main", + "data": [ + [ + "k8s:deployment:VfJUeLlJOUyRrgi8ABDBMQ", + { + "$dataset": "d:attributes-1", + "$jsonPath": "$..[?(@.type == 'data' && @.dataset == 'd:attributes-1')]" + }, + null + ], + [ + "k8s:deployment:GY6sVnqLPbCtHwDpX0JARw", + { + "$dataset": "d:attributes-3", + "$jsonPath": "$..[?(@.type == 'data' && @.dataset == 'd:attributes-3')]" + }, + null + ], + [ + "k8s:deployment:Cky9fa+OMeWBRhYR0miVeg", + { + "$dataset": "d:attributes-5", + "$jsonPath": "$..[?(@.type == 'data' && @.dataset == 'd:attributes-5')]" + }, + null + ], + [ + "k8s:deployment:fdCKxDo1O6Sz3YUTUhvFIA", + { + "$dataset": "d:attributes-7", + "$jsonPath": "$..[?(@.type == 'data' && @.dataset == 'd:attributes-7')]" + }, + null + ], + [ + "k8s:deployment:GsgjXFUqPzWfP/b3JGaJZA", + { + "$dataset": "d:attributes-9", + "$jsonPath": "$..[?(@.type == 'data' && @.dataset == 'd:attributes-9')]" + }, + null + ], + [ + "k8s:deployment:7LIVdeMiOUu4DPKQ6B9kwA", + { + "$dataset": "d:attributes-11", + "$jsonPath": "$..[?(@.type == 'data' && @.dataset == 'd:attributes-11')]" + }, + null + ], + [ + "k8s:deployment:ESw66KKKOACQ5NQ6ZqyGXg", + { + "$dataset": "d:attributes-13", + "$jsonPath": "$..[?(@.type == 'data' && @.dataset == 'd:attributes-13')]" + }, + null + ], + [ + "k8s:deployment:y6osKMxVNzWq3GZDa8jDBg", + { + "$dataset": "d:attributes-15", + "$jsonPath": "$..[?(@.type == 'data' && @.dataset == 'd:attributes-15')]" + }, + null + ], + [ + "k8s:deployment:Z6o0QVUKNbOt3P0ZYhW3Sw", + { + "$dataset": "d:attributes-17", + "$jsonPath": "$..[?(@.type == 'data' && @.dataset == 'd:attributes-17')]" + }, + null + ], + [ + "k8s:deployment:ZhaOCwGZMoy2vd+/juwwlQ", + { + "$dataset": "d:attributes-19", + "$jsonPath": "$..[?(@.type == 'data' && @.dataset == 'd:attributes-19')]" + }, + null + ], + [ + "k8s:deployment:rQEJDLbnOJSohc2CWJ6GOA", + { + "$dataset": "d:attributes-21", + "$jsonPath": "$..[?(@.type == 'data' && @.dataset == 'd:attributes-21')]" + }, + null + ] + ] + } + ] \ No newline at end of file