|
|
@@ -14,6 +14,7 @@ import (
|
|
|
|
|
|
costAnalyzerCloud "github.com/kubecost/cost-model/pkg/cloud"
|
|
|
"github.com/kubecost/cost-model/pkg/clustercache"
|
|
|
+ "github.com/kubecost/cost-model/pkg/errors"
|
|
|
"github.com/kubecost/cost-model/pkg/log"
|
|
|
"github.com/kubecost/cost-model/pkg/util"
|
|
|
prometheusClient "github.com/prometheus/client_golang/api"
|
|
|
@@ -122,42 +123,6 @@ func (cd *CostData) GetController() (name string, kind string, hasController boo
|
|
|
return name, kind, hasController
|
|
|
}
|
|
|
|
|
|
-// Error collection helper
|
|
|
-type ErrorCollector struct {
|
|
|
- m sync.Mutex
|
|
|
- errors []error
|
|
|
-}
|
|
|
-
|
|
|
-// Reports an error to the collector. Ignores if the error is nil.
|
|
|
-func (ec *ErrorCollector) Report(e error) {
|
|
|
- if e == nil {
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- ec.m.Lock()
|
|
|
- defer ec.m.Unlock()
|
|
|
-
|
|
|
- ec.errors = append(ec.errors, e)
|
|
|
-}
|
|
|
-
|
|
|
-// Whether or not the collector caught errors
|
|
|
-func (ec *ErrorCollector) IsError() bool {
|
|
|
- ec.m.Lock()
|
|
|
- defer ec.m.Unlock()
|
|
|
-
|
|
|
- return len(ec.errors) > 0
|
|
|
-}
|
|
|
-
|
|
|
-// Errors caught by the collector
|
|
|
-func (ec *ErrorCollector) Errors() []error {
|
|
|
- ec.m.Lock()
|
|
|
- defer ec.m.Unlock()
|
|
|
-
|
|
|
- errs := make([]error, len(ec.errors))
|
|
|
- copy(errs, ec.errors)
|
|
|
- return errs
|
|
|
-}
|
|
|
-
|
|
|
const (
|
|
|
queryRAMRequestsStr = `avg(
|
|
|
label_replace(
|
|
|
@@ -370,10 +335,11 @@ func (cm *CostModel) ComputeCostData(cli prometheusClient.Client, clientset kube
|
|
|
var wg sync.WaitGroup
|
|
|
wg.Add(11)
|
|
|
|
|
|
- var ec ErrorCollector
|
|
|
+ var ec errors.ErrorCollector
|
|
|
var resultRAMRequests interface{}
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultRAMRequests, promErr = Query(cli, queryRAMRequests)
|
|
|
@@ -386,6 +352,7 @@ func (cm *CostModel) ComputeCostData(cli prometheusClient.Client, clientset kube
|
|
|
var resultRAMUsage interface{}
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultRAMUsage, promErr = Query(cli, queryRAMUsage)
|
|
|
@@ -397,6 +364,7 @@ func (cm *CostModel) ComputeCostData(cli prometheusClient.Client, clientset kube
|
|
|
var resultCPURequests interface{}
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultCPURequests, promErr = Query(cli, queryCPURequests)
|
|
|
@@ -408,6 +376,7 @@ func (cm *CostModel) ComputeCostData(cli prometheusClient.Client, clientset kube
|
|
|
var resultCPUUsage interface{}
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultCPUUsage, promErr = Query(cli, queryCPUUsage)
|
|
|
@@ -419,6 +388,7 @@ func (cm *CostModel) ComputeCostData(cli prometheusClient.Client, clientset kube
|
|
|
var resultGPURequests interface{}
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultGPURequests, promErr = Query(cli, queryGPURequests)
|
|
|
@@ -430,6 +400,7 @@ func (cm *CostModel) ComputeCostData(cli prometheusClient.Client, clientset kube
|
|
|
var resultPVRequests interface{}
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultPVRequests, promErr = Query(cli, queryPVRequests)
|
|
|
@@ -441,6 +412,7 @@ func (cm *CostModel) ComputeCostData(cli prometheusClient.Client, clientset kube
|
|
|
var resultNetZoneRequests interface{}
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultNetZoneRequests, promErr = Query(cli, queryNetZoneRequests)
|
|
|
@@ -452,6 +424,7 @@ func (cm *CostModel) ComputeCostData(cli prometheusClient.Client, clientset kube
|
|
|
var resultNetRegionRequests interface{}
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultNetRegionRequests, promErr = Query(cli, queryNetRegionRequests)
|
|
|
@@ -463,6 +436,7 @@ func (cm *CostModel) ComputeCostData(cli prometheusClient.Client, clientset kube
|
|
|
var resultNetInternetRequests interface{}
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultNetInternetRequests, promErr = Query(cli, queryNetInternetRequests)
|
|
|
@@ -474,6 +448,7 @@ func (cm *CostModel) ComputeCostData(cli prometheusClient.Client, clientset kube
|
|
|
var normalizationResult interface{}
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
normalizationResult, promErr = Query(cli, normalization)
|
|
|
@@ -490,6 +465,7 @@ func (cm *CostModel) ComputeCostData(cli prometheusClient.Client, clientset kube
|
|
|
var k8sErr error
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
podDeploymentsMapping, k8sErr = getPodDeployments(cm.Cache, podlist, clusterID)
|
|
|
if k8sErr != nil {
|
|
|
@@ -1772,11 +1748,12 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
queryProfileStart := time.Now()
|
|
|
queryProfileCh := make(chan string, numQueries)
|
|
|
|
|
|
- var ec ErrorCollector
|
|
|
+ var ec errors.ErrorCollector
|
|
|
var resultRAMRequests interface{}
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "RAMRequests", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultRAMRequests, promErr = QueryRange(cli, queryRAMRequests, start, end, window)
|
|
|
@@ -1789,6 +1766,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "RAMUsage", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultRAMUsage, promErr = QueryRange(cli, queryRAMUsage, start, end, window)
|
|
|
@@ -1801,6 +1779,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "CPURequests", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultCPURequests, promErr = QueryRange(cli, queryCPURequests, start, end, window)
|
|
|
@@ -1813,6 +1792,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "CPUUsage", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultCPUUsage, promErr = QueryRange(cli, queryCPUUsage, start, end, window)
|
|
|
@@ -1825,6 +1805,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "RAMAllocations", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultRAMAllocations, promErr = QueryRange(cli, queryRAMAlloc, start, end, window)
|
|
|
@@ -1837,6 +1818,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "CPUAllocations", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultCPUAllocations, promErr = QueryRange(cli, queryCPUAlloc, start, end, window)
|
|
|
@@ -1849,6 +1831,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "GPURequests", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultGPURequests, promErr = QueryRange(cli, queryGPURequests, start, end, window)
|
|
|
@@ -1861,6 +1844,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "PVRequests", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultPVRequests, promErr = QueryRange(cli, queryPVRequests, start, end, window)
|
|
|
@@ -1873,6 +1857,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "NetZoneRequests", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultNetZoneRequests, promErr = QueryRange(cli, queryNetZoneRequests, start, end, window)
|
|
|
@@ -1885,6 +1870,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "NetRegionRequests", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultNetRegionRequests, promErr = QueryRange(cli, queryNetRegionRequests, start, end, window)
|
|
|
@@ -1897,6 +1883,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "NetInternetRequests", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
resultNetInternetRequests, promErr = QueryRange(cli, queryNetInternetRequests, start, end, window)
|
|
|
@@ -1909,6 +1896,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "PVPodAllocation", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
pvPodAllocationResults, promErr = QueryRange(cli, queryPVCAllocation, start, end, window)
|
|
|
@@ -1921,6 +1909,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "PVCost", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
pvCostResults, promErr = QueryRange(cli, queryPVHourlyCost, start, end, window)
|
|
|
@@ -1933,6 +1922,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "NSLabels", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
nsLabelsResults, promErr = QueryRange(cli, fmt.Sprintf(queryNSLabels, windowString), start, end, window)
|
|
|
@@ -1945,6 +1935,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "PodLabels", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
podLabelsResults, promErr = QueryRange(cli, fmt.Sprintf(queryPodLabels, windowString), start, end, window)
|
|
|
@@ -1957,6 +1948,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "ServiceLabels", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
serviceLabelsResults, promErr = QueryRange(cli, fmt.Sprintf(queryServiceLabels, windowString), start, end, window)
|
|
|
@@ -1969,6 +1961,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "DeploymentLabels", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
deploymentLabelsResults, promErr = QueryRange(cli, fmt.Sprintf(queryDeploymentLabels, windowString), start, end, window)
|
|
|
@@ -1981,6 +1974,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "Daemonsets", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
daemonsetResults, promErr = QueryRange(cli, fmt.Sprintf(queryPodDaemonsets), start, end, window)
|
|
|
@@ -1993,6 +1987,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "StatefulSetLabels", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
statefulsetLabelsResults, promErr = QueryRange(cli, fmt.Sprintf(queryStatefulsetLabels, windowString), start, end, window)
|
|
|
@@ -2005,6 +2000,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
defer measureTimeAsync(time.Now(), profileThreshold, "Normalization", queryProfileCh)
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
var promErr error
|
|
|
normalizationResults, promErr = QueryRange(cli, normalization, start, end, window)
|
|
|
@@ -2022,6 +2018,7 @@ func (cm *CostModel) costDataRange(cli prometheusClient.Client, clientset kubern
|
|
|
var k8sErr error
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
+ defer errors.HandlePanic()
|
|
|
|
|
|
podDeploymentsMapping, k8sErr = getPodDeployments(cm.Cache, podlist, clusterID)
|
|
|
if k8sErr != nil {
|