Browse Source

Replaced encoding/json with jsoniter

Neal Ormsbee 5 năm trước cách đây
mục cha
commit
665f1cc70e

+ 1 - 0
go.mod

@@ -18,6 +18,7 @@ require (
 	github.com/google/uuid v1.1.2
 	github.com/googleapis/gax-go v2.0.2+incompatible // indirect
 	github.com/gophercloud/gophercloud v0.2.0 // indirect
+	github.com/json-iterator/go v1.1.10
 	github.com/jszwec/csvutil v1.2.1
 	github.com/julienschmidt/httprouter v1.2.0
 	github.com/lib/pq v1.2.0

+ 7 - 6
pkg/cloud/awsprovider.go

@@ -36,6 +36,7 @@ import (
 	"github.com/jszwec/csvutil"
 
 	v1 "k8s.io/api/core/v1"
+	jsoniter "github.com/json-iterator/go"
 )
 
 const supportedSpotFeedVersion = "1"
@@ -1284,7 +1285,7 @@ func (aws *AWS) loadAWSAuthSecret(force bool) (*AWSAccessKey, error) {
 	}
 
 	var ak AWSAccessKey
-	err = json.Unmarshal(result, &ak)
+	err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(result, &ak)
 	if err != nil {
 		return nil, err
 	}
@@ -1304,7 +1305,7 @@ func getClusterConfig(ccFile string) (map[string]string, error) {
 		return nil, err
 	}
 	var clusterConf map[string]string
-	err = json.Unmarshal([]byte(b), &clusterConf)
+	err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal([]byte(b), &clusterConf)
 	if err != nil {
 		return nil, err
 	}
@@ -1388,7 +1389,7 @@ func (a *AWS) GetAddresses() ([]byte, error) {
 	// Format the response this way to match the JSON-encoded formatting of a single response
 	// from DescribeAddresss, so that consumers can always expect AWS disk responses to have
 	// a "Addresss" key at the top level.
-	return json.Marshal(map[string][]*ec2.Address{
+	return jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(map[string][]*ec2.Address{
 		"Addresses": addresses,
 	})
 }
@@ -1492,7 +1493,7 @@ func (a *AWS) GetDisks() ([]byte, error) {
 	// Format the response this way to match the JSON-encoded formatting of a single response
 	// from DescribeVolumes, so that consumers can always expect AWS disk responses to have
 	// a "Volumes" key at the top level.
-	return json.Marshal(map[string][]*ec2.Volume{
+	return jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(map[string][]*ec2.Volume{
 		"Volumes": volumes,
 	})
 }
@@ -1968,7 +1969,7 @@ func (a *AWS) QuerySQL(query string) ([]byte, error) {
 		return nil, err
 	}
 	var athenaConf map[string]string
-	json.Unmarshal([]byte(b), &athenaConf)
+	jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal([]byte(b), &athenaConf)
 	region := aws.String(customPricing.AthenaRegion)
 	resultsBucket := customPricing.AthenaBucketName
 	database := customPricing.AthenaDatabase
@@ -2023,7 +2024,7 @@ func (a *AWS) QuerySQL(query string) ([]byte, error) {
 		if err != nil {
 			return nil, err
 		}
-		b, err := json.Marshal(op.ResultSet)
+		b, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(op.ResultSet)
 		if err != nil {
 			return nil, err
 		}

+ 4 - 3
pkg/cloud/azureprovider.go

@@ -28,6 +28,7 @@ import (
 	"github.com/Azure/go-autorest/autorest/azure/auth"
 	v1 "k8s.io/api/core/v1"
 	"k8s.io/klog"
+	jsoniter "github.com/json-iterator/go"
 )
 
 const (
@@ -387,7 +388,7 @@ func (az *Azure) loadAzureAuthSecret(force bool) (*AzureServiceKey, error) {
 	}
 
 	var ask AzureServiceKey
-	err = json.Unmarshal(result, &ask)
+	err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(result, &ask)
 	if err != nil {
 		return nil, err
 	}
@@ -416,7 +417,7 @@ func (az *Azure) loadAzureStorageConfig(force bool) (*AzureStorageConfig, error)
 	}
 
 	var ask AzureStorageConfig
-	err = json.Unmarshal(result, &ask)
+	err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(result, &ask)
 	if err != nil {
 		return nil, err
 	}
@@ -1023,7 +1024,7 @@ func parseCSV(reader *csv.Reader, start, end time.Time, oocAllocs map[string]*Ou
 		itemTags := make(map[string]string)
 		itemTagJson := makeValidJSON(record[headerMap["Tags"]])
 		if itemTagJson != "" {
-			err = json.Unmarshal([]byte(itemTagJson), &itemTags)
+			err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal([]byte(itemTagJson), &itemTags)
 			if err != nil {
 				klog.Infof("Could not parse item tags %v", err)
 			}

+ 5 - 4
pkg/cloud/gcpprovider.go

@@ -29,6 +29,7 @@ import (
 	compute "google.golang.org/api/compute/v1"
 	"google.golang.org/api/iterator"
 	v1 "k8s.io/api/core/v1"
+	jsoniter "github.com/json-iterator/go"
 )
 
 const GKE_GPU_TAG = "cloud.google.com/gke-accelerator"
@@ -80,7 +81,7 @@ func multiKeyGCPAllocationToOutOfClusterAllocation(gcpAlloc multiKeyGCPAllocatio
 	var environment string
 	var usedAggregatorName string
 	if gcpAlloc.Keys.Valid {
-		err := json.Unmarshal([]byte(gcpAlloc.Keys.StringVal), &keys)
+		err := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal([]byte(gcpAlloc.Keys.StringVal), &keys)
 		if err != nil {
 			klog.Infof("Invalid unmarshaling response from BigQuery filtered query: %s", err.Error())
 		}
@@ -242,7 +243,7 @@ func (gcp *GCP) UpdateConfig(r io.Reader, updateType string) (*CustomPricing, er
 			c.BillingDataDataset = a.BillingDataDataset
 
 			if len(a.Key) > 0 {
-				j, err := json.Marshal(a.Key)
+				j, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(a.Key)
 				if err != nil {
 					return err
 				}
@@ -532,7 +533,7 @@ func (*GCP) GetAddresses() ([]byte, error) {
 	if err != nil {
 		return nil, err
 	}
-	return json.Marshal(res)
+	return jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(res)
 }
 
 // GetDisks returns the GCP disks backing PVs. Useful because sometimes k8s will not clean up PVs correctly. Requires a json config in /var/configs with key region.
@@ -561,7 +562,7 @@ func (*GCP) GetDisks() ([]byte, error) {
 	if err != nil {
 		return nil, err
 	}
-	return json.Marshal(res)
+	return jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(res)
 
 }
 

+ 4 - 4
pkg/cloud/providerconfig.go

@@ -1,7 +1,6 @@
 package cloud
 
 import (
-	"encoding/json"
 	"fmt"
 	"io/ioutil"
 	"reflect"
@@ -14,6 +13,7 @@ import (
 	"github.com/microcosm-cc/bluemonday"
 
 	"k8s.io/klog"
+	jsoniter "github.com/json-iterator/go"
 )
 
 var sanitizePolicy = bluemonday.UGCPolicy()
@@ -58,7 +58,7 @@ func (pc *ProviderConfig) loadConfig(writeIfNotExists bool) (*CustomPricing, err
 
 		// Only write the file if flag enabled
 		if writeIfNotExists {
-			cj, err := json.Marshal(pc.customPricing)
+			cj, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(pc.customPricing)
 			if err != nil {
 				return pc.customPricing, err
 			}
@@ -82,7 +82,7 @@ func (pc *ProviderConfig) loadConfig(writeIfNotExists bool) (*CustomPricing, err
 	}
 
 	var customPricing CustomPricing
-	err = json.Unmarshal(byteValue, &customPricing)
+	err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(byteValue, &customPricing)
 	if err != nil {
 		klog.Infof("Could not decode Custom Pricing file at path %s", pc.configPath)
 		return DefaultPricing(), err
@@ -123,7 +123,7 @@ func (pc *ProviderConfig) Update(updateFunc func(*CustomPricing) error) (*Custom
 	// Cache Update (possible the ptr already references the cached value)
 	pc.customPricing = c
 
-	cj, err := json.Marshal(c)
+	cj, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(c)
 	if err != nil {
 		return c, err
 	}

+ 4 - 4
pkg/clustermanager/clustermanager.go

@@ -2,7 +2,6 @@ package clustermanager
 
 import (
 	"encoding/base64"
-	"encoding/json"
 	"fmt"
 	"io/ioutil"
 	"strings"
@@ -13,6 +12,7 @@ import (
 
 	"k8s.io/klog"
 	"sigs.k8s.io/yaml"
+	jsoniter "github.com/json-iterator/go"
 )
 
 // The details key used to provide auth information
@@ -140,7 +140,7 @@ func (cm *ClusterManager) Add(cluster ClusterDefinition) (*ClusterDefinition, er
 		cluster.ID = uuid.New().String()
 	}
 
-	data, err := json.Marshal(cluster)
+	data, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(cluster)
 	if err != nil {
 		return nil, err
 	}
@@ -159,7 +159,7 @@ func (cm *ClusterManager) AddOrUpdate(cluster ClusterDefinition) (*ClusterDefini
 		cluster.ID = uuid.New().String()
 	}
 
-	data, err := json.Marshal(cluster)
+	data, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(cluster)
 	if err != nil {
 		return nil, err
 	}
@@ -181,7 +181,7 @@ func (cm *ClusterManager) GetAll() []*ClusterDefinition {
 
 	err := cm.storage.Each(func(key string, cluster []byte) error {
 		var cd ClusterDefinition
-		err := json.Unmarshal(cluster, &cd)
+		err := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(cluster, &cd)
 		if err != nil {
 			klog.V(1).Infof("[Error] Failed to unmarshal json cluster definition for key: %s", key)
 			return nil

+ 4 - 4
pkg/clustermanager/clustersendpoints.go

@@ -1,7 +1,6 @@
 package clustermanager
 
 import (
-	"encoding/json"
 	"errors"
 	"io/ioutil"
 	"net/http"
@@ -9,6 +8,7 @@ import (
 	"github.com/julienschmidt/httprouter"
 
 	"k8s.io/klog"
+	jsoniter "github.com/json-iterator/go"
 )
 
 // DataEnvelope is a generic wrapper struct for http response data
@@ -47,7 +47,7 @@ func (cme *ClusterManagerEndpoints) PutCluster(w http.ResponseWriter, r *http.Re
 	}
 
 	var clusterDef ClusterDefinition
-	err = json.Unmarshal(data, &clusterDef)
+	err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(data, &clusterDef)
 	if err != nil {
 		w.Write(wrapData(nil, err))
 		return
@@ -86,13 +86,13 @@ func wrapData(data interface{}, err error) []byte {
 
 	if err != nil {
 		klog.V(1).Infof("Error returned to client: %s", err.Error())
-		resp, _ = json.Marshal(&DataEnvelope{
+		resp, _ = jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(&DataEnvelope{
 			Code:   http.StatusInternalServerError,
 			Status: "error",
 			Data:   err.Error(),
 		})
 	} else {
-		resp, _ = json.Marshal(&DataEnvelope{
+		resp, _ = jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(&DataEnvelope{
 			Code:   http.StatusOK,
 			Status: "success",
 			Data:   data,

+ 2 - 2
pkg/costmodel/aggregation.go

@@ -1,7 +1,6 @@
 package costmodel
 
 import (
-	"encoding/json"
 	"fmt"
 	"math"
 	"net/http"
@@ -23,6 +22,7 @@ import (
 	"github.com/patrickmn/go-cache"
 	prometheusClient "github.com/prometheus/client_golang/api"
 	"k8s.io/klog"
+	jsoniter "github.com/json-iterator/go"
 )
 
 const (
@@ -2130,7 +2130,7 @@ func WriteError(w http.ResponseWriter, err Error) {
 	}
 	w.WriteHeader(status)
 
-	resp, _ := json.Marshal(&Response{
+	resp, _ := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(&Response{
 		Code:    status,
 		Message: fmt.Sprintf("Error: %s", err.Body),
 	})

+ 9 - 9
pkg/costmodel/router.go

@@ -2,7 +2,6 @@ package costmodel
 
 import (
 	"context"
-	"encoding/json"
 	"flag"
 	"fmt"
 	"net/http"
@@ -39,6 +38,7 @@ import (
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/rest"
 	"k8s.io/client-go/tools/clientcmd"
+	jsoniter "github.com/json-iterator/go"
 )
 
 const (
@@ -308,14 +308,14 @@ func WrapData(data interface{}, err error) []byte {
 
 	if err != nil {
 		klog.V(1).Infof("Error returned to client: %s", err.Error())
-		resp, _ = json.Marshal(&Response{
+		resp, _ = jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(&Response{
 			Code:    http.StatusInternalServerError,
 			Status:  "error",
 			Message: err.Error(),
 			Data:    data,
 		})
 	} else {
-		resp, _ = json.Marshal(&Response{
+		resp, _ = jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(&Response{
 			Code:   http.StatusOK,
 			Status: "success",
 			Data:   data,
@@ -330,14 +330,14 @@ func WrapDataWithMessage(data interface{}, err error, message string) []byte {
 
 	if err != nil {
 		klog.V(1).Infof("Error returned to client: %s", err.Error())
-		resp, _ = json.Marshal(&Response{
+		resp, _ = jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(&Response{
 			Code:    http.StatusInternalServerError,
 			Status:  "error",
 			Message: err.Error(),
 			Data:    data,
 		})
 	} else {
-		resp, _ = json.Marshal(&Response{
+		resp, _ = jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(&Response{
 			Code:    http.StatusOK,
 			Status:  "success",
 			Data:    data,
@@ -353,7 +353,7 @@ func WrapDataWithWarning(data interface{}, err error, warning string) []byte {
 
 	if err != nil {
 		klog.V(1).Infof("Error returned to client: %s", err.Error())
-		resp, _ = json.Marshal(&Response{
+		resp, _ = jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(&Response{
 			Code:    http.StatusInternalServerError,
 			Status:  "error",
 			Message: err.Error(),
@@ -361,7 +361,7 @@ func WrapDataWithWarning(data interface{}, err error, warning string) []byte {
 			Data:    data,
 		})
 	} else {
-		resp, _ = json.Marshal(&Response{
+		resp, _ = jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(&Response{
 			Code:    http.StatusOK,
 			Status:  "success",
 			Data:    data,
@@ -377,7 +377,7 @@ func WrapDataWithMessageAndWarning(data interface{}, err error, message, warning
 
 	if err != nil {
 		klog.V(1).Infof("Error returned to client: %s", err.Error())
-		resp, _ = json.Marshal(&Response{
+		resp, _ = jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(&Response{
 			Code:    http.StatusInternalServerError,
 			Status:  "error",
 			Message: err.Error(),
@@ -385,7 +385,7 @@ func WrapDataWithMessageAndWarning(data interface{}, err error, message, warning
 			Data:    data,
 		})
 	} else {
-		resp, _ = json.Marshal(&Response{
+		resp, _ = jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(&Response{
 			Code:    http.StatusOK,
 			Status:  "success",
 			Data:    data,

+ 2 - 2
pkg/costmodel/sql.go

@@ -2,7 +2,6 @@ package costmodel
 
 import (
 	"database/sql"
-	"encoding/json"
 	"fmt"
 	"time"
 
@@ -13,6 +12,7 @@ import (
 	"github.com/kubecost/cost-model/pkg/util"
 
 	_ "github.com/lib/pq"
+	jsoniter "github.com/json-iterator/go"
 )
 
 func getPVCosts(db *sql.DB) (map[string]*costAnalyzerCloud.PV, error) {
@@ -280,7 +280,7 @@ func CostDataRangeFromSQL(field string, value string, window string, start strin
 		}
 
 		var dat map[string]string
-		err := json.Unmarshal([]byte(result[4]), &dat)
+		err := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal([]byte(result[4]), &dat)
 		if err != nil {
 			return nil, err
 		}

+ 4 - 4
pkg/kubecost/allocation.go

@@ -2,7 +2,6 @@ package kubecost
 
 import (
 	"bytes"
-	"encoding/json"
 	"fmt"
 	"sort"
 	"strings"
@@ -11,6 +10,7 @@ import (
 
 	"github.com/kubecost/cost-model/pkg/log"
 	"github.com/kubecost/cost-model/pkg/util"
+	jsoniter "github.com/json-iterator/go"
 )
 
 // TODO Clean-up use of IsEmpty; nil checks should be separated for safety.
@@ -257,7 +257,7 @@ func (a *Allocation) PVBytes() float64 {
 	return a.PVByteHours / (a.Minutes() / 60.0)
 }
 
-// MarshalJSON implements json.Marshal interface
+// MarshalJSON implements jsoniter.ConfigCompatibleWithStandardLibrary.Marshal interface
 func (a *Allocation) MarshalJSON() ([]byte, error) {
 	buffer := bytes.NewBufferString("{")
 	jsonEncodeString(buffer, "name", a.Name, ",")
@@ -1659,7 +1659,7 @@ func (as *AllocationSet) Map() map[string]*Allocation {
 func (as *AllocationSet) MarshalJSON() ([]byte, error) {
 	as.RLock()
 	defer as.RUnlock()
-	return json.Marshal(as.allocations)
+	return jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(as.allocations)
 }
 
 // Resolution returns the AllocationSet's window duration
@@ -1946,7 +1946,7 @@ func (asr *AllocationSetRange) Length() int {
 func (asr *AllocationSetRange) MarshalJSON() ([]byte, error) {
 	asr.RLock()
 	asr.RUnlock()
-	return json.Marshal(asr.allocations)
+	return jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(asr.allocations)
 }
 
 // Slice copies the underlying slice of AllocationSets, maintaining order,

+ 3 - 2
pkg/kubecost/asset.go

@@ -10,6 +10,7 @@ import (
 	"time"
 
 	"github.com/kubecost/cost-model/pkg/log"
+	jsoniter "github.com/json-iterator/go"
 )
 
 const timeFmt = "2006-01-02T15:04:05-0700"
@@ -2792,7 +2793,7 @@ func (as *AssetSet) Map() map[string]Asset {
 func (as *AssetSet) MarshalJSON() ([]byte, error) {
 	as.RLock()
 	defer as.RUnlock()
-	return json.Marshal(as.assets)
+	return jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(as.assets)
 }
 
 func (as *AssetSet) Set(asset Asset, aggregateBy []string) error {
@@ -2992,7 +2993,7 @@ func (asr *AssetSetRange) Length() int {
 func (asr *AssetSetRange) MarshalJSON() ([]byte, error) {
 	asr.RLock()
 	asr.RUnlock()
-	return json.Marshal(asr.assets)
+	return jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(asr.assets)
 }
 
 func (asr *AssetSetRange) UTCOffset() time.Duration {

+ 2 - 2
pkg/kubecost/json.go

@@ -2,9 +2,9 @@ package kubecost
 
 import (
 	"bytes"
-	"encoding/json"
 	"fmt"
 	"math"
+	jsoniter "github.com/json-iterator/go"
 )
 
 // TODO move everything below to a separate package
@@ -26,7 +26,7 @@ func jsonEncodeString(buffer *bytes.Buffer, name, val, comma string) {
 
 func jsonEncode(buffer *bytes.Buffer, name string, obj interface{}, comma string) {
 	buffer.WriteString(fmt.Sprintf("\"%s\":", name))
-	if bytes, err := json.Marshal(obj); err != nil {
+	if bytes, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(obj); err != nil {
 		buffer.WriteString("null")
 	} else {
 		buffer.Write(bytes)

+ 4 - 3
pkg/prom/metrics.go

@@ -1,12 +1,13 @@
 package prom
 
 import (
-	"encoding/json"
 	"fmt"
 	"reflect"
 	"regexp"
 	"sort"
 	"strings"
+
+	jsoniter "github.com/json-iterator/go"
 )
 
 var invalidLabelCharRE = regexp.MustCompile(`[^a-zA-Z0-9_]`)
@@ -20,13 +21,13 @@ func AnyToLabels(a interface{}) (map[string]string, error) {
 		return MapToLabels(a), nil
 	}
 
-	b, e := json.Marshal(a)
+	b, e := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(a)
 	if e != nil {
 		return nil, e
 	}
 
 	var m map[string]interface{}
-	e = json.Unmarshal(b, &m)
+	e = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(b, &m)
 	if e != nil {
 		return nil, e
 	}

+ 3 - 3
pkg/prom/query.go

@@ -2,7 +2,6 @@ package prom
 
 import (
 	"context"
-	"encoding/json"
 	"fmt"
 	"net/http"
 	"net/url"
@@ -13,6 +12,7 @@ import (
 	"github.com/kubecost/cost-model/pkg/log"
 	"github.com/kubecost/cost-model/pkg/util"
 	prometheus "github.com/prometheus/client_golang/api"
+	jsoniter "github.com/json-iterator/go"
 )
 
 const (
@@ -188,7 +188,7 @@ func (ctx *Context) query(query string) (interface{}, prometheus.Warnings, error
 	}
 
 	var toReturn interface{}
-	err = json.Unmarshal(body, &toReturn)
+	err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(body, &toReturn)
 	if err != nil {
 		return nil, warnings, fmt.Errorf("query error: '%s' fetching query '%s'", err.Error(), query)
 	}
@@ -291,7 +291,7 @@ func (ctx *Context) queryRange(query string, start, end time.Time, step time.Dur
 	}
 
 	var toReturn interface{}
-	err = json.Unmarshal(body, &toReturn)
+	err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(body, &toReturn)
 	if err != nil {
 		return nil, warnings, fmt.Errorf("%d (%s) Headers: %s Error: %s Body: %s Query: %s", statusCode, statusText, util.HeaderString(resp.Header), err.Error(), body, query)
 	}