Skip to content

Commit

Permalink
Customize monitoringURL prefix for Stackdriver metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
kushal288 committed Mar 2, 2023
1 parent 4f729ce commit 8a3f78f
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 20 deletions.
111 changes: 97 additions & 14 deletions surfacers/stackdriver/proto/config.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions surfacers/stackdriver/proto/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,12 @@ message SurfacerConf {
// processing is paused while serving data to Stackdriver. This buffer is to
// make writes to Stackdriver surfacer non-blocking.
optional int64 metrics_buffer_size = 5 [default = 10000];

enum MetricPrefix {
NONE = 0; // monitoring_url/metric_name
PROBE = 1; // monitoring_url/probe/metric_name
PTYPE_PROBE = 2; // monitoring_url/ptype/probe/metric_name
}
optional MetricPrefix metrics_prefix = 6
[default = PTYPE_PROBE]; // using current behavior as default
}
19 changes: 19 additions & 0 deletions surfacers/stackdriver/proto/config_proto_gen.cue
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,23 @@ package proto
// processing is paused while serving data to Stackdriver. This buffer is to
// make writes to Stackdriver surfacer non-blocking.
metricsBufferSize?: int64 @protobuf(5,int64,name=metrics_buffer_size,"default=10000")

#MetricPrefix: {
"NONE"// monitoring_url/metric_name
#enumValue: 0
} | {
"PROBE"// monitoring_url/probe/metric_name
#enumValue: 1
} | {
"PTYPE_PROBE"// monitoring_url/ptype/probe/metric_name
#enumValue: 2
}

#MetricPrefix_value: {
NONE: 0
PROBE: 1
PTYPE_PROBE: 2
}

metricsPrefix?: #MetricPrefix @protobuf(6,MetricPrefix,name=metrics_prefix,"default=PTYPE_PROBE") // using current behavior as default
}
16 changes: 10 additions & 6 deletions surfacers/stackdriver/stackdriver.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,16 +332,20 @@ func (s *SDSurfacer) sdKind(kind metrics.Kind) string {
// - a labels key of the form label1_key=label1_val,label2_key=label2_val,
// used for caching.
// - prefix for metric names, usually <ptype>/<probe>.
func processLabels(em *metrics.EventMetrics) (labels map[string]string, labelsKey, metricPrefix string) {
func (s *SDSurfacer) processLabels(em *metrics.EventMetrics) (labels map[string]string, labelsKey, metricPrefix string) {
labels = make(map[string]string)
var sortedLabels []string // we use this for cache key below
var ptype, probe string
metricPrefixConfig := s.c.GetMetricsPrefix()
usePType := true && metricPrefixConfig == configpb.SurfacerConf_PTYPE_PROBE
useProbe := true && metricPrefixConfig == configpb.SurfacerConf_PTYPE_PROBE ||
metricPrefixConfig == configpb.SurfacerConf_PROBE
for _, k := range em.LabelsKeys() {
if k == "ptype" {
if k == "ptype" && usePType {
ptype = em.Label(k)
continue
}
if k == "probe" {
if k == "probe" && useProbe {
probe = em.Label(k)
continue
}
Expand All @@ -350,10 +354,10 @@ func processLabels(em *metrics.EventMetrics) (labels map[string]string, labelsKe
}
labelsKey = strings.Join(sortedLabels, ",")

if ptype != "" {
if ptype != "" && usePType {
metricPrefix += ptype + "/"
}
if probe != "" {
if probe != "" && useProbe {
metricPrefix += probe + "/"
}
return
Expand Down Expand Up @@ -387,7 +391,7 @@ func (s *SDSurfacer) recordEventMetrics(em *metrics.EventMetrics) (ts []*monitor
return
}

emLabels, cacheKey, metricPrefix := processLabels(em)
emLabels, cacheKey, metricPrefix := s.processLabels(em)

for _, k := range em.MetricsKeys() {
if !s.opts.AllowMetric(k) {
Expand Down
73 changes: 73 additions & 0 deletions surfacers/stackdriver/stackdriver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ import (
"testing"
"time"

"github.com/golang/protobuf/proto"
"github.com/cloudprober/cloudprober/logger"
"github.com/cloudprober/cloudprober/metrics"
"github.com/kylelemons/godebug/pretty"
configpb "github.com/cloudprober/cloudprober/surfacers/stackdriver/proto"
monitoring "google.golang.org/api/monitoring/v3"
)

Expand All @@ -46,6 +48,77 @@ func newTestSurfacer() SDSurfacer {
}
}

func TestProcessLabels(t *testing.T) {
s:= newTestSurfacer()
s.c = &configpb.SurfacerConf{
MetricsPrefix: configpb.SurfacerConf_PTYPE_PROBE.Enum(),
MonitoringUrl: proto.String("custom.googleapis.com/cloudprober/"),
}
testTimestamp := time.Now()
testProbe := "test_probe"
testPtype := "external"

tests := []struct {
description string
metricPrefixConfig *configpb.SurfacerConf_MetricPrefix
em *metrics.EventMetrics
wantKeys string
wantMetricPrefix string
}{
{
description: "metrics prefix with ptype and probe",
metricPrefixConfig: configpb.SurfacerConf_PTYPE_PROBE.Enum(),
em: metrics.NewEventMetrics(testTimestamp).
AddMetric("test_metric", metrics.NewString("metval")).
AddLabel("keyA", "valueA").
AddLabel("keyB", "valueB").
AddLabel("probe", testProbe).
AddLabel("ptype", testPtype),
wantKeys: "keyA=valueA,keyB=valueB",
wantMetricPrefix: "external/test_probe/",
},
{
description: "metrics prefix with only probe",
metricPrefixConfig: configpb.SurfacerConf_PROBE.Enum(),
em: metrics.NewEventMetrics(testTimestamp).
AddMetric("test_metric", metrics.NewString("metval")).
AddLabel("keyA", "valueA").
AddLabel("keyB", "valueB").
AddLabel("probe", testProbe).
AddLabel("ptype", testPtype),
wantKeys: "keyA=valueA,keyB=valueB,ptype=external",
wantMetricPrefix: "test_probe/",
},
{
description: "metrics prefix with none",
metricPrefixConfig: configpb.SurfacerConf_NONE.Enum(),
em: metrics.NewEventMetrics(testTimestamp).
AddMetric("test_metric", metrics.NewString("metval")).
AddLabel("keyA", "valueA").
AddLabel("keyB", "valueB").
AddLabel("probe", testProbe).
AddLabel("ptype", testPtype),
wantKeys: "keyA=valueA,keyB=valueB,probe=test_probe,ptype=external",
wantMetricPrefix: "",
},
}

for _, tt := range tests {
s.c = &configpb.SurfacerConf{
MetricsPrefix: tt.metricPrefixConfig,
}
_, key, metricPrefix := s.processLabels(tt.em)
if key != tt.wantKeys {
t.Errorf("Failed test: %s, expected keys: %s, actual: %s",
tt.description, tt.wantKeys, key)
}
if metricPrefix != tt.wantMetricPrefix {
t.Errorf("Failed test: %s, expected metricPrefix: %s, actual: %s",
tt.description, tt.wantMetricPrefix, metricPrefix)
}
}
}

func TestTimeSeries(t *testing.T) {
testTimestamp := time.Now()

Expand Down

0 comments on commit 8a3f78f

Please sign in to comment.