devtools: update tools to use monitoring v3 APIs.
MultiPart: 1/2
Change-Id: I6570b48beed533ba212bd5eb649cb8e7c6af050a
diff --git a/internal/monitoring/monitoring.go b/internal/monitoring/monitoring.go
index bc863e8..a5e096c 100644
--- a/internal/monitoring/monitoring.go
+++ b/internal/monitoring/monitoring.go
@@ -8,14 +8,15 @@
"fmt"
"io/ioutil"
"net/http"
+ "sort"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
- "google.golang.org/api/cloudmonitoring/v2beta2"
+ cloudmonitoring "google.golang.org/api/monitoring/v3"
)
const (
- customMetricPrefix = "custom.cloudmonitoring.googleapis.com"
+ customMetricPrefix = "custom.googleapis.com"
)
type ServiceLocation struct {
@@ -54,9 +55,9 @@
},
}
-// CustomMetricDescriptors is a map from metric's short names to their
+// customMetricDescriptors is a map from metric's short names to their
// MetricDescriptor definitions.
-var CustomMetricDescriptors = map[string]*cloudmonitoring.MetricDescriptor{
+var customMetricDescriptors = map[string]*cloudmonitoring.MetricDescriptor{
// Custom metrics for recording check latency and its aggregation
// of vanadium production services.
"service-latency": createMetric("service/latency", "The check latency (ms) of vanadium production services.", "double", true, nil),
@@ -66,13 +67,13 @@
// for a service.
"service-permethod-latency": createMetric("service/latency/method", "Service latency (ms) per method.", "double", true, []labelData{
labelData{
- key: "method-name",
+ key: "method_name",
description: "The method name",
},
}),
"service-permethod-latency-agg": createMetric("service/latency/method-agg", "Aggregated service latency (ms) per method.", "double", false, []labelData{
labelData{
- key: "method-name",
+ key: "method_name",
description: "The method name",
},
aggLabelData[0],
@@ -87,13 +88,13 @@
// of vanadium production services.
"service-metadata": createMetric("service/metadata", "Various metadata of vanadium production services.", "double", true, []labelData{
labelData{
- key: "metadata-name",
+ key: "metadata_name",
description: "The metadata name",
},
}),
"service-metadata-agg": createMetric("service/metadata-agg", "Aggregated metadata of vanadium production services.", "double", false, []labelData{
labelData{
- key: "metadata-name",
+ key: "metadata_name",
description: "The metadata name",
},
aggLabelData[0],
@@ -106,13 +107,13 @@
// Custom metric for recording per-method rpc qps for a service.
"service-qps-method": createMetric("service/qps/method", "Service QPS per method.", "double", true, []labelData{
labelData{
- key: "method-name",
+ key: "method_name",
description: "The method name",
},
}),
"service-qps-method-agg": createMetric("service/qps/method-agg", "Aggregated service QPS per method.", "double", false, []labelData{
labelData{
- key: "method-name",
+ key: "method_name",
description: "The method name",
},
aggLabelData[0],
@@ -132,40 +133,62 @@
}
func createMetric(metricType, description, valueType string, includeGCELabels bool, extraLabels []labelData) *cloudmonitoring.MetricDescriptor {
- labels := []*cloudmonitoring.MetricDescriptorLabelDescriptor{}
+ labels := []*cloudmonitoring.LabelDescriptor{}
if includeGCELabels {
- labels = append(labels, &cloudmonitoring.MetricDescriptorLabelDescriptor{
- Key: fmt.Sprintf("%s/gce-instance", customMetricPrefix),
+ labels = append(labels, &cloudmonitoring.LabelDescriptor{
+ Key: "gce_instance",
Description: "The name of the GCE instance associated with this metric.",
- }, &cloudmonitoring.MetricDescriptorLabelDescriptor{
- Key: fmt.Sprintf("%s/gce-zone", customMetricPrefix),
+ ValueType: "string",
+ }, &cloudmonitoring.LabelDescriptor{
+ Key: "gce_zone",
Description: "The zone of the GCE instance associated with this metric.",
+ ValueType: "string",
})
}
- labels = append(labels, &cloudmonitoring.MetricDescriptorLabelDescriptor{
- Key: fmt.Sprintf("%s/metric-name", customMetricPrefix),
+ labels = append(labels, &cloudmonitoring.LabelDescriptor{
+ Key: "metric_name",
Description: "The name of the metric.",
+ ValueType: "string",
})
if extraLabels != nil {
for _, data := range extraLabels {
- labels = append(labels, &cloudmonitoring.MetricDescriptorLabelDescriptor{
- Key: fmt.Sprintf("%s/%s", customMetricPrefix, data.key),
+ labels = append(labels, &cloudmonitoring.LabelDescriptor{
+ Key: fmt.Sprintf("%s", data.key),
Description: data.description,
+ ValueType: "string",
})
}
}
return &cloudmonitoring.MetricDescriptor{
- Name: fmt.Sprintf("%s/vanadium/%s", customMetricPrefix, metricType),
+ Type: fmt.Sprintf("%s/vanadium/%s", customMetricPrefix, metricType),
Description: description,
- TypeDescriptor: &cloudmonitoring.MetricDescriptorTypeDescriptor{
- MetricType: "gauge",
- ValueType: valueType,
- },
- Labels: labels,
+ MetricKind: "gauge",
+ ValueType: valueType,
+ Labels: labels,
}
}
+// GetMetric gets the custom metric descriptor with the given name and project.
+func GetMetric(name, project string) (*cloudmonitoring.MetricDescriptor, error) {
+ md, ok := customMetricDescriptors[name]
+ if !ok {
+ return nil, fmt.Errorf("metric %q doesn't exist", name)
+ }
+ md.Name = fmt.Sprintf("projects/%s/metricDescriptors/%s", project, md.Type)
+ return md, nil
+}
+
+// GetSortedMetricNames gets the sorted metric names.
+func GetSortedMetricNames() []string {
+ names := []string{}
+ for n := range customMetricDescriptors {
+ names = append(names, n)
+ }
+ sort.Strings(names)
+ return names
+}
+
func createClient(keyFilePath string) (*http.Client, error) {
if len(keyFilePath) > 0 {
data, err := ioutil.ReadFile(keyFilePath)
diff --git a/internal/monitoring/monitoring_test.go b/internal/monitoring/monitoring_test.go
index 9cef6b6..566cb96 100644
--- a/internal/monitoring/monitoring_test.go
+++ b/internal/monitoring/monitoring_test.go
@@ -9,7 +9,7 @@
"reflect"
"testing"
- "google.golang.org/api/cloudmonitoring/v2beta2"
+ cloudmonitoring "google.golang.org/api/monitoring/v3"
)
func TestCreateMetric(t *testing.T) {
@@ -29,16 +29,15 @@
includeGCELabels: false,
extraLabels: nil,
expectedMetric: &cloudmonitoring.MetricDescriptor{
- Name: fmt.Sprintf("%s/vanadium/test", customMetricPrefix),
+ Type: fmt.Sprintf("%s/vanadium/test", customMetricPrefix),
Description: "this is a test",
- TypeDescriptor: &cloudmonitoring.MetricDescriptorTypeDescriptor{
- MetricType: "gauge",
- ValueType: "double",
- },
- Labels: []*cloudmonitoring.MetricDescriptorLabelDescriptor{
- &cloudmonitoring.MetricDescriptorLabelDescriptor{
- Key: fmt.Sprintf("%s/metric-name", customMetricPrefix),
+ MetricKind: "gauge",
+ ValueType: "double",
+ Labels: []*cloudmonitoring.LabelDescriptor{
+ &cloudmonitoring.LabelDescriptor{
+ Key: "metric_name",
Description: "The name of the metric.",
+ ValueType: "string",
},
},
},
@@ -50,24 +49,25 @@
includeGCELabels: true,
extraLabels: nil,
expectedMetric: &cloudmonitoring.MetricDescriptor{
- Name: fmt.Sprintf("%s/vanadium/test2", customMetricPrefix),
+ Type: fmt.Sprintf("%s/vanadium/test2", customMetricPrefix),
Description: "this is a test2",
- TypeDescriptor: &cloudmonitoring.MetricDescriptorTypeDescriptor{
- MetricType: "gauge",
- ValueType: "string",
- },
- Labels: []*cloudmonitoring.MetricDescriptorLabelDescriptor{
- &cloudmonitoring.MetricDescriptorLabelDescriptor{
- Key: fmt.Sprintf("%s/gce-instance", customMetricPrefix),
+ MetricKind: "gauge",
+ ValueType: "string",
+ Labels: []*cloudmonitoring.LabelDescriptor{
+ &cloudmonitoring.LabelDescriptor{
+ Key: "gce_instance",
Description: "The name of the GCE instance associated with this metric.",
+ ValueType: "string",
},
- &cloudmonitoring.MetricDescriptorLabelDescriptor{
- Key: fmt.Sprintf("%s/gce-zone", customMetricPrefix),
+ &cloudmonitoring.LabelDescriptor{
+ Key: "gce_zone",
Description: "The zone of the GCE instance associated with this metric.",
+ ValueType: "string",
},
- &cloudmonitoring.MetricDescriptorLabelDescriptor{
- Key: fmt.Sprintf("%s/metric-name", customMetricPrefix),
+ &cloudmonitoring.LabelDescriptor{
+ Key: "metric_name",
Description: "The name of the metric.",
+ ValueType: "string",
},
},
},
@@ -84,28 +84,30 @@
},
},
expectedMetric: &cloudmonitoring.MetricDescriptor{
- Name: fmt.Sprintf("%s/vanadium/test3", customMetricPrefix),
+ Type: fmt.Sprintf("%s/vanadium/test3", customMetricPrefix),
Description: "this is a test3",
- TypeDescriptor: &cloudmonitoring.MetricDescriptorTypeDescriptor{
- MetricType: "gauge",
- ValueType: "double",
- },
- Labels: []*cloudmonitoring.MetricDescriptorLabelDescriptor{
- &cloudmonitoring.MetricDescriptorLabelDescriptor{
- Key: fmt.Sprintf("%s/gce-instance", customMetricPrefix),
+ MetricKind: "gauge",
+ ValueType: "double",
+ Labels: []*cloudmonitoring.LabelDescriptor{
+ &cloudmonitoring.LabelDescriptor{
+ Key: "gce_instance",
Description: "The name of the GCE instance associated with this metric.",
+ ValueType: "string",
},
- &cloudmonitoring.MetricDescriptorLabelDescriptor{
- Key: fmt.Sprintf("%s/gce-zone", customMetricPrefix),
+ &cloudmonitoring.LabelDescriptor{
+ Key: "gce_zone",
Description: "The zone of the GCE instance associated with this metric.",
+ ValueType: "string",
},
- &cloudmonitoring.MetricDescriptorLabelDescriptor{
- Key: fmt.Sprintf("%s/metric-name", customMetricPrefix),
+ &cloudmonitoring.LabelDescriptor{
+ Key: "metric_name",
Description: "The name of the metric.",
+ ValueType: "string",
},
- &cloudmonitoring.MetricDescriptorLabelDescriptor{
- Key: fmt.Sprintf("%s/extraLabel", customMetricPrefix),
+ &cloudmonitoring.LabelDescriptor{
+ Key: "extraLabel",
Description: "this is an extra label",
+ ValueType: "string",
},
},
},
diff --git a/jiri-test/internal/test/go.go b/jiri-test/internal/test/go.go
index 4b739b4..f9e4ebd 100644
--- a/jiri-test/internal/test/go.go
+++ b/jiri-test/internal/test/go.go
@@ -1015,6 +1015,8 @@
newExclusion("github.com/howeyc/fsnotify", ".*", isDarwin()),
// This test relies on timing, which results in flakiness on GCE.
newExclusion("google.golang.org/appengine/internal", "TestDelayedLogFlushing", isCI()),
+ // This test relies on timing, which results in flakiness on GCE.
+ newExclusion("google.golang.org/cloud/bigtable", "TestClientIntegration", isCI()),
// The crypto/ssh TestValidTerminalMode is flakey on Jenkins and
// sometimes fails when getting a pty.
newExclusion("golang.org/x/crypto/ssh/test", "TestValidTerminalMode", isCI()),
diff --git a/oncall/collect.go b/oncall/collect.go
index b780f54..6af7299 100644
--- a/oncall/collect.go
+++ b/oncall/collect.go
@@ -17,7 +17,7 @@
"strings"
"time"
- cloudmonitoring "google.golang.org/api/cloudmonitoring/v2beta2"
+ cloudmonitoring "google.golang.org/api/monitoring/v3"
"v.io/jiri/tool"
"v.io/x/devtools/internal/monitoring"
@@ -33,7 +33,7 @@
metricNameLabelKey = "custom.cloudmonitoring.googleapis.com/metric-name"
gceInstanceLabelKey = "custom.cloudmonitoring.googleapis.com/gce-instance"
gceZoneLabelKey = "custom.cloudmonitoring.googleapis.com/gce-zone"
- historyDuration = "1h"
+ historyDuration = time.Hour
serviceStatusOK = "serviceStatusOK"
serviceStatusWarning = "serviceStatusWarning"
serviceStatusDown = "serviceStatusDown"
@@ -244,19 +244,22 @@
func collectServiceStatusData(ctx *tool.Context, s *cloudmonitoring.Service, now time.Time, buildInfo map[string]*buildInfoData) (*serviceStatusData, error) {
// Collect data for the last 8 days and aggregate data every 10 minutes.
- resp, err := s.Timeseries.List(projectFlag, cloudServiceLatencyMetric, now.Format(time.RFC3339), &cloudmonitoring.ListTimeseriesRequest{
- Kind: "cloudmonitoring#listTimeseriesRequest",
- }).Window("10m").Timespan("8d").Aggregator("max").Do()
+ resp, err := s.Projects.TimeSeries.List(fmt.Sprintf("projects/%s", projectFlag)).
+ Filter(fmt.Sprintf("metric.type=%s", cloudServiceLatencyMetric)).
+ AggregationAlignmentPeriod(fmt.Sprintf("%ds", 10*60)).
+ AggregationPerSeriesAligner("ALIGN_MAX").
+ IntervalStartTime(now.AddDate(0, 0, -8).Format(time.RFC3339)).
+ IntervalEndTime(now.Format(time.RFC3339)).Do()
if err != nil {
return nil, fmt.Errorf("List failed: %v", err)
}
status := []statusData{}
- for _, t := range resp.Timeseries {
- serviceName := t.TimeseriesDesc.Labels[metricNameLabelKey]
+ for _, t := range resp.TimeSeries {
+ serviceName := t.Metric.Labels[metricNameLabelKey]
curStatusData := statusData{
Name: serviceName,
- CurrentStatus: statusForLatency(t.Points[0].DoubleValue), // t.Points[0] is the latest
+ CurrentStatus: statusForLatency(t.Points[0].Value.DoubleValue), // t.Points[0] is the latest
}
incidents, err := calcIncidents(t.Points)
if err != nil {
@@ -301,12 +304,12 @@
// through them backwards.
for i := len(points) - 1; i >= 0; i-- {
point := points[i]
- value := point.DoubleValue
+ value := point.Value.DoubleValue
curStatus := statusForLatency(value)
if curStatus != lastStatus {
- pointTime, err := time.Parse(time.RFC3339, point.Start)
+ pointTime, err := time.Parse(time.RFC3339, point.Interval.StartTime)
if err != nil {
- return nil, fmt.Errorf("time.Parse(%s) failed: %v", point.Start, err)
+ return nil, fmt.Errorf("time.Parse(%s) failed: %v", point.Interval.StartTime, err)
}
// Set the duration of the last incident.
@@ -328,7 +331,7 @@
}
// Process the possible last incident.
if lastStatus != serviceStatusOK {
- strLastPointTime := points[0].Start
+ strLastPointTime := points[0].Interval.StartTime
pointTime, err := time.Parse(time.RFC3339, strLastPointTime)
if err != nil {
return nil, fmt.Errorf("time.Parse(%q) failed: %v", strLastPointTime, err)
@@ -689,19 +692,20 @@
// (metricData) organized in metricDataMap.
func getMetricData(ctx *tool.Context, s *cloudmonitoring.Service, metric string, now time.Time, metricNameSuffix string) (metricDataMap, error) {
// Query the given metric.
- resp, err := s.Timeseries.List(projectFlag, metric, now.Format(time.RFC3339), &cloudmonitoring.ListTimeseriesRequest{
- Kind: "cloudmonitoring#listTimeseriesRequest",
- }).Timespan(historyDuration).Do()
+ resp, err := s.Projects.TimeSeries.List(fmt.Sprintf("projects/%s", projectFlag)).
+ Filter(fmt.Sprintf("metric.type=%s", metric)).
+ IntervalStartTime(now.Add(-historyDuration).Format(time.RFC3339)).
+ IntervalEndTime(now.Format(time.RFC3339)).Do()
if err != nil {
return nil, fmt.Errorf("List() failed: %v", err)
}
// Populate metric items and put them into a metricDataMap.
data := metricDataMap{}
- for _, t := range resp.Timeseries {
- zone := t.TimeseriesDesc.Labels[gceZoneLabelKey]
- instance := t.TimeseriesDesc.Labels[gceInstanceLabelKey]
- metricName := t.TimeseriesDesc.Labels[metricNameLabelKey]
+ for _, t := range resp.TimeSeries {
+ zone := t.Metric.Labels[gceZoneLabelKey]
+ instance := t.Metric.Labels[gceInstanceLabelKey]
+ metricName := t.Metric.Labels[metricNameLabelKey]
if metricNameSuffix != "" {
metricName = fmt.Sprintf("%s %s", metricName, metricNameSuffix)
}
@@ -724,7 +728,7 @@
ZoneName: zone,
InstanceName: instance,
Name: metricName,
- CurrentValue: t.Points[0].DoubleValue,
+ CurrentValue: t.Points[0].Value.DoubleValue,
MinTime: math.MaxInt64,
MaxTime: 0,
MinValue: math.MaxFloat64,
@@ -742,18 +746,18 @@
// latest and going back in time.
for i := numPoints - 1; i >= 0; i-- {
point := t.Points[i]
- epochTime, err := time.Parse(time.RFC3339, point.Start)
+ epochTime, err := time.Parse(time.RFC3339, point.Interval.StartTime)
if err != nil {
fmt.Fprintf(ctx.Stderr(), "%v\n", err)
continue
}
timestamp := epochTime.Unix()
timestamps = append(timestamps, timestamp)
- values = append(values, point.DoubleValue)
+ values = append(values, point.Value.DoubleValue)
curMetricData.MinTime = int64(math.Min(float64(curMetricData.MinTime), float64(timestamp)))
curMetricData.MaxTime = int64(math.Max(float64(curMetricData.MaxTime), float64(timestamp)))
- curMetricData.MinValue = math.Min(curMetricData.MinValue, point.DoubleValue)
- curMetricData.MaxValue = math.Max(curMetricData.MaxValue, point.DoubleValue)
+ curMetricData.MinValue = math.Min(curMetricData.MinValue, point.Value.DoubleValue)
+ curMetricData.MaxValue = math.Max(curMetricData.MaxValue, point.Value.DoubleValue)
}
curMetricData.HistoryTimestamps = timestamps
curMetricData.HistoryValues = values
diff --git a/oncall/collect_test.go b/oncall/collect_test.go
index 0ee3185..0de0e17 100644
--- a/oncall/collect_test.go
+++ b/oncall/collect_test.go
@@ -9,7 +9,7 @@
"testing"
"time"
- "google.golang.org/api/cloudmonitoring/v2beta2"
+ cloudmonitoring "google.golang.org/api/monitoring/v3"
)
func TestCalcIncidents(t *testing.T) {
@@ -21,16 +21,28 @@
{
points: []*cloudmonitoring.Point{
&cloudmonitoring.Point{
- DoubleValue: 1000,
- Start: time.Unix(1429896102, 0).Format(time.RFC3339),
+ Interval: &cloudmonitoring.TimeInterval{
+ StartTime: time.Unix(1429896102, 0).Format(time.RFC3339),
+ },
+ Value: &cloudmonitoring.TypedValue{
+ DoubleValue: 1000,
+ },
},
&cloudmonitoring.Point{
- DoubleValue: 1000,
- Start: time.Unix(1429896101, 0).Format(time.RFC3339),
+ Interval: &cloudmonitoring.TimeInterval{
+ StartTime: time.Unix(1429896101, 0).Format(time.RFC3339),
+ },
+ Value: &cloudmonitoring.TypedValue{
+ DoubleValue: 1000,
+ },
},
&cloudmonitoring.Point{
- DoubleValue: 1000,
- Start: time.Unix(1429896100, 0).Format(time.RFC3339),
+ Interval: &cloudmonitoring.TimeInterval{
+ StartTime: time.Unix(1429896100, 0).Format(time.RFC3339),
+ },
+ Value: &cloudmonitoring.TypedValue{
+ DoubleValue: 1000,
+ },
},
},
expectedIncidentData: []incidentData{},
@@ -39,20 +51,36 @@
{
points: []*cloudmonitoring.Point{
&cloudmonitoring.Point{
- DoubleValue: 1000,
- Start: time.Unix(1429896103, 0).Format(time.RFC3339),
+ Interval: &cloudmonitoring.TimeInterval{
+ StartTime: time.Unix(1429896103, 0).Format(time.RFC3339),
+ },
+ Value: &cloudmonitoring.TypedValue{
+ DoubleValue: 1000,
+ },
},
&cloudmonitoring.Point{
- DoubleValue: 3000,
- Start: time.Unix(1429896102, 0).Format(time.RFC3339),
+ Interval: &cloudmonitoring.TimeInterval{
+ StartTime: time.Unix(1429896102, 0).Format(time.RFC3339),
+ },
+ Value: &cloudmonitoring.TypedValue{
+ DoubleValue: 3000,
+ },
},
&cloudmonitoring.Point{
- DoubleValue: 3000,
- Start: time.Unix(1429896101, 0).Format(time.RFC3339),
+ Interval: &cloudmonitoring.TimeInterval{
+ StartTime: time.Unix(1429896101, 0).Format(time.RFC3339),
+ },
+ Value: &cloudmonitoring.TypedValue{
+ DoubleValue: 3000,
+ },
},
&cloudmonitoring.Point{
- DoubleValue: 1000,
- Start: time.Unix(1429896100, 0).Format(time.RFC3339),
+ Interval: &cloudmonitoring.TimeInterval{
+ StartTime: time.Unix(1429896100, 0).Format(time.RFC3339),
+ },
+ Value: &cloudmonitoring.TypedValue{
+ DoubleValue: 1000,
+ },
},
},
expectedIncidentData: []incidentData{
@@ -67,24 +95,44 @@
{
points: []*cloudmonitoring.Point{
&cloudmonitoring.Point{
- DoubleValue: 1000,
- Start: time.Unix(1429896104, 0).Format(time.RFC3339),
+ Interval: &cloudmonitoring.TimeInterval{
+ StartTime: time.Unix(1429896104, 0).Format(time.RFC3339),
+ },
+ Value: &cloudmonitoring.TypedValue{
+ DoubleValue: 1000,
+ },
},
&cloudmonitoring.Point{
- DoubleValue: 3000,
- Start: time.Unix(1429896103, 0).Format(time.RFC3339),
+ Interval: &cloudmonitoring.TimeInterval{
+ StartTime: time.Unix(1429896103, 0).Format(time.RFC3339),
+ },
+ Value: &cloudmonitoring.TypedValue{
+ DoubleValue: 3000,
+ },
},
&cloudmonitoring.Point{
- DoubleValue: 3000,
- Start: time.Unix(1429896102, 0).Format(time.RFC3339),
+ Interval: &cloudmonitoring.TimeInterval{
+ StartTime: time.Unix(1429896102, 0).Format(time.RFC3339),
+ },
+ Value: &cloudmonitoring.TypedValue{
+ DoubleValue: 3000,
+ },
},
&cloudmonitoring.Point{
- DoubleValue: 5000,
- Start: time.Unix(1429896101, 0).Format(time.RFC3339),
+ Interval: &cloudmonitoring.TimeInterval{
+ StartTime: time.Unix(1429896101, 0).Format(time.RFC3339),
+ },
+ Value: &cloudmonitoring.TypedValue{
+ DoubleValue: 5000,
+ },
},
&cloudmonitoring.Point{
- DoubleValue: 1000,
- Start: time.Unix(1429896100, 0).Format(time.RFC3339),
+ Interval: &cloudmonitoring.TimeInterval{
+ StartTime: time.Unix(1429896100, 0).Format(time.RFC3339),
+ },
+ Value: &cloudmonitoring.TypedValue{
+ DoubleValue: 1000,
+ },
},
},
expectedIncidentData: []incidentData{
@@ -104,20 +152,36 @@
{
points: []*cloudmonitoring.Point{
&cloudmonitoring.Point{
- DoubleValue: 3000,
- Start: time.Unix(1429896103, 0).Format(time.RFC3339),
+ Interval: &cloudmonitoring.TimeInterval{
+ StartTime: time.Unix(1429896103, 0).Format(time.RFC3339),
+ },
+ Value: &cloudmonitoring.TypedValue{
+ DoubleValue: 3000,
+ },
},
&cloudmonitoring.Point{
- DoubleValue: 3000,
- Start: time.Unix(1429896102, 0).Format(time.RFC3339),
+ Interval: &cloudmonitoring.TimeInterval{
+ StartTime: time.Unix(1429896102, 0).Format(time.RFC3339),
+ },
+ Value: &cloudmonitoring.TypedValue{
+ DoubleValue: 3000,
+ },
},
&cloudmonitoring.Point{
- DoubleValue: 1000,
- Start: time.Unix(1429896101, 0).Format(time.RFC3339),
+ Interval: &cloudmonitoring.TimeInterval{
+ StartTime: time.Unix(1429896101, 0).Format(time.RFC3339),
+ },
+ Value: &cloudmonitoring.TypedValue{
+ DoubleValue: 1000,
+ },
},
&cloudmonitoring.Point{
- DoubleValue: 5000,
- Start: time.Unix(1429896100, 0).Format(time.RFC3339),
+ Interval: &cloudmonitoring.TimeInterval{
+ StartTime: time.Unix(1429896100, 0).Format(time.RFC3339),
+ },
+ Value: &cloudmonitoring.TypedValue{
+ DoubleValue: 5000,
+ },
},
},
expectedIncidentData: []incidentData{
diff --git a/vmon/check.go b/vmon/check.go
index df0e2fd..a628334 100644
--- a/vmon/check.go
+++ b/vmon/check.go
@@ -9,7 +9,7 @@
"sort"
"strings"
- "google.golang.org/api/cloudmonitoring/v2beta2"
+ cloudmonitoring "google.golang.org/api/monitoring/v3"
"v.io/jiri/tool"
"v.io/v23/context"
diff --git a/vmon/cmd.go b/vmon/cmd.go
index e237aa3..9b6978b 100644
--- a/vmon/cmd.go
+++ b/vmon/cmd.go
@@ -23,7 +23,7 @@
queryFilterFlag string
projectFlag string
- defaultQueryFilter = "custom.cloudmonitoring.googleapis.com"
+ defaultQueryFilter = `metric.type=starts_with("custom.googleapis.com")`
)
func init() {
diff --git a/vmon/doc.go b/vmon/doc.go
index 14909dd..fee81e9 100644
--- a/vmon/doc.go
+++ b/vmon/doc.go
@@ -174,7 +174,7 @@
vmon md query [flags]
The vmon md query flags are:
- -filter=custom.cloudmonitoring.googleapis.com
+ -filter=metric.type=starts_with("custom.googleapis.com")
The filter used for query. Default to only query custom metrics.
-color=true
diff --git a/vmon/gceinstance.go b/vmon/gceinstance.go
index e5646e6..7c1e0e5 100644
--- a/vmon/gceinstance.go
+++ b/vmon/gceinstance.go
@@ -18,7 +18,7 @@
"strings"
"time"
- "google.golang.org/api/cloudmonitoring/v2beta2"
+ cloudmonitoring "google.golang.org/api/monitoring/v3"
"v.io/jiri/collect"
"v.io/jiri/tool"
@@ -386,7 +386,7 @@
if err != nil {
return err
}
- timeStr := time.Now().Format(time.RFC3339)
+ timeStr := time.Now().UTC().Format(time.RFC3339)
for _, instance := range instances {
msg := fmt.Sprintf("Send gce instance data for %s (%s)\n", instance.name, instance.zone)
for _, metricName := range gceMetricNames {
@@ -453,28 +453,11 @@
// sendInstanceDataToGCM sends a single instance's stat to GCM.
func sendInstanceDataToGCM(s *cloudmonitoring.Service, metricType, metricName, timeStr string, instance *gceInstanceData, value float64) error {
- pt := cloudmonitoring.Point{
- DoubleValue: value,
- Start: timeStr,
- End: timeStr,
- }
- md := monitoring.CustomMetricDescriptors[metricType]
- _, err := s.Timeseries.Write(projectFlag, &cloudmonitoring.WriteTimeseriesRequest{
- Timeseries: []*cloudmonitoring.TimeseriesPoint{
- &cloudmonitoring.TimeseriesPoint{
- Point: &pt,
- TimeseriesDesc: &cloudmonitoring.TimeseriesDescriptor{
- Metric: md.Name,
- Labels: map[string]string{
- md.Labels[0].Key: instance.name,
- md.Labels[1].Key: instance.zone,
- md.Labels[2].Key: metricName,
- },
- },
- },
- },
- }).Do()
+ md, err := monitoring.GetMetric(metricType, projectFlag)
if err != nil {
+ return err
+ }
+ if err := sendDataToGCM(s, md, value, timeStr, "", "", metricName); err != nil {
return fmt.Errorf("failed to write timeseries: %v", err)
}
return nil
diff --git a/vmon/jenkins.go b/vmon/jenkins.go
index 7a5fa80..e891b7a 100644
--- a/vmon/jenkins.go
+++ b/vmon/jenkins.go
@@ -8,7 +8,7 @@
"fmt"
"time"
- "google.golang.org/api/cloudmonitoring/v2beta2"
+ cloudmonitoring "google.golang.org/api/monitoring/v3"
"v.io/jiri/tool"
"v.io/v23/context"
"v.io/x/devtools/internal/monitoring"
@@ -30,12 +30,15 @@
return err
}
now := time.Now()
- strNow := now.Format(time.RFC3339)
+ strNow := now.UTC().Format(time.RFC3339)
ageInHours := now.Sub(time.Unix(info.Timestamp/1000, 0)).Hours()
msg := fmt.Sprintf("vanadium-go-build age: %f hours.\n", ageInHours)
// Send data to GCM.
- md := monitoring.CustomMetricDescriptors["jenkins"]
+ md, err := monitoring.GetMetric("jenkins", projectFlag)
+ if err != nil {
+ return err
+ }
if err := sendDataToGCM(s, md, float64(ageInHours), strNow, "", "", "vanadium-go-build age"); err != nil {
test.Fail(ctx, msg)
return err
diff --git a/vmon/metricdescriptor.go b/vmon/metricdescriptor.go
index ae86361..5a86cad 100644
--- a/vmon/metricdescriptor.go
+++ b/vmon/metricdescriptor.go
@@ -6,10 +6,9 @@
import (
"fmt"
- "sort"
"strings"
- cloudmonitoring "google.golang.org/api/cloudmonitoring/v2beta2"
+ cloudmonitoring "google.golang.org/api/monitoring/v3"
"v.io/v23/context"
"v.io/x/devtools/internal/monitoring"
@@ -41,7 +40,7 @@
Short: "Create the given metric descriptor in GCM",
Long: "Create the given metric descriptor in GCM.",
ArgsName: "<names>",
- ArgsLong: "<names> is a list of metric descriptor names to create. Available: " + strings.Join(knownMetricDescriptorNames(), ", "),
+ ArgsLong: "<names> is a list of metric descriptor names to create. Available: " + strings.Join(monitoring.GetSortedMetricNames(), ", "),
}
func runMetricDescriptorCreate(_ *context.T, env *cmdline.Env, args []string) error {
@@ -54,7 +53,11 @@
return err
}
for _, arg := range args {
- _, err := s.MetricDescriptors.Create(projectFlag, monitoring.CustomMetricDescriptors[arg]).Do()
+ md, err := monitoring.GetMetric(arg, projectFlag)
+ if err != nil {
+ return err
+ }
+ _, err = s.Projects.MetricDescriptors.Create(fmt.Sprintf("projects/%s", projectFlag), md).Do()
if err != nil {
return fmt.Errorf("Create failed: %v", err)
}
@@ -70,7 +73,7 @@
Short: "Delete the given metric descriptor from GCM",
Long: "Delete the given metric descriptor from GCM.",
ArgsName: "<names>",
- ArgsLong: "<names> is a list of metric descriptor names to delete. Available: " + strings.Join(knownMetricDescriptorNames(), ", "),
+ ArgsLong: "<names> is a list of metric descriptor names to delete. Available: " + strings.Join(monitoring.GetSortedMetricNames(), ", "),
}
func runMetricDescriptorDelete(_ *context.T, env *cmdline.Env, args []string) error {
@@ -83,7 +86,11 @@
return err
}
for _, arg := range args {
- _, err := s.MetricDescriptors.Delete(projectFlag, monitoring.CustomMetricDescriptors[arg].Name).Do()
+ md, err := monitoring.GetMetric(arg, projectFlag)
+ if err != nil {
+ return err
+ }
+ _, err = s.Projects.MetricDescriptors.Delete(md.Name).Do()
if err != nil {
return fmt.Errorf("Delete failed: %v", err)
}
@@ -101,7 +108,7 @@
}
func runMetricDescriptorList(_ *context.T, env *cmdline.Env, _ []string) error {
- for _, n := range knownMetricDescriptorNames() {
+ for _, n := range monitoring.GetSortedMetricNames() {
fmt.Fprintf(env.Stdout, "%s\n", n)
}
return nil
@@ -125,13 +132,13 @@
nextPageToken := ""
descriptors := []*cloudmonitoring.MetricDescriptor{}
for {
- resp, err := s.MetricDescriptors.List(projectFlag, &cloudmonitoring.ListMetricDescriptorsRequest{
- Kind: "cloudmonitoring#listMetricDescriptorsRequest",
- }).Query(queryFilterFlag).PageToken(nextPageToken).Do()
+ resp, err := s.Projects.MetricDescriptors.List(fmt.Sprintf("projects/%s", projectFlag)).
+ Filter(queryFilterFlag).
+ PageToken(nextPageToken).Do()
if err != nil {
return fmt.Errorf("Query failed: %v", err)
}
- descriptors = append(descriptors, resp.Metrics...)
+ descriptors = append(descriptors, resp.MetricDescriptors...)
nextPageToken = resp.NextPageToken
if nextPageToken == "" {
break
@@ -140,10 +147,11 @@
// Output results.
for _, metric := range descriptors {
- fmt.Fprintf(env.Stdout, "%s\n", metric.Name)
+ fmt.Fprintf(env.Stdout, "%s\n", metric.Type)
+ fmt.Fprintf(env.Stdout, "- Name: %s\n", metric.Name)
fmt.Fprintf(env.Stdout, "- Description: %s\n", metric.Description)
- fmt.Fprintf(env.Stdout, "- Metric Type: %s\n", metric.TypeDescriptor.MetricType)
- fmt.Fprintf(env.Stdout, "- Value Type: %s\n", metric.TypeDescriptor.ValueType)
+ fmt.Fprintf(env.Stdout, "- Metric Type: %s\n", metric.MetricKind)
+ fmt.Fprintf(env.Stdout, "- Value Type: %s\n", metric.ValueType)
if len(metric.Labels) > 0 {
fmt.Fprintf(env.Stdout, "- Labels:\n")
for _, label := range metric.Labels {
@@ -157,19 +165,10 @@
return nil
}
-func knownMetricDescriptorNames() []string {
- names := []string{}
- for n := range monitoring.CustomMetricDescriptors {
- names = append(names, n)
- }
- sort.Strings(names)
- return names
-}
-
func checkArgs(env *cmdline.Env, args []string) error {
for _, arg := range args {
- if _, ok := monitoring.CustomMetricDescriptors[arg]; !ok {
- return env.UsageErrorf("metric descriptor %v does not exist", arg)
+ if _, err := monitoring.GetMetric(arg, projectFlag); err != nil {
+ return err
}
}
if len(args) == 0 {
diff --git a/vmon/rpcloadtest.go b/vmon/rpcloadtest.go
index 0728963..786956a 100644
--- a/vmon/rpcloadtest.go
+++ b/vmon/rpcloadtest.go
@@ -11,7 +11,7 @@
"path/filepath"
"time"
- "google.golang.org/api/cloudmonitoring/v2beta2"
+ cloudmonitoring "google.golang.org/api/monitoring/v3"
"v.io/jiri/tool"
"v.io/v23/context"
@@ -41,31 +41,17 @@
"latency": results.MsecPerRpc,
"qps": results.Qps,
}
- mdRpcLoadTest := monitoring.CustomMetricDescriptors["rpc-load-test"]
+ mdRpcLoadTest, err := monitoring.GetMetric("rpc-load-test", projectFlag)
+ if err != nil {
+ return err
+ }
fi, err := seq.Stat(resultFile)
if err != nil {
return err
}
- timeStr := fi.ModTime().Format(time.RFC3339)
+ timeStr := fi.ModTime().UTC().Format(time.RFC3339)
for label, value := range items {
- _, err = s.Timeseries.Write(projectFlag, &cloudmonitoring.WriteTimeseriesRequest{
- Timeseries: []*cloudmonitoring.TimeseriesPoint{
- &cloudmonitoring.TimeseriesPoint{
- Point: &cloudmonitoring.Point{
- DoubleValue: value,
- Start: timeStr,
- End: timeStr,
- },
- TimeseriesDesc: &cloudmonitoring.TimeseriesDescriptor{
- Metric: mdRpcLoadTest.Name,
- Labels: map[string]string{
- mdRpcLoadTest.Labels[0].Key: label,
- },
- },
- },
- },
- }).Do()
- if err != nil {
+ if err := sendDataToGCM(s, mdRpcLoadTest, value, timeStr, "", ""); err != nil {
test.Fail(ctx, "%s: %f\n", label, value)
return fmt.Errorf("Timeseries Write failed: %v", err)
}
diff --git a/vmon/servicecommon.go b/vmon/servicecommon.go
index 58f8e57..b7153a9 100644
--- a/vmon/servicecommon.go
+++ b/vmon/servicecommon.go
@@ -10,7 +10,7 @@
"math"
"strings"
- cloudmonitoring "google.golang.org/api/cloudmonitoring/v2beta2"
+ cloudmonitoring "google.golang.org/api/monitoring/v3"
"v.io/jiri/tool"
"v.io/v23"
@@ -273,22 +273,27 @@
for i := range labels {
labelsMap[md.Labels[i].Key] = labels[i]
}
- if _, err := s.Timeseries.Write(projectFlag, &cloudmonitoring.WriteTimeseriesRequest{
- Timeseries: []*cloudmonitoring.TimeseriesPoint{
- &cloudmonitoring.TimeseriesPoint{
- Point: &cloudmonitoring.Point{
- DoubleValue: value,
- Start: now,
- End: now,
- },
- TimeseriesDesc: &cloudmonitoring.TimeseriesDescriptor{
- Metric: md.Name,
+ if _, err := s.Projects.TimeSeries.Create(fmt.Sprintf("projects/%s", projectFlag), &cloudmonitoring.CreateTimeSeriesRequest{
+ TimeSeries: []*cloudmonitoring.TimeSeries{
+ &cloudmonitoring.TimeSeries{
+ Metric: &cloudmonitoring.Metric{
+ Type: md.Type,
Labels: labelsMap,
},
+ Points: []*cloudmonitoring.Point{
+ &cloudmonitoring.Point{
+ Value: &cloudmonitoring.TypedValue{
+ DoubleValue: value,
+ },
+ Interval: &cloudmonitoring.TimeInterval{
+ StartTime: now,
+ EndTime: now,
+ },
+ },
+ },
},
- },
- }).Do(); err != nil {
- return fmt.Errorf("Timeseries Write failed for metric %q with value %q: %v", md.Name, value, err)
+ }}).Do(); err != nil {
+ return fmt.Errorf("Timeseries Write failed for metric %q with value %f: %v", md.Name, value, err)
}
return nil
}
diff --git a/vmon/servicecounters.go b/vmon/servicecounters.go
index bd41ffa..8320a85 100644
--- a/vmon/servicecounters.go
+++ b/vmon/servicecounters.go
@@ -8,7 +8,7 @@
"fmt"
"time"
- "google.golang.org/api/cloudmonitoring/v2beta2"
+ cloudmonitoring "google.golang.org/api/monitoring/v3"
"v.io/jiri/tool"
"v.io/v23/context"
@@ -42,8 +42,11 @@
}
hasError := false
- mdCounter := monitoring.CustomMetricDescriptors["service-counters"]
- now := time.Now().Format(time.RFC3339)
+ mdCounter, err := monitoring.GetMetric("service-counters", projectFlag)
+ if err != nil {
+ return err
+ }
+ now := time.Now().UTC().Format(time.RFC3339)
for serviceName, serviceCounters := range counters {
for _, counter := range serviceCounters {
vs, err := checkSingleCounter(v23ctx, ctx, serviceName, counter)
@@ -69,7 +72,11 @@
}
// Send aggregated data to GCM.
- if err := sendAggregatedDataToGCM(ctx, s, monitoring.CustomMetricDescriptors["service-counters-agg"], agg, now, counter.name); err != nil {
+ mdAgg, err := monitoring.GetMetric("service-counters-agg", projectFlag)
+ if err != nil {
+ return err
+ }
+ if err := sendAggregatedDataToGCM(ctx, s, mdAgg, agg, now, counter.name); err != nil {
return err
}
}
diff --git a/vmon/servicelatency.go b/vmon/servicelatency.go
index bfb560e..1eb3fef 100644
--- a/vmon/servicelatency.go
+++ b/vmon/servicelatency.go
@@ -8,7 +8,7 @@
"fmt"
"time"
- "google.golang.org/api/cloudmonitoring/v2beta2"
+ cloudmonitoring "google.golang.org/api/monitoring/v3"
"v.io/jiri/tool"
"v.io/v23/context"
@@ -44,8 +44,11 @@
}
hasError := false
- mdLat := monitoring.CustomMetricDescriptors["service-latency"]
- now := time.Now().Format(time.RFC3339)
+ mdLat, err := monitoring.GetMetric("service-latency", projectFlag)
+ if err != nil {
+ return err
+ }
+ now := time.Now().UTC().Format(time.RFC3339)
for _, serviceName := range serviceNames {
lats, err := checkSingleServiceLatency(v23ctx, ctx, serviceName)
if err != nil {
@@ -75,7 +78,11 @@
}
// Send aggregated data to GCM.
- if err := sendAggregatedDataToGCM(ctx, s, monitoring.CustomMetricDescriptors["service-latency-agg"], agg, now, serviceName); err != nil {
+ mdAgg, err := monitoring.GetMetric("service-latency-agg", projectFlag)
+ if err != nil {
+ return err
+ }
+ if err := sendAggregatedDataToGCM(ctx, s, mdAgg, agg, now, serviceName); err != nil {
return err
}
}
diff --git a/vmon/servicemetadata.go b/vmon/servicemetadata.go
index a05fc53..15a050b 100644
--- a/vmon/servicemetadata.go
+++ b/vmon/servicemetadata.go
@@ -8,7 +8,7 @@
"fmt"
"time"
- "google.golang.org/api/cloudmonitoring/v2beta2"
+ cloudmonitoring "google.golang.org/api/monitoring/v3"
"v.io/jiri/tool"
"v.io/v23/context"
@@ -35,9 +35,12 @@
}
hasError := false
- mdMetadata := monitoring.CustomMetricDescriptors["service-metadata"]
+ mdMetadata, err := monitoring.GetMetric("service-metadata", projectFlag)
+ if err != nil {
+ return err
+ }
now := time.Now()
- strNow := now.Format(time.RFC3339)
+ strNow := now.UTC().Format(time.RFC3339)
for _, serviceName := range serviceNames {
ms, err := checkSingleServiceMetadata(v23ctx, ctx, serviceName)
if err != nil {
@@ -70,7 +73,10 @@
}
// Send aggregated data to GCM.
- mdMetadataAgg := monitoring.CustomMetricDescriptors["service-metadata-agg"]
+ mdMetadataAgg, err := monitoring.GetMetric("service-metadata-agg", projectFlag)
+ if err != nil {
+ return err
+ }
if err := sendAggregatedDataToGCM(ctx, s, mdMetadataAgg, aggBuildTime, strNow, serviceName, "build time"); err != nil {
return err
}
diff --git a/vmon/servicemethodlatency.go b/vmon/servicemethodlatency.go
index eb6b3ca..454bb31 100644
--- a/vmon/servicemethodlatency.go
+++ b/vmon/servicemethodlatency.go
@@ -11,7 +11,7 @@
"sort"
"time"
- "google.golang.org/api/cloudmonitoring/v2beta2"
+ cloudmonitoring "google.golang.org/api/monitoring/v3"
"v.io/jiri/tool"
"v.io/v23/context"
@@ -41,8 +41,11 @@
}
hasError := false
- mdLatPerMethod := monitoring.CustomMetricDescriptors["service-permethod-latency"]
- now := time.Now().Format(time.RFC3339)
+ mdLatPerMethod, err := monitoring.GetMetric("service-permethod-latency", projectFlag)
+ if err != nil {
+ return err
+ }
+ now := time.Now().UTC().Format(time.RFC3339)
for _, serviceName := range serviceNames {
lats, err := checkSingleServicePerMethodLatency(v23ctx, ctx, serviceName)
if err != nil {
@@ -80,7 +83,11 @@
// Send aggregated data to GCM.
for method, agg := range aggByMethod {
- if err := sendAggregatedDataToGCM(ctx, s, monitoring.CustomMetricDescriptors["service-permethod-latency-agg"], agg, now, serviceName, method); err != nil {
+ mdAgg, err := monitoring.GetMetric("service-permethod-latency-agg", projectFlag)
+ if err != nil {
+ return err
+ }
+ if err := sendAggregatedDataToGCM(ctx, s, mdAgg, agg, now, serviceName, method); err != nil {
return err
}
}
diff --git a/vmon/serviceqps.go b/vmon/serviceqps.go
index 8b6b4cd..3dc4c7a 100644
--- a/vmon/serviceqps.go
+++ b/vmon/serviceqps.go
@@ -10,7 +10,7 @@
"sort"
"time"
- "google.golang.org/api/cloudmonitoring/v2beta2"
+ cloudmonitoring "google.golang.org/api/monitoring/v3"
"v.io/jiri/tool"
"v.io/v23/context"
@@ -44,9 +44,15 @@
}
hasError := false
- mdPerMethodQPS := monitoring.CustomMetricDescriptors["service-qps-method"]
- mdTotalQPS := monitoring.CustomMetricDescriptors["service-qps-total"]
- now := time.Now().Format(time.RFC3339)
+ mdPerMethodQPS, err := monitoring.GetMetric("service-qps-method", projectFlag)
+ if err != nil {
+ return err
+ }
+ mdTotalQPS, err := monitoring.GetMetric("service-qps-total", projectFlag)
+ if err != nil {
+ return err
+ }
+ now := time.Now().UTC().Format(time.RFC3339)
for _, serviceName := range serviceNames {
qps, err := checkSingleServiceQPS(v23ctx, ctx, serviceName)
if err != nil {
@@ -94,11 +100,19 @@
}
// Send aggregated data to GCM.
- if err := sendAggregatedDataToGCM(ctx, s, monitoring.CustomMetricDescriptors["service-qps-total-agg"], agg, now, serviceName); err != nil {
+ mdTotalAgg, err := monitoring.GetMetric("service-qps-total-agg", projectFlag)
+ if err != nil {
+ return err
+ }
+ if err := sendAggregatedDataToGCM(ctx, s, mdTotalAgg, agg, now, serviceName); err != nil {
return err
}
for method, agg := range aggByMethod {
- if err := sendAggregatedDataToGCM(ctx, s, monitoring.CustomMetricDescriptors["service-qps-method-agg"], agg, now, serviceName, method); err != nil {
+ mdMethodAgg, err := monitoring.GetMetric("service-qps-method-agg", projectFlag)
+ if err != nil {
+ return err
+ }
+ if err := sendAggregatedDataToGCM(ctx, s, mdMethodAgg, agg, now, serviceName, method); err != nil {
return err
}
}