// Package gcp calls the GCP metrics api to return data // about metric samples and logs ingested for edge clusters. package gcp import ( "context" "fmt" monitoring "cloud.google.com/go/monitoring/apiv3/v2" monitoringpb "cloud.google.com/go/monitoring/apiv3/v2/monitoringpb" "google.golang.org/api/iterator" ) // GetMetricSamples uses the write_sample_count metric from // the MetricIngestionAttribution resource to determine the // number of metric samples can be attributed to a given // cluster id. // // ref: https://cloud.google.com/stackdriver/docs/managed-prometheus/cost-controls func GetMetricSamples(scopingProject string, clusterID string, interval string) (int64, error) { ctx := context.Background() client, err := monitoring.NewQueryClient(ctx) if err != nil { return 0.0, fmt.Errorf("NewQueryClient for metrics: %v", err) } defer client.Close() query := "fetch monitoring.googleapis.com/MetricIngestionAttribution" + " | metric 'monitoring.googleapis.com/collection/attribution/write_sample_count'" + " | filter (resource.attribution_dimension == 'cluster' && resource.attribution_id == \"" + clusterID + "\")" + " | group_by " + interval + ", [samples_agg: aggregate(value.write_sample_count)]" + " | every 5m " + " | group_by [resource.attribution_id, resource.resource_container] " req := &monitoringpb.QueryTimeSeriesRequest{ Name: "projects/" + scopingProject, Query: query, } var bytes int64 it := client.QueryTimeSeries(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { return 0, fmt.Errorf("could not read time series value: %v", err) } if len(resp.GetPointData()) > 0 { bytes = resp.GetPointData()[0].GetValues()[0].GetInt64Value() } } return bytes, nil } // GetLogBytes uses the byte_count to deterine the number of // log bytes ingested can be attributed to a given cluster id. func GetLogBytes(scopingProject string, clusterID string, interval string, logType string) (int64, error) { ctx := context.Background() client, err := monitoring.NewQueryClient(ctx) if err != nil { return 0.0, fmt.Errorf("NewQueryClient for logs: %v", err) } defer client.Close() query := "fetch " + logType + "| metric 'logging.googleapis.com/byte_count'" + "| filter (resource.project_id == \"" + scopingProject + "\" && resource.cluster_name == \"" + clusterID + "\")" + "| group_by " + interval + ", [byte_count_agg:aggregate(value.byte_count)]" + "| every 5m" + "| group_by [resource.cluster_name], [aggregate(byte_count_agg)]" req := &monitoringpb.QueryTimeSeriesRequest{ Name: "projects/" + scopingProject, Query: query, } var bytes int64 it := client.QueryTimeSeries(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { return 0, fmt.Errorf("could not read time series value: %v", err) } if len(resp.GetPointData()) > 0 { bytes = resp.GetPointData()[0].GetValues()[0].GetInt64Value() } } return bytes, nil }