AjayTripathy 7 лет назад
Родитель
Сommit
1f0b23399a
6 измененных файлов с 61 добавлено и 53 удалено
  1. 17 16
      cloud/awsprovider.go
  2. 8 7
      cloud/gcpprovider.go
  3. 6 5
      cloud/provider.go
  4. 15 16
      costmodel/costmodel.go
  5. 1 0
      go.mod
  6. 14 9
      main.go

+ 17 - 16
cloud/awsprovider.go

@@ -5,7 +5,6 @@ import (
 	"fmt"
 	"io"
 	"io/ioutil"
-	"log"
 	"net/http"
 	"net/url"
 	"os"
@@ -13,6 +12,8 @@ import (
 	"strings"
 	"time"
 
+	"k8s.io/klog"
+
 	"github.com/aws/aws-sdk-go/aws"
 	"github.com/aws/aws-sdk-go/aws/awserr"
 	"github.com/aws/aws-sdk-go/aws/credentials"
@@ -179,10 +180,10 @@ func (aws *AWS) DownloadPricingData() error {
 	skusToKeys := make(map[string]string)
 
 	pricingURL := "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/current/index.json"
-	log.Printf("starting download of \"%s\", which is quite large ...", pricingURL)
+	klog.V(2).Infof("starting download of \"%s\", which is quite large ...", pricingURL)
 	resp, err := http.Get(pricingURL)
 	if err != nil {
-		log.Printf("Bogus fetch of \"%s\": %v", pricingURL, err)
+		klog.V(2).Infof("Bogus fetch of \"%s\": %v", pricingURL, err)
 		return err
 	}
 
@@ -190,7 +191,7 @@ func (aws *AWS) DownloadPricingData() error {
 	for {
 		t, err := dec.Token()
 		if err == io.EOF {
-			log.Printf("done loading \"%s\"\n", pricingURL)
+			klog.V(2).Infof("done loading \"%s\"\n", pricingURL)
 			break
 		}
 		if t == "products" {
@@ -201,7 +202,7 @@ func (aws *AWS) DownloadPricingData() error {
 				err := dec.Decode(&product)
 
 				if err != nil {
-					log.Printf("Error parsing response from \"%s\": %v", pricingURL, err.Error())
+					klog.V(1).Infof("Error parsing response from \"%s\": %v", pricingURL, err.Error())
 					break
 				}
 				if product.Attributes.PreInstalledSw == "NA" &&
@@ -236,7 +237,7 @@ func (aws *AWS) DownloadPricingData() error {
 					offerTerm := &AWSOfferTerm{}
 					err := dec.Decode(&offerTerm)
 					if err != nil {
-						log.Printf("Error decoding AWS Offer Term: " + err.Error())
+						klog.V(1).Infof("Error decoding AWS Offer Term: " + err.Error())
 					}
 					if sku.(string)+OnDemandRateCode == skuOnDemand {
 						key, ok := skusToKeys[sku.(string)]
@@ -258,7 +259,7 @@ func (aws *AWS) DownloadPricingData() error {
 	}
 	c, err := GetDefaultPricingData("aws.json")
 	if err != nil {
-		log.Printf("Error downloading default pricing data: %s", err.Error())
+		klog.V(1).Infof("Error downloading default pricing data: %s", err.Error())
 	}
 	aws.BaseCPUPrice = c.CPU
 	aws.BaseSpotCPUPrice = c.SpotCPU
@@ -340,7 +341,7 @@ func (aws *AWS) NodePricing(key string) (*Node, error) {
 func (awsProvider *AWS) ClusterName() ([]byte, error) {
 	defaultClusterName := "AWS Cluster #1"
 	makeStructure := func(clusterName string) ([]byte, error) {
-		log.Printf("Returning \"%s\" as ClusterName", clusterName)
+		klog.V(2).Infof("Returning \"%s\" as ClusterName", clusterName)
 		m := make(map[string]string)
 		m["name"] = clusterName
 		m["provider"] = "AWS"
@@ -369,7 +370,7 @@ func (awsProvider *AWS) ClusterName() ([]byte, error) {
 			}
 		}
 		if len(instanceId) == 0 {
-			log.Printf("Unable to decode Node.ProviderID \"%s\", skipping it", providerId)
+			klog.V(2).Infof("Unable to decode Node.ProviderID \"%s\", skipping it", providerId)
 			continue
 		}
 		c := &aws.Config{
@@ -387,12 +388,12 @@ func (awsProvider *AWS) ClusterName() ([]byte, error) {
 			continue
 		}
 		if len(di.Reservations) != 1 {
-			log.Printf("Expected 1 Reservation back from DescribeInstances(%s), received %d", instanceId, len(di.Reservations))
+			klog.V(2).Infof("Expected 1 Reservation back from DescribeInstances(%s), received %d", instanceId, len(di.Reservations))
 			continue
 		}
 		res := di.Reservations[0]
 		if len(res.Instances) != 1 {
-			log.Printf("Expected 1 Instance back from DescribeInstances(%s), received %d", instanceId, len(res.Instances))
+			klog.V(2).Infof("Expected 1 Instance back from DescribeInstances(%s), received %d", instanceId, len(res.Instances))
 			continue
 		}
 		inst := res.Instances[0]
@@ -406,7 +407,7 @@ func (awsProvider *AWS) ClusterName() ([]byte, error) {
 			}
 		}
 	}
-	log.Printf("Unable to sniff out cluster ID, perhaps set $%s to force one", ClusterIdEnvVar)
+	klog.V(2).Infof("Unable to sniff out cluster ID, perhaps set $%s to force one", ClusterIdEnvVar)
 	return makeStructure(defaultClusterName)
 }
 
@@ -434,7 +435,7 @@ func (*AWS) GetDisks() ([]byte, error) {
 		os.Setenv("AWS_ACCESS_KEY_ID", result["access_key_ID"])
 		os.Setenv("AWS_SECRET_ACCESS_KEY", result["secret_access_key"])
 	} else if os.IsNotExist(err) {
-		log.Print("Using Default Credentials")
+		klog.V(2).Infof("Using Default Credentials")
 	} else {
 		return nil, err
 	}
@@ -482,7 +483,7 @@ func (*AWS) QuerySQL(query string) ([]byte, error) {
 		os.Setenv("AWS_ACCESS_KEY_ID", result["access_key_ID"])
 		os.Setenv("AWS_SECRET_ACCESS_KEY", result["secret_access_key"])
 	} else if os.IsNotExist(err) {
-		log.Print("Using Default Credentials")
+		klog.V(2).Infof("Using Default Credentials")
 	} else {
 		return nil, err
 	}
@@ -522,8 +523,8 @@ func (*AWS) QuerySQL(query string) ([]byte, error) {
 		return nil, err
 	}
 
-	log.Println("StartQueryExecution result:")
-	log.Println(res.GoString())
+	klog.V(2).Infof("StartQueryExecution result:")
+	klog.V(2).Infof(res.GoString())
 
 	var qri athena.GetQueryExecutionInput
 	qri.SetQueryExecutionId(*res.QueryExecutionId)

+ 8 - 7
cloud/gcpprovider.go

@@ -5,13 +5,14 @@ import (
 	"fmt"
 	"io"
 	"io/ioutil"
-	"log"
 	"math"
 	"net/http"
 	"net/url"
 	"strconv"
 	"strings"
 
+	"k8s.io/klog"
+
 	"cloud.google.com/go/compute/metadata"
 	"golang.org/x/oauth2"
 	"golang.org/x/oauth2/google"
@@ -201,7 +202,7 @@ func (gcp *GCP) parsePage(r io.Reader, inputKeys map[string]bool) (map[string]*G
 							continue
 						} else if strings.Contains(strings.ToUpper(product.Description), "RAM") {
 							if instanceType == "custom" {
-								log.Printf("RAM custom sku is: " + product.Name)
+								klog.V(2).Infof("RAM custom sku is: " + product.Name)
 							}
 							if _, ok := gcpPricingList[candidateKey]; ok {
 								gcpPricingList[candidateKey].Node.RAMCost = strconv.FormatFloat(hourlyPrice, 'f', -1, 64)
@@ -238,7 +239,7 @@ func (gcp *GCP) parsePage(r io.Reader, inputKeys map[string]bool) (map[string]*G
 		if t == "nextPageToken" {
 			pageToken, err := dec.Token()
 			if err != nil {
-				log.Printf("Error parsing nextpage token: " + err.Error())
+				klog.V(2).Infof("Error parsing nextpage token: " + err.Error())
 				break
 			}
 			if pageToken.(string) != "" {
@@ -254,7 +255,7 @@ func (gcp *GCP) parsePage(r io.Reader, inputKeys map[string]bool) (map[string]*G
 func (gcp *GCP) parsePages(inputKeys map[string]bool) (map[string]*GCPPricing, error) {
 	var pages []map[string]*GCPPricing
 	url := "https://cloudbilling.googleapis.com/v1/services/6F81-5844-456A/skus?key=" + gcp.APIKey //AIzaSyDXQPG_MHUEy9neR7stolq6l0ujXmjJlvk
-	log.Printf("URL: %s", url)
+	klog.V(2).Infof("URL: %s", url)
 	var parsePagesHelper func(string) error
 	parsePagesHelper = func(pageToken string) error {
 		if pageToken == "done" {
@@ -313,7 +314,7 @@ func (gcp *GCP) DownloadPricingData() error {
 	gcp.Pricing = pages
 	c, err := GetDefaultPricingData("default.json")
 	if err != nil {
-		log.Printf("Error downloading default pricing data: %s", err.Error())
+		klog.V(2).Infof("Error downloading default pricing data: %s", err.Error())
 	}
 	gcp.BaseCPUPrice = c.CPU
 
@@ -347,10 +348,10 @@ func (gcp *GCP) AllNodePricing() (interface{}, error) {
 // NodePricing returns GCP pricing data for a single node
 func (gcp *GCP) NodePricing(key string) (*Node, error) {
 	if n, ok := gcp.Pricing[key]; ok {
-		log.Printf("Returning pricing for node %s: %+v from SKU %s", key, n.Node, n.Name)
+		klog.V(2).Infof("Returning pricing for node %s: %+v from SKU %s", key, n.Node, n.Name)
 		n.Node.BaseCPUPrice = gcp.BaseCPUPrice
 		return n.Node, nil
 	}
-	log.Printf("Warning: no pricing data found for %s", key)
+	klog.V(1).Infof("Warning: no pricing data found for %s", key)
 	return nil, fmt.Errorf("Warning: no pricing data found for %s", key)
 }

+ 6 - 5
cloud/provider.go

@@ -4,11 +4,12 @@ import (
 	"encoding/json"
 	"errors"
 	"io/ioutil"
-	"log"
 	"net/url"
 	"os"
 	"strings"
 
+	"k8s.io/klog"
+
 	"cloud.google.com/go/compute/metadata"
 
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -147,7 +148,7 @@ func (*CustomProvider) QuerySQL(query string) ([]byte, error) {
 // NewProvider looks at the nodespec or provider metadata server to decide which provider to instantiate.
 func NewProvider(clientset *kubernetes.Clientset, apiKey string) (Provider, error) {
 	if metadata.OnGCE() {
-		log.Print("metadata reports we are in GCE")
+		klog.V(3).Info("metadata reports we are in GCE")
 		if apiKey == "" {
 			return nil, errors.New("Supply a GCP Key to start getting data")
 		}
@@ -162,19 +163,19 @@ func NewProvider(clientset *kubernetes.Clientset, apiKey string) (Provider, erro
 	}
 	provider := strings.ToLower(nodes.Items[0].Spec.ProviderID)
 	if strings.HasPrefix(provider, "aws") {
-		log.Print("Found ProviderID starting with \"aws\", using AWS Provider")
+		klog.V(3).Info("Found ProviderID starting with \"aws\", using AWS Provider")
 		return &AWS{
 			Clientset: clientset,
 		}, nil
 	} else if strings.HasPrefix(provider, "azure") {
-		log.Print("Found ProviderID starting with \"azure\", using Azure Provider")
+		klog.V(3).Info("Found ProviderID starting with \"azure\", using Azure Provider")
 		return &Azure{
 			CustomProvider: &CustomProvider{
 				Clientset: clientset,
 			},
 		}, nil
 	} else {
-		log.Print("Unsupported provider, falling back to default")
+		klog.V(3).Info("Unsupported provider, falling back to default")
 		return &CustomProvider{
 			Clientset: clientset,
 		}, nil

+ 15 - 16
costmodel/costmodel.go

@@ -4,7 +4,6 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
-	"log"
 	"math"
 	"net/http"
 	"sort"
@@ -17,6 +16,7 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/labels"
 	"k8s.io/client-go/kubernetes"
+	"k8s.io/klog"
 )
 
 const (
@@ -108,7 +108,7 @@ func ComputeCostData(cli prometheusClient.Client, clientset *kubernetes.Clientse
 
 	nodes, err := getNodeCost(clientset, cloud)
 	if err != nil {
-		log.Printf("Warning, no Node cost model available: " + err.Error())
+		klog.V(1).Infof("Warning, no Node cost model available: " + err.Error())
 		return nil, err
 	}
 
@@ -292,7 +292,7 @@ func getNodeCost(clientset *kubernetes.Clientset, cloud costAnalyzerCloud.Provid
 		nodeLabels := n.GetObjectMeta().GetLabels()
 		cnode, err := cloud.NodePricing(cloud.GetKey(nodeLabels))
 		if err != nil {
-			log.Printf("Error getting node. Error: " + err.Error())
+			klog.V(1).Infof("Error getting node. Error: " + err.Error())
 			continue
 		}
 
@@ -313,10 +313,10 @@ func getNodeCost(clientset *kubernetes.Clientset, cloud costAnalyzerCloud.Provid
 			totalCPUPrice := basePrice * cpu
 			var nodePrice float64
 			if cnode.Cost != "" {
-				log.Print("Use given nodeprice as whole node price")
+				klog.V(3).Infof("Use given nodeprice as whole node price")
 				nodePrice, _ = strconv.ParseFloat(cnode.Cost, 64)
 			} else {
-				log.Print("Use cpuprice as whole node price")
+				klog.V(3).Infof("Use cpuprice as whole node price")
 				nodePrice, _ = strconv.ParseFloat(cnode.VCPUCost, 64) // all the price was allocated the the CPU
 			}
 			if totalCPUPrice >= nodePrice {
@@ -328,7 +328,7 @@ func getNodeCost(clientset *kubernetes.Clientset, cloud costAnalyzerCloud.Provid
 			cnode.VCPUCost = fmt.Sprintf("%f", cpuPrice)
 			cnode.RAMCost = fmt.Sprintf("%f", ramPrice)
 			cnode.RAMBytes = fmt.Sprintf("%f", ram)
-			log.Printf("Node \"%s\" RAM Cost := %v", name, cnode.RAMCost)
+			klog.V(2).Infof("Node \"%s\" RAM Cost := %v", name, cnode.RAMCost)
 		}
 		nodes[name] = cnode
 	}
@@ -350,7 +350,7 @@ func getPodServices(clientset *kubernetes.Clientset, podList *v1.PodList) (map[s
 		}
 		s := labels.Set(service.Spec.Selector).AsSelectorPreValidated()
 		if err != nil {
-			log.Printf("Error doing service label conversion: " + err.Error())
+			klog.V(2).Infof("Error doing service label conversion: " + err.Error())
 		}
 		for _, pod := range podList.Items {
 			labelSet := labels.Set(pod.GetObjectMeta().GetLabels())
@@ -381,7 +381,7 @@ func getPodDeployments(clientset *kubernetes.Clientset, podList *v1.PodList) (ma
 		}
 		s, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector)
 		if err != nil {
-			log.Printf("Error doing deployment label conversion: " + err.Error())
+			klog.V(2).Infof("Error doing deployment label conversion: " + err.Error())
 		}
 		for _, pod := range podList.Items {
 			labelSet := labels.Set(pod.GetObjectMeta().GetLabels())
@@ -412,17 +412,17 @@ func ComputeCostDataRange(cli prometheusClient.Client, clientset *kubernetes.Cli
 
 	start, err := time.Parse(layout, startString)
 	if err != nil {
-		log.Printf("Error parsing time " + startString + ". Error: " + err.Error())
+		klog.V(1).Infof("Error parsing time " + startString + ". Error: " + err.Error())
 		return nil, err
 	}
 	end, err := time.Parse(layout, endString)
 	if err != nil {
-		log.Printf("Error parsing time " + endString + ". Error: " + err.Error())
+		klog.V(1).Infof("Error parsing time " + endString + ". Error: " + err.Error())
 		return nil, err
 	}
 	window, err := time.ParseDuration(windowString)
 	if err != nil {
-		log.Printf("Error parsing time " + windowString + ". Error: " + err.Error())
+		klog.V(1).Infof("Error parsing time " + windowString + ". Error: " + err.Error())
 		return nil, err
 	}
 	resultRAMRequests, err := queryRange(cli, queryRAMRequests, start, end, window)
@@ -462,7 +462,7 @@ func ComputeCostDataRange(cli prometheusClient.Client, clientset *kubernetes.Cli
 	nodes, err := getNodeCost(clientset, cloud)
 	if err != nil {
 		//return nil, err
-		log.Printf("Warning, no cost model available: " + err.Error())
+		klog.V(1).Infof("Warning, no cost model available: " + err.Error())
 	}
 
 	podlist, err := clientset.CoreV1().Pods("").List(metav1.ListOptions{})
@@ -675,7 +675,6 @@ func getPVInfoVectors(qr interface{}) (map[string]*PersistentVolumeData, error)
 
 func getPVInfoVector(qr interface{}) (map[string]*PersistentVolumeData, error) {
 	pvmap := make(map[string]*PersistentVolumeData)
-	log.Printf("Interface %v. If the interface is nil, prometheus is not running!", qr)
 	for _, val := range qr.(map[string]interface{})["data"].(map[string]interface{})["result"].([]interface{}) {
 		metricInterface, ok := val.(map[string]interface{})["metric"]
 		if !ok {
@@ -732,7 +731,7 @@ func queryRange(cli prometheusClient.Client, query string, start, end time.Time,
 
 	_, body, err := cli.Do(context.Background(), req)
 	if err != nil {
-		log.Print("ERROR" + err.Error())
+		klog.V(1).Infof("ERROR" + err.Error())
 	}
 	if err != nil {
 		return nil, err
@@ -740,7 +739,7 @@ func queryRange(cli prometheusClient.Client, query string, start, end time.Time,
 	var toReturn interface{}
 	err = json.Unmarshal(body, &toReturn)
 	if err != nil {
-		log.Print("ERROR" + err.Error())
+		klog.V(1).Infof("ERROR" + err.Error())
 	}
 	return toReturn, err
 }
@@ -763,7 +762,7 @@ func query(cli prometheusClient.Client, query string) (interface{}, error) {
 	var toReturn interface{}
 	err = json.Unmarshal(body, &toReturn)
 	if err != nil {
-		log.Print("ERROR" + err.Error())
+		klog.V(1).Infof("ERROR" + err.Error())
 	}
 	return toReturn, err
 }

+ 1 - 0
go.mod

@@ -14,5 +14,6 @@ require (
 	k8s.io/api v0.0.0-20190404065945-709cf190c7b7
 	k8s.io/apimachinery v0.0.0-20190404065847-4a4abcd45006
 	k8s.io/client-go v0.0.0-20190404172613-2e1a3ed22ac5
+	k8s.io/klog v0.0.0-20190306015804-8e90cee79f82
 	k8s.io/utils v0.0.0-20190308190857-21c4ce38f2a7 // indirect
 )

+ 14 - 9
main.go

@@ -3,12 +3,14 @@ package main
 import (
 	"context"
 	"encoding/json"
-	"log"
+	"flag"
 	"net/http"
 	"os"
 	"strconv"
 	"time"
 
+	"k8s.io/klog"
+
 	"github.com/julienschmidt/httprouter"
 	costAnalyzerCloud "github.com/kubecost/cost-model/cloud"
 	costModel "github.com/kubecost/cost-model/costmodel"
@@ -100,10 +102,10 @@ func Healthz(w http.ResponseWriter, _ *http.Request, _ httprouter.Params) {
 func (a *Accesses) recordPrices() {
 	go func() {
 		for {
-			log.Print("Recording prices...")
+			klog.V(3).Info("Recording prices...")
 			data, err := costModel.ComputeCostData(a.PrometheusClient, a.KubeClientSet, a.Cloud, "1h")
 			if err != nil {
-				log.Printf("Error in price recording: " + err.Error())
+				klog.V(3).Info("Error in price recording: " + err.Error())
 				// zero the for loop so the time.Sleep will still work
 				data = map[string]*costModel.CostData{}
 			}
@@ -111,7 +113,7 @@ func (a *Accesses) recordPrices() {
 				nodeName := costs.NodeName
 				node := costs.NodeData
 				if node == nil {
-					log.Printf("Skipping Node \"%s\" due to missing Node Data costs", nodeName)
+					klog.V(3).Info("Skipping Node \"%s\" due to missing Node Data costs", nodeName)
 					continue
 				}
 				cpuCost, _ := strconv.ParseFloat(node.VCPUCost, 64)
@@ -131,10 +133,13 @@ func (a *Accesses) recordPrices() {
 }
 
 func main() {
+	klog.InitFlags(nil)
+	flag.Set("v", "3")
+	flag.Parse()
 
 	address := os.Getenv("PROMETHEUS_SERVER_ENDPOINT")
 	if address == "" {
-		log.Fatal("No address for prometheus set. Aborting.")
+		klog.Fatal("No address for prometheus set. Aborting.")
 	}
 
 	pc := prometheusClient.Config{
@@ -145,9 +150,9 @@ func main() {
 	api := prometheusAPI.NewAPI(promCli)
 	_, err := api.Config(context.Background())
 	if err != nil {
-		log.Fatal("Failed to use Prometheus at " + address + " Error: " + err.Error())
+		klog.Fatal("Failed to use Prometheus at " + address + " Error: " + err.Error())
 	}
-	log.Printf("Checked prometheus endpoint: " + address)
+	klog.V(1).Info("Checked prometheus endpoint: " + address)
 
 	// Kubernetes API setup
 	kc, err := rest.InClusterConfig()
@@ -195,7 +200,7 @@ func main() {
 
 	err = a.Cloud.DownloadPricingData()
 	if err != nil {
-		log.Printf("Failed to download pricing data: " + err.Error())
+		klog.V(1).Info("Failed to download pricing data: " + err.Error())
 	}
 
 	a.recordPrices()
@@ -210,5 +215,5 @@ func main() {
 	rootMux.Handle("/", router)
 	rootMux.Handle("/metrics", promhttp.Handler())
 
-	log.Fatal(http.ListenAndServe(":9003", rootMux))
+	klog.Fatal(http.ListenAndServe(":9003", rootMux))
 }