From 7d41a1f796b2a1db2323cf327b8e322e1b822741 Mon Sep 17 00:00:00 2001 From: Rob Pickerill Date: Wed, 21 Apr 2021 19:22:26 -0700 Subject: [PATCH] Add AWS cloudwatch surfacer. This is import of the original PR at https://github.com/google/cloudprober/pull/583. PiperOrigin-RevId: 369784229 --- go.mod | 2 +- go.sum | 2 + surfacers/cloudwatch/cloudwatch.go | 243 +++++++++++++++ surfacers/cloudwatch/cloudwatch_test.go | 379 ++++++++++++++++++++++++ surfacers/cloudwatch/proto/config.pb.go | 188 ++++++++++++ surfacers/cloudwatch/proto/config.proto | 23 ++ surfacers/proto/config.pb.go | 136 +++++---- surfacers/proto/config.proto | 3 + surfacers/surfacers.go | 8 +- tools/gen_pb_go.sh | 3 +- 10 files changed, 931 insertions(+), 56 deletions(-) create mode 100644 surfacers/cloudwatch/cloudwatch.go create mode 100644 surfacers/cloudwatch/cloudwatch_test.go create mode 100644 surfacers/cloudwatch/proto/config.pb.go create mode 100644 surfacers/cloudwatch/proto/config.proto diff --git a/go.mod b/go.mod index 1ac16d0d..d7df98f8 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( cloud.google.com/go/pubsub v1.8.1 github.com/aws/aws-sdk-go v1.35.7 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b - github.com/golang/protobuf v1.5.1 + github.com/golang/protobuf v1.5.2 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/hashicorp/golang-lru v0.5.3 // indirect github.com/hoisie/redis v0.0.0-20160730154456-b5c6e81454e0 diff --git a/go.sum b/go.sum index bc9514cf..51db1344 100644 --- a/go.sum +++ b/go.sum @@ -111,6 +111,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1 h1:jAbXjIeW2ZSW2AwFxlGTDoc2CjI2XujLkV3ArsZFCvc= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= diff --git a/surfacers/cloudwatch/cloudwatch.go b/surfacers/cloudwatch/cloudwatch.go new file mode 100644 index 00000000..3680425a --- /dev/null +++ b/surfacers/cloudwatch/cloudwatch.go @@ -0,0 +1,243 @@ +// Copyright 2021 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* +Package cloudwatch implements a surfacer to export metrics to AWS Cloudwatch. +*/ +package cloudwatch + +import ( + "context" + "fmt" + "regexp" + "strconv" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/cloudwatch" + "github.com/google/cloudprober/logger" + "github.com/google/cloudprober/metrics" + + configpb "github.com/google/cloudprober/surfacers/cloudwatch/proto" + "github.com/google/cloudprober/surfacers/common/options" +) + +// Cloudwatch API limit for metrics included in a PutMetricData call +const maxMetricDatums int = 20 + +// The dimension named used to identify distributions +const distributionDimensionName string = "le" + +// CWSurfacer implements AWS Cloudwatch surfacer. +type CWSurfacer struct { + c *configpb.SurfacerConf + writeChan chan *metrics.EventMetrics + session *cloudwatch.CloudWatch + l *logger.Logger + allowedMetricsRegex *regexp.Regexp + + // A cache of []*cloudwatch.MetricDatum's, used for batch writing to the + // cloudwatch api. + cwMetricDatumCache []*cloudwatch.MetricDatum +} + +func (cw *CWSurfacer) processIncomingMetrics(ctx context.Context) { +RoutineLoop: + for { + select { + case <-ctx.Done(): + cw.l.Infof("Context canceled, stopping the surfacer write loop") + return + case em := <-cw.writeChan: + + // evaluate if any of the metric labels are to be ignored and exit early + for _, label := range em.LabelsKeys() { + if cw.ignoreMetric(label) || cw.ignoreMetric(em.Label(label)) { + continue RoutineLoop + } + } + + // check if a failure metric can be calculated + if em.Metric("success") != nil && em.Metric("total") != nil && em.Metric("failure") == nil { + if failure, err := calculateFailureMetric(em); err == nil { + em.AddMetric("failure", metrics.NewFloat(failure)) + } else { + cw.l.Errorf("Error calculating failure metric: %s", err) + } + } + + cw.recordEventMetrics(em) + } + } +} + +// recordEventMetrics takes an EventMetric, which can contain multiple metrics +// of varying types, and loops through each metric in the EventMetric, parsing +// each metric into a structure that is supported by Cloudwatch +func (cw *CWSurfacer) recordEventMetrics(em *metrics.EventMetrics) { + for _, metricKey := range em.MetricsKeys() { + + switch value := em.Metric(metricKey).(type) { + case metrics.NumValue: + cw.publishMetrics(cw.newCWMetricDatum(metricKey, value.Float64(), emLabelsToDimensions(em), em.Timestamp, em.LatencyUnit)) + + case *metrics.Map: + for _, mapKey := range value.Keys() { + dimensions := emLabelsToDimensions(em) + dimensions = append(dimensions, &cloudwatch.Dimension{ + Name: aws.String(value.MapName), + Value: aws.String(mapKey), + }) + cw.publishMetrics(cw.newCWMetricDatum(metricKey, value.GetKey(mapKey).Float64(), dimensions, em.Timestamp, em.LatencyUnit)) + } + + case *metrics.Distribution: + for i, distributionBound := range value.Data().LowerBounds { + dimensions := append(emLabelsToDimensions(em), &cloudwatch.Dimension{ + Name: aws.String(distributionDimensionName), + Value: aws.String(strconv.FormatFloat(distributionBound, 'f', -1, 64)), + }) + + cw.publishMetrics(cw.newCWMetricDatum(metricKey, float64(value.Data().BucketCounts[i]), dimensions, em.Timestamp, em.LatencyUnit)) + } + } + } +} + +// Publish the metrics to cloudwatch, using the namespace provided from +// configuration. +func (cw *CWSurfacer) publishMetrics(md *cloudwatch.MetricDatum) { + if len(cw.cwMetricDatumCache) >= maxMetricDatums { + _, err := cw.session.PutMetricData(&cloudwatch.PutMetricDataInput{ + Namespace: aws.String(cw.c.GetNamespace()), + MetricData: cw.cwMetricDatumCache, + }) + + if err != nil { + cw.l.Errorf("Failed to publish metrics to cloudwatch: %s", err) + } + + cw.cwMetricDatumCache = cw.cwMetricDatumCache[:0] + } + + cw.cwMetricDatumCache = append(cw.cwMetricDatumCache, md) +} + +// calculateFailureMetrics calculates a failure cumalative metric, from the +// total and success metrics in the eventmetric. +func calculateFailureMetric(em *metrics.EventMetrics) (float64, error) { + successMetric, totalMetric := em.Metric("success"), em.Metric("total") + + success, successOK := successMetric.(metrics.NumValue) + total, totalOK := totalMetric.(metrics.NumValue) + + if !successOK || !totalOK { + return 0, fmt.Errorf("unexpected error, either success or total is not a number") + } + + failure := total.Float64() - success.Float64() + + return failure, nil +} + +func (cw *CWSurfacer) ignoreMetric(name string) bool { + if cw.allowedMetricsRegex != nil { + if !cw.allowedMetricsRegex.MatchString(name) { + return true + } + } + + return false +} + +// Create a new cloudwatch metriddatum using the values passed in. +func (cw *CWSurfacer) newCWMetricDatum(metricname string, value float64, dimensions []*cloudwatch.Dimension, timestamp time.Time, latencyUnit time.Duration) *cloudwatch.MetricDatum { + // define the metric datum with default values + metricDatum := cloudwatch.MetricDatum{ + Dimensions: dimensions, + MetricName: aws.String(metricname), + Value: aws.Float64(value), + StorageResolution: aws.Int64(cw.c.GetResolution()), + Timestamp: aws.Time(timestamp), + Unit: aws.String(cloudwatch.StandardUnitCount), + } + + // the cloudwatch api will throw warnings when a timeseries has multiple + // units, to avoid this always calculate the value as milliseconds. + if metricname == "latency" { + metricDatum.Unit = aws.String(cloudwatch.StandardUnitMilliseconds) + metricDatum.Value = aws.Float64(value * float64(latencyUnit) / float64(time.Millisecond)) + } + + return &metricDatum +} + +// Take metric labels from an event metric and parse them into a Cloudwatch Dimension struct. +func emLabelsToDimensions(em *metrics.EventMetrics) []*cloudwatch.Dimension { + dimensions := []*cloudwatch.Dimension{} + + for _, k := range em.LabelsKeys() { + dimensions = append(dimensions, &cloudwatch.Dimension{ + Name: aws.String(k), + Value: aws.String(em.Label(k)), + }) + } + + return dimensions +} + +// New creates a new instance of a cloudwatch surfacer, based on the config +// passed in. It then hands off to a goroutine to surface metrics to cloudwatch +// across a buffered channel. +func New(ctx context.Context, config *configpb.SurfacerConf, opts *options.Options, l *logger.Logger) (*CWSurfacer, error) { + + sess := session.Must(session.NewSessionWithOptions(session.Options{ + SharedConfigState: session.SharedConfigEnable, + })) + + cw := &CWSurfacer{ + c: config, + writeChan: make(chan *metrics.EventMetrics, opts.MetricsBufferSize), + session: cloudwatch.New(sess), + l: l, + } + + if cw.c.GetAllowedMetricsRegex() != "" { + r, err := regexp.Compile(cw.c.GetAllowedMetricsRegex()) + if err != nil { + return nil, err + } + cw.allowedMetricsRegex = r + } + + // Set the capacity of this slice to the max metric value, to avoid having to + // grow the slice. + cw.cwMetricDatumCache = make([]*cloudwatch.MetricDatum, 0, maxMetricDatums) + + go cw.processIncomingMetrics(ctx) + + cw.l.Info("Initialised Cloudwatch surfacer") + return cw, nil +} + +// Write is a function defined to comply with the surfacer interface, and enables the +// cloudwatch surfacer to receive EventMetrics over the buffered channel. +func (cw *CWSurfacer) Write(ctx context.Context, em *metrics.EventMetrics) { + select { + case cw.writeChan <- em: + default: + cw.l.Error("Surfacer's write channel is full, dropping new data.") + } +} diff --git a/surfacers/cloudwatch/cloudwatch_test.go b/surfacers/cloudwatch/cloudwatch_test.go new file mode 100644 index 00000000..2b38c980 --- /dev/null +++ b/surfacers/cloudwatch/cloudwatch_test.go @@ -0,0 +1,379 @@ +// Copyright 2021 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cloudwatch + +import ( + "context" + "reflect" + "regexp" + "strings" + "testing" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/cloudwatch" + "github.com/google/cloudprober/logger" + "github.com/google/cloudprober/metrics" + configpb "github.com/google/cloudprober/surfacers/cloudwatch/proto" +) + +func newTestCWSurfacer() CWSurfacer { + l, _ := logger.New(context.TODO(), "test-logger") + namespace := "sre/test/cloudprober" + resolution := int64(60) + + return CWSurfacer{ + l: l, + allowedMetricsRegex: ®exp.Regexp{}, + c: &configpb.SurfacerConf{ + Namespace: &namespace, + AllowedMetricsRegex: new(string), + Resolution: &resolution, + }, + } +} + +func TestIgnoreMetric(t *testing.T) { + tests := map[string]struct { + surfacer CWSurfacer + regex string + name string + want bool + }{ + "regex default": { + surfacer: newTestCWSurfacer(), + regex: "", + name: "test", + want: false, + }, + "regexp direct match": { + surfacer: newTestCWSurfacer(), + regex: "latency", + name: "latency", + want: false, + }, + "regexp partial match inside optional": { + surfacer: newTestCWSurfacer(), + regex: ".*(http.*|ping).*", + name: "httphttp", + want: false, + }, + "regex ignored": { + surfacer: newTestCWSurfacer(), + regex: ".*(http|ping).*", + name: "sysvar", + want: true, + }, + "regex ignored partial": { + surfacer: newTestCWSurfacer(), + regex: ".*(http.*|ping).*", + name: "httsysvar", + want: true, + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + r, err := regexp.Compile(tc.regex) + if err != nil { + t.Fatalf("Error compiling regex string: %s, error: %s", tc.regex, err) + } + + tc.surfacer.allowedMetricsRegex = r + + got := tc.surfacer.ignoreMetric(tc.name) + if got != tc.want { + t.Errorf("got: %t, want: %t", got, tc.want) + } + }) + } +} + +func TestEmLabelsToDimensions(t *testing.T) { + timestamp := time.Now() + + tests := map[string]struct { + em *metrics.EventMetrics + want []*cloudwatch.Dimension + }{ + "no label": { + em: metrics.NewEventMetrics(timestamp), + want: []*cloudwatch.Dimension{}, + }, + "one label": { + em: metrics.NewEventMetrics(timestamp). + AddLabel("ptype", "sysvars"), + want: []*cloudwatch.Dimension{ + { + Name: aws.String("ptype"), + Value: aws.String("sysvars"), + }, + }, + }, + "three labels": { + em: metrics.NewEventMetrics(timestamp). + AddLabel("ptype", "sysvars"). + AddLabel("probe", "sysvars"). + AddLabel("test", "testing123"), + want: []*cloudwatch.Dimension{ + { + Name: aws.String("ptype"), + Value: aws.String("sysvars"), + }, + { + Name: aws.String("probe"), + Value: aws.String("sysvars"), + }, + { + Name: aws.String("test"), + Value: aws.String("testing123"), + }, + }, + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + got := emLabelsToDimensions(tc.em) + if !reflect.DeepEqual(got, tc.want) { + t.Errorf("got: %v, want: %v", got, tc.want) + } + }) + } +} + +func TestNewCWMetricDatum(t *testing.T) { + timestamp := time.Now() + + tests := map[string]struct { + surfacer CWSurfacer + metricname string + value float64 + dimensions []*cloudwatch.Dimension + timestamp time.Time + duration time.Duration + want *cloudwatch.MetricDatum + }{ + "simple": { + surfacer: newTestCWSurfacer(), + metricname: "testingmetric", + value: float64(20), + dimensions: []*cloudwatch.Dimension{ + { + Name: aws.String("test"), Value: aws.String("value"), + }, + }, + timestamp: timestamp, + want: &cloudwatch.MetricDatum{ + Dimensions: []*cloudwatch.Dimension{ + { + Name: aws.String("test"), Value: aws.String("value"), + }, + }, + MetricName: aws.String("testingmetric"), + Value: aws.Float64(float64(20)), + StorageResolution: aws.Int64(60), + Timestamp: aws.Time(timestamp), + Unit: aws.String(cloudwatch.StandardUnitCount), + }, + }, + "le_dimension_count_unit": { + surfacer: newTestCWSurfacer(), + metricname: "testingmetric", + value: float64(20), + dimensions: []*cloudwatch.Dimension{ + { + Name: aws.String("test"), Value: aws.String("value"), + }, + }, + timestamp: timestamp, + want: &cloudwatch.MetricDatum{ + Dimensions: []*cloudwatch.Dimension{ + { + Name: aws.String("test"), Value: aws.String("value"), + }, + }, + MetricName: aws.String("testingmetric"), + Value: aws.Float64(float64(20)), + StorageResolution: aws.Int64(60), + Timestamp: aws.Time(timestamp), + Unit: aws.String("Count"), + }, + }, + "latency_name_nanosecond_unit": { + surfacer: newTestCWSurfacer(), + metricname: "latency", + value: float64(20), + dimensions: []*cloudwatch.Dimension{ + { + Name: aws.String("name"), Value: aws.String("value"), + }, + }, + timestamp: timestamp, + duration: time.Nanosecond, + want: &cloudwatch.MetricDatum{ + Dimensions: []*cloudwatch.Dimension{ + { + Name: aws.String("name"), Value: aws.String("value"), + }, + }, + MetricName: aws.String("latency"), + Value: aws.Float64(0.00002), + StorageResolution: aws.Int64(60), + Timestamp: aws.Time(timestamp), + Unit: aws.String("Milliseconds"), + }, + }, + "latency_name_microseconds_unit": { + surfacer: newTestCWSurfacer(), + metricname: "latency", + value: float64(20), + dimensions: []*cloudwatch.Dimension{ + { + Name: aws.String("name"), Value: aws.String("value"), + }, + }, + timestamp: timestamp, + duration: time.Microsecond, + want: &cloudwatch.MetricDatum{ + Dimensions: []*cloudwatch.Dimension{ + { + Name: aws.String("name"), Value: aws.String("value"), + }, + }, + MetricName: aws.String("latency"), + Value: aws.Float64(0.02), + StorageResolution: aws.Int64(60), + Timestamp: aws.Time(timestamp), + Unit: aws.String("Milliseconds"), + }, + }, + "latency_name_milliseconds_unit": { + surfacer: newTestCWSurfacer(), + metricname: "latency", + value: float64(20), + dimensions: []*cloudwatch.Dimension{ + { + Name: aws.String("name"), Value: aws.String("value"), + }, + }, + timestamp: timestamp, + duration: time.Millisecond, + want: &cloudwatch.MetricDatum{ + Dimensions: []*cloudwatch.Dimension{ + { + Name: aws.String("name"), Value: aws.String("value"), + }, + }, + MetricName: aws.String("latency"), + Value: aws.Float64(20), + StorageResolution: aws.Int64(60), + Timestamp: aws.Time(timestamp), + Unit: aws.String("Milliseconds"), + }, + }, + "latency_name_seconds_unit": { + surfacer: newTestCWSurfacer(), + metricname: "latency", + value: float64(20), + dimensions: []*cloudwatch.Dimension{ + { + Name: aws.String("name"), Value: aws.String("value"), + }, + }, + timestamp: timestamp, + duration: time.Second, + want: &cloudwatch.MetricDatum{ + Dimensions: []*cloudwatch.Dimension{ + { + Name: aws.String("name"), Value: aws.String("value"), + }, + }, + MetricName: aws.String("latency"), + Value: aws.Float64(20000), + StorageResolution: aws.Int64(60), + Timestamp: aws.Time(timestamp), + Unit: aws.String("Milliseconds"), + }, + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + got := tc.surfacer.newCWMetricDatum( + tc.metricname, + tc.value, + tc.dimensions, + tc.timestamp, + tc.duration, + ) + + if !reflect.DeepEqual(got, tc.want) { + t.Errorf("got: %v, want: %v", got, tc.want) + } + }) + } +} + +func TestCalculateFailureMetric(t *testing.T) { + timestamp := time.Now() + + tests := map[string]struct { + em *metrics.EventMetrics + want float64 + wantErr string + }{ + "simple": { + em: metrics.NewEventMetrics(timestamp). + AddLabel("ptype", "http"). + AddMetric("total", metrics.NewFloat(10)). + AddMetric("success", metrics.NewFloat(5)), + want: float64(5), + wantErr: "", + }, + "string metric": { + em: metrics.NewEventMetrics(timestamp). + AddLabel("ptype", "http"). + AddMetric("total", metrics.NewFloat(10)). + AddMetric("success", metrics.NewString("5")), + want: float64(0), + wantErr: "unexpected", + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + gotFailure, err := calculateFailureMetric(tc.em) + + if !ErrorContains(err, tc.wantErr) { + t.Errorf("unexpected error: %s", err) + } + + if gotFailure != tc.want { + t.Errorf("Return failure metric check: got: %f, want: %f", gotFailure, tc.want) + } + }) + } +} + +func ErrorContains(out error, want string) bool { + if out == nil { + return want == "" + } + if want == "" { + return false + } + return strings.Contains(out.Error(), want) +} diff --git a/surfacers/cloudwatch/proto/config.pb.go b/surfacers/cloudwatch/proto/config.pb.go new file mode 100644 index 00000000..461f3a67 --- /dev/null +++ b/surfacers/cloudwatch/proto/config.pb.go @@ -0,0 +1,188 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.11.2 +// source: github.com/google/cloudprober/surfacers/cloudwatch/proto/config.proto + +package proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type SurfacerConf struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The cloudwatch metric namespace + Namespace *string `protobuf:"bytes,1,opt,name=namespace,def=cloudprober" json:"namespace,omitempty"` + // The cloudwatch resolution value, lowering this below 60 will incur + // additional charges as the metrics will be charged at a high resolution + // rate. + Resolution *int64 `protobuf:"varint,2,opt,name=resolution,def=60" json:"resolution,omitempty"` + // If allowed_metrics_regex is specified, only metrics matching the given + // regular expression will be exported to cloudwatch. This will be evaluated + // against both the probe type and probe name. + // Note: This option may change in future. + // Example: + // allowed_metrics_regex: "(http|ping)" + AllowedMetricsRegex *string `protobuf:"bytes,3,opt,name=allowed_metrics_regex,json=allowedMetricsRegex" json:"allowed_metrics_regex,omitempty"` +} + +// Default values for SurfacerConf fields. +const ( + Default_SurfacerConf_Namespace = string("cloudprober") + Default_SurfacerConf_Resolution = int64(60) +) + +func (x *SurfacerConf) Reset() { + *x = SurfacerConf{} + if protoimpl.UnsafeEnabled { + mi := &file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SurfacerConf) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SurfacerConf) ProtoMessage() {} + +func (x *SurfacerConf) ProtoReflect() protoreflect.Message { + mi := &file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SurfacerConf.ProtoReflect.Descriptor instead. +func (*SurfacerConf) Descriptor() ([]byte, []int) { + return file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_rawDescGZIP(), []int{0} +} + +func (x *SurfacerConf) GetNamespace() string { + if x != nil && x.Namespace != nil { + return *x.Namespace + } + return Default_SurfacerConf_Namespace +} + +func (x *SurfacerConf) GetResolution() int64 { + if x != nil && x.Resolution != nil { + return *x.Resolution + } + return Default_SurfacerConf_Resolution +} + +func (x *SurfacerConf) GetAllowedMetricsRegex() string { + if x != nil && x.AllowedMetricsRegex != nil { + return *x.AllowedMetricsRegex + } + return "" +} + +var File_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto protoreflect.FileDescriptor + +var file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_rawDesc = []byte{ + 0x0a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x72, 0x2f, + 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x73, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x77, + 0x61, 0x74, 0x63, 0x68, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x70, 0x72, + 0x6f, 0x62, 0x65, 0x72, 0x2e, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x2e, 0x63, 0x6c, + 0x6f, 0x75, 0x64, 0x77, 0x61, 0x74, 0x63, 0x68, 0x22, 0x91, 0x01, 0x0a, 0x0c, 0x53, 0x75, 0x72, + 0x66, 0x61, 0x63, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x29, 0x0a, 0x09, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x0b, 0x63, 0x6c, + 0x6f, 0x75, 0x64, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x72, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x12, 0x22, 0x0a, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x3a, 0x02, 0x36, 0x30, 0x52, 0x0a, 0x72, 0x65, + 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x15, 0x61, 0x6c, 0x6c, 0x6f, + 0x77, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x65, + 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, + 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x67, 0x65, 0x78, 0x42, 0x3a, 0x5a, 0x38, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x72, 0x2f, 0x73, 0x75, + 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x73, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x77, 0x61, 0x74, + 0x63, 0x68, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, +} + +var ( + file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_rawDescOnce sync.Once + file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_rawDescData = file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_rawDesc +) + +func file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_rawDescGZIP() []byte { + file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_rawDescOnce.Do(func() { + file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_rawDescData) + }) + return file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_rawDescData +} + +var file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_goTypes = []interface{}{ + (*SurfacerConf)(nil), // 0: cloudprober.surfacer.cloudwatch.SurfacerConf +} +var file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_init() } +func file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_init() { + if File_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SurfacerConf); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_goTypes, + DependencyIndexes: file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_depIdxs, + MessageInfos: file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_msgTypes, + }.Build() + File_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto = out.File + file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_rawDesc = nil + file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_goTypes = nil + file_github_com_google_cloudprober_surfacers_cloudwatch_proto_config_proto_depIdxs = nil +} diff --git a/surfacers/cloudwatch/proto/config.proto b/surfacers/cloudwatch/proto/config.proto new file mode 100644 index 00000000..9c62ab38 --- /dev/null +++ b/surfacers/cloudwatch/proto/config.proto @@ -0,0 +1,23 @@ +syntax = "proto2"; + +package cloudprober.surfacer.cloudwatch; + +option go_package = "github.com/google/cloudprober/surfacers/cloudwatch/proto"; + +message SurfacerConf { + // The cloudwatch metric namespace + optional string namespace = 1 [default = "cloudprober"]; + + // The cloudwatch resolution value, lowering this below 60 will incur + // additional charges as the metrics will be charged at a high resolution + // rate. + optional int64 resolution = 2 [default = 60]; + + // If allowed_metrics_regex is specified, only metrics matching the given + // regular expression will be exported to cloudwatch. This will be evaluated + // against both the probe type and probe name. + // Note: This option may change in future. + // Example: + // allowed_metrics_regex: "(http|ping)" + optional string allowed_metrics_regex = 3; +} diff --git a/surfacers/proto/config.pb.go b/surfacers/proto/config.pb.go index d8c22610..0db6f254 100644 --- a/surfacers/proto/config.pb.go +++ b/surfacers/proto/config.pb.go @@ -7,6 +7,7 @@ package proto import ( + proto5 "github.com/google/cloudprober/surfacers/cloudwatch/proto" proto2 "github.com/google/cloudprober/surfacers/file/proto" proto3 "github.com/google/cloudprober/surfacers/postgres/proto" proto "github.com/google/cloudprober/surfacers/prometheus/proto" @@ -35,6 +36,7 @@ const ( Type_FILE Type = 3 Type_POSTGRES Type = 4 Type_PUBSUB Type = 5 + Type_CLOUDWATCH Type = 6 Type_USER_DEFINED Type = 99 ) @@ -47,6 +49,7 @@ var ( 3: "FILE", 4: "POSTGRES", 5: "PUBSUB", + 6: "CLOUDWATCH", 99: "USER_DEFINED", } Type_value = map[string]int32{ @@ -56,6 +59,7 @@ var ( "FILE": 3, "POSTGRES": 4, "PUBSUB": 5, + "CLOUDWATCH": 6, "USER_DEFINED": 99, } ) @@ -124,6 +128,7 @@ type SurfacerDef struct { // *SurfacerDef_FileSurfacer // *SurfacerDef_PostgresSurfacer // *SurfacerDef_PubsubSurfacer + // *SurfacerDef_CloudwatchSurfacer Surfacer isSurfacerDef_Surfacer `protobuf_oneof:"surfacer"` } @@ -227,6 +232,13 @@ func (x *SurfacerDef) GetPubsubSurfacer() *proto4.SurfacerConf { return nil } +func (x *SurfacerDef) GetCloudwatchSurfacer() *proto5.SurfacerConf { + if x, ok := x.GetSurfacer().(*SurfacerDef_CloudwatchSurfacer); ok { + return x.CloudwatchSurfacer + } + return nil +} + type isSurfacerDef_Surfacer interface { isSurfacerDef_Surfacer() } @@ -251,6 +263,10 @@ type SurfacerDef_PubsubSurfacer struct { PubsubSurfacer *proto4.SurfacerConf `protobuf:"bytes,14,opt,name=pubsub_surfacer,json=pubsubSurfacer,oneof"` } +type SurfacerDef_CloudwatchSurfacer struct { + CloudwatchSurfacer *proto5.SurfacerConf `protobuf:"bytes,15,opt,name=cloudwatch_surfacer,json=cloudwatchSurfacer,oneof"` +} + func (*SurfacerDef_PrometheusSurfacer) isSurfacerDef_Surfacer() {} func (*SurfacerDef_StackdriverSurfacer) isSurfacerDef_Surfacer() {} @@ -261,6 +277,8 @@ func (*SurfacerDef_PostgresSurfacer) isSurfacerDef_Surfacer() {} func (*SurfacerDef_PubsubSurfacer) isSurfacerDef_Surfacer() {} +func (*SurfacerDef_CloudwatchSurfacer) isSurfacerDef_Surfacer() {} + var File_github_com_google_cloudprober_surfacers_proto_config_proto protoreflect.FileDescriptor var file_github_com_google_cloudprober_surfacers_proto_config_proto_rawDesc = []byte{ @@ -290,55 +308,66 @@ var file_github_com_google_cloudprober_surfacers_proto_config_proto_rawDesc = [] 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x72, 0x2f, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x73, 0x2f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdd, 0x04, 0x0a, 0x0b, 0x53, - 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x44, 0x65, 0x66, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2e, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, + 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x45, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, + 0x6f, 0x75, 0x64, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x72, 0x2f, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, + 0x65, 0x72, 0x73, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x77, 0x61, 0x74, 0x63, 0x68, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0xbf, 0x05, 0x0a, 0x0b, 0x53, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x44, 0x65, + 0x66, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x70, 0x72, 0x6f, 0x62, 0x65, + 0x72, 0x2e, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x35, 0x0a, 0x13, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, + 0x5f, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x03, 0x3a, 0x05, 0x31, 0x30, 0x30, 0x30, 0x30, 0x52, 0x11, 0x6d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x73, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x60, 0x0a, 0x13, + 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x5f, 0x73, 0x75, 0x72, 0x66, 0x61, + 0x63, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6c, 0x6f, 0x75, + 0x64, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x72, 0x2e, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x53, 0x75, 0x72, 0x66, + 0x61, 0x63, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x48, 0x00, 0x52, 0x12, 0x70, 0x72, 0x6f, 0x6d, + 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x53, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x12, 0x63, + 0x0a, 0x14, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x73, 0x75, + 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x72, 0x2e, 0x73, 0x75, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x35, - 0x0a, 0x13, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, - 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x3a, 0x05, 0x31, 0x30, 0x30, - 0x30, 0x30, 0x52, 0x11, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x42, 0x75, 0x66, 0x66, 0x65, - 0x72, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, - 0x65, 0x75, 0x73, 0x5f, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, + 0x63, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x2e, + 0x53, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x48, 0x00, 0x52, 0x13, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x53, 0x75, 0x72, 0x66, 0x61, + 0x63, 0x65, 0x72, 0x12, 0x4e, 0x0a, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x73, 0x75, 0x72, 0x66, + 0x61, 0x63, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6c, 0x6f, + 0x75, 0x64, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x72, 0x2e, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, + 0x72, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x53, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x43, + 0x6f, 0x6e, 0x66, 0x48, 0x00, 0x52, 0x0c, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x75, 0x72, 0x66, 0x61, + 0x63, 0x65, 0x72, 0x12, 0x5a, 0x0a, 0x11, 0x70, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x73, 0x5f, + 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, + 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x72, 0x2e, 0x73, 0x75, 0x72, + 0x66, 0x61, 0x63, 0x65, 0x72, 0x2e, 0x70, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x73, 0x2e, 0x53, + 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x48, 0x00, 0x52, 0x10, 0x70, + 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x73, 0x53, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x12, + 0x54, 0x0a, 0x0f, 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, 0x5f, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, + 0x65, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, + 0x70, 0x72, 0x6f, 0x62, 0x65, 0x72, 0x2e, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x2e, + 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, 0x2e, 0x53, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x43, + 0x6f, 0x6e, 0x66, 0x48, 0x00, 0x52, 0x0e, 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, 0x53, 0x75, 0x72, + 0x66, 0x61, 0x63, 0x65, 0x72, 0x12, 0x60, 0x0a, 0x13, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x77, 0x61, + 0x74, 0x63, 0x68, 0x5f, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x72, - 0x2e, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, - 0x68, 0x65, 0x75, 0x73, 0x2e, 0x53, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x43, 0x6f, 0x6e, - 0x66, 0x48, 0x00, 0x52, 0x12, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x53, - 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x12, 0x63, 0x0a, 0x14, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x18, - 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x70, 0x72, 0x6f, - 0x62, 0x65, 0x72, 0x2e, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x61, - 0x63, 0x6b, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x48, 0x00, 0x52, 0x13, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x64, 0x72, - 0x69, 0x76, 0x65, 0x72, 0x53, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x12, 0x4e, 0x0a, 0x0d, - 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x18, 0x0c, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x70, 0x72, 0x6f, 0x62, 0x65, - 0x72, 0x2e, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, - 0x53, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x48, 0x00, 0x52, 0x0c, - 0x66, 0x69, 0x6c, 0x65, 0x53, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x12, 0x5a, 0x0a, 0x11, - 0x70, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x73, 0x5f, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x70, - 0x72, 0x6f, 0x62, 0x65, 0x72, 0x2e, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x2e, 0x70, - 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x73, 0x2e, 0x53, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, - 0x43, 0x6f, 0x6e, 0x66, 0x48, 0x00, 0x52, 0x10, 0x70, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x73, - 0x53, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x12, 0x54, 0x0a, 0x0f, 0x70, 0x75, 0x62, 0x73, - 0x75, 0x62, 0x5f, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x72, 0x2e, - 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x2e, 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, 0x2e, - 0x53, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x48, 0x00, 0x52, 0x0e, - 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, 0x53, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x42, 0x0a, - 0x0a, 0x08, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x2a, 0x67, 0x0a, 0x04, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, - 0x50, 0x52, 0x4f, 0x4d, 0x45, 0x54, 0x48, 0x45, 0x55, 0x53, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, - 0x53, 0x54, 0x41, 0x43, 0x4b, 0x44, 0x52, 0x49, 0x56, 0x45, 0x52, 0x10, 0x02, 0x12, 0x08, 0x0a, - 0x04, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x4f, 0x53, 0x54, 0x47, - 0x52, 0x45, 0x53, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x55, 0x42, 0x53, 0x55, 0x42, 0x10, - 0x05, 0x12, 0x10, 0x0a, 0x0c, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x45, 0x46, 0x49, 0x4e, 0x45, - 0x44, 0x10, 0x63, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x70, 0x72, - 0x6f, 0x62, 0x65, 0x72, 0x2f, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x73, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x77, + 0x61, 0x74, 0x63, 0x68, 0x2e, 0x53, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x43, 0x6f, 0x6e, + 0x66, 0x48, 0x00, 0x52, 0x12, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x77, 0x61, 0x74, 0x63, 0x68, 0x53, + 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x42, 0x0a, 0x0a, 0x08, 0x73, 0x75, 0x72, 0x66, 0x61, + 0x63, 0x65, 0x72, 0x2a, 0x77, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4e, + 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x4f, 0x4d, 0x45, 0x54, 0x48, + 0x45, 0x55, 0x53, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x44, 0x52, + 0x49, 0x56, 0x45, 0x52, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x03, + 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x10, 0x04, 0x12, 0x0a, + 0x0a, 0x06, 0x50, 0x55, 0x42, 0x53, 0x55, 0x42, 0x10, 0x05, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x4c, + 0x4f, 0x55, 0x44, 0x57, 0x41, 0x54, 0x43, 0x48, 0x10, 0x06, 0x12, 0x10, 0x0a, 0x0c, 0x55, 0x53, + 0x45, 0x52, 0x5f, 0x44, 0x45, 0x46, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x63, 0x42, 0x2f, 0x5a, 0x2d, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x72, 0x2f, 0x73, 0x75, + 0x72, 0x66, 0x61, 0x63, 0x65, 0x72, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, } var ( @@ -363,6 +392,7 @@ var file_github_com_google_cloudprober_surfacers_proto_config_proto_goTypes = [] (*proto2.SurfacerConf)(nil), // 4: cloudprober.surfacer.file.SurfacerConf (*proto3.SurfacerConf)(nil), // 5: cloudprober.surfacer.postgres.SurfacerConf (*proto4.SurfacerConf)(nil), // 6: cloudprober.surfacer.pubsub.SurfacerConf + (*proto5.SurfacerConf)(nil), // 7: cloudprober.surfacer.cloudwatch.SurfacerConf } var file_github_com_google_cloudprober_surfacers_proto_config_proto_depIdxs = []int32{ 0, // 0: cloudprober.surfacer.SurfacerDef.type:type_name -> cloudprober.surfacer.Type @@ -371,11 +401,12 @@ var file_github_com_google_cloudprober_surfacers_proto_config_proto_depIdxs = [] 4, // 3: cloudprober.surfacer.SurfacerDef.file_surfacer:type_name -> cloudprober.surfacer.file.SurfacerConf 5, // 4: cloudprober.surfacer.SurfacerDef.postgres_surfacer:type_name -> cloudprober.surfacer.postgres.SurfacerConf 6, // 5: cloudprober.surfacer.SurfacerDef.pubsub_surfacer:type_name -> cloudprober.surfacer.pubsub.SurfacerConf - 6, // [6:6] is the sub-list for method output_type - 6, // [6:6] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 7, // 6: cloudprober.surfacer.SurfacerDef.cloudwatch_surfacer:type_name -> cloudprober.surfacer.cloudwatch.SurfacerConf + 7, // [7:7] is the sub-list for method output_type + 7, // [7:7] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name } func init() { file_github_com_google_cloudprober_surfacers_proto_config_proto_init() } @@ -403,6 +434,7 @@ func file_github_com_google_cloudprober_surfacers_proto_config_proto_init() { (*SurfacerDef_FileSurfacer)(nil), (*SurfacerDef_PostgresSurfacer)(nil), (*SurfacerDef_PubsubSurfacer)(nil), + (*SurfacerDef_CloudwatchSurfacer)(nil), } type x struct{} out := protoimpl.TypeBuilder{ diff --git a/surfacers/proto/config.proto b/surfacers/proto/config.proto index 0922a6f5..336bb468 100644 --- a/surfacers/proto/config.proto +++ b/surfacers/proto/config.proto @@ -7,6 +7,7 @@ import "github.com/google/cloudprober/surfacers/postgres/proto/config.proto"; import "github.com/google/cloudprober/surfacers/prometheus/proto/config.proto"; import "github.com/google/cloudprober/surfacers/pubsub/proto/config.proto"; import "github.com/google/cloudprober/surfacers/stackdriver/proto/config.proto"; +import "github.com/google/cloudprober/surfacers/cloudwatch/proto/config.proto"; option go_package = "github.com/google/cloudprober/surfacers/proto"; @@ -18,6 +19,7 @@ enum Type { FILE = 3; POSTGRES = 4; PUBSUB = 5; + CLOUDWATCH = 6; USER_DEFINED = 99; } @@ -46,5 +48,6 @@ message SurfacerDef { file.SurfacerConf file_surfacer = 12; postgres.SurfacerConf postgres_surfacer = 13; pubsub.SurfacerConf pubsub_surfacer = 14; + cloudwatch.SurfacerConf cloudwatch_surfacer = 15; } } diff --git a/surfacers/surfacers.go b/surfacers/surfacers.go index c77e90ab..4faa464a 100644 --- a/surfacers/surfacers.go +++ b/surfacers/surfacers.go @@ -1,4 +1,4 @@ -// Copyright 2017 Google Inc. +// Copyright 2017-2021 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ import ( "github.com/google/cloudprober/logger" "github.com/google/cloudprober/metrics" + "github.com/google/cloudprober/surfacers/cloudwatch" "github.com/google/cloudprober/surfacers/common/options" "github.com/google/cloudprober/surfacers/file" "github.com/google/cloudprober/surfacers/postgres" @@ -112,6 +113,8 @@ func inferType(s *surfacerpb.SurfacerDef) surfacerspb.Type { return surfacerspb.Type_POSTGRES case *surfacerpb.SurfacerDef_PubsubSurfacer: return surfacerspb.Type_PUBSUB + case *surfacerpb.SurfacerDef_CloudwatchSurfacer: + return surfacerspb.Type_CLOUDWATCH } return surfacerspb.Type_NONE @@ -153,6 +156,9 @@ func initSurfacer(ctx context.Context, s *surfacerpb.SurfacerDef, sType surfacer case surfacerpb.Type_PUBSUB: surfacer, err = pubsub.New(ctx, s.GetPubsubSurfacer(), opts, l) conf = s.GetPubsubSurfacer() + case surfacerpb.Type_CLOUDWATCH: + surfacer, err = cloudwatch.New(ctx, s.GetCloudwatchSurfacer(), opts, l) + conf = s.GetCloudwatchSurfacer() case surfacerpb.Type_USER_DEFINED: userDefinedSurfacersMu.Lock() defer userDefinedSurfacersMu.Unlock() diff --git a/tools/gen_pb_go.sh b/tools/gen_pb_go.sh index e82a5aea..70913272 100755 --- a/tools/gen_pb_go.sh +++ b/tools/gen_pb_go.sh @@ -16,7 +16,7 @@ # This script generates Go code for the config protobufs. -PROTOC_VERSION="3.3.0" +PROTOC_VERSION="3.11.2" PROJECT="github.com/google/cloudprober" GOPATH=$(go env GOPATH) @@ -104,4 +104,3 @@ find $PROJECT -type d | \ ${protoc_path} --go_out=plugins=grpc:. ${dir}/*.proto done cd - -