Skip to content
This repository was archived by the owner on Oct 3, 2023. It is now read-only.

Commit dc2fe43

Browse files
authored
Batch time series with different label values into same request. (#119)
* Batch timeseries with different label values into same request. * fixed one more review comment.
1 parent 0ca8377 commit dc2fe43

3 files changed

Lines changed: 44 additions & 60 deletions

File tree

metrics_proto.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import (
2424
"errors"
2525
"fmt"
2626
"path"
27+
"sort"
28+
"strings"
2729

2830
"github.com/golang/protobuf/ptypes/timestamp"
2931
"go.opencensus.io/stats"
@@ -117,6 +119,20 @@ func (se *statsExporter) handleMetricsProtoUpload(payloads []*metricProtoPayload
117119
return nil
118120
}
119121

122+
// metricSignature creates a unique signature consisting of a
123+
// metric's type and its lexicographically sorted label values
124+
// See https://github.com/census-ecosystem/opencensus-go-exporter-stackdriver/issues/120
125+
func metricSignature(metric *googlemetricpb.Metric) string {
126+
labels := metric.GetLabels()
127+
labelValues := make([]string, 0, len(labels))
128+
129+
for _, labelValue := range labels {
130+
labelValues = append(labelValues, labelValue)
131+
}
132+
sort.Strings(labelValues)
133+
return fmt.Sprintf("%s:%s", metric.GetType(), strings.Join(labelValues, ","))
134+
}
135+
120136
func (se *statsExporter) combineTimeSeriesToCreateTimeSeriesRequest(ts []*monitoringpb.TimeSeries) (ctsreql []*monitoringpb.CreateTimeSeriesRequest) {
121137
if len(ts) == 0 {
122138
return nil
@@ -139,10 +155,10 @@ func (se *statsExporter) combineTimeSeriesToCreateTimeSeriesRequest(ts []*monito
139155
seenMetrics := make(map[string]struct{})
140156

141157
for _, tti := range ts {
142-
signature := tti.Metric.GetType()
143-
if _, alreadySeen := seenMetrics[signature]; !alreadySeen {
158+
key := metricSignature(tti.Metric)
159+
if _, alreadySeen := seenMetrics[key]; !alreadySeen {
144160
uniqueTimeSeries = append(uniqueTimeSeries, tti)
145-
seenMetrics[signature] = struct{}{}
161+
seenMetrics[key] = struct{}{}
146162
} else {
147163
nonUniqueTimeSeries = append(nonUniqueTimeSeries, tti)
148164
}

metrics_proto_test.go

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -397,11 +397,17 @@ func TestCombineTimeSeriesAndDeduplication(t *testing.T) {
397397
{
398398
Metric: &googlemetricpb.Metric{
399399
Type: "a/b/c",
400+
Labels: map[string]string{
401+
"k1": "v1",
402+
},
400403
},
401404
},
402405
{
403406
Metric: &googlemetricpb.Metric{
404407
Type: "a/b/c",
408+
Labels: map[string]string{
409+
"k1": "v2",
410+
},
405411
},
406412
},
407413
{
@@ -412,6 +418,9 @@ func TestCombineTimeSeriesAndDeduplication(t *testing.T) {
412418
{
413419
Metric: &googlemetricpb.Metric{
414420
Type: "a/b/c",
421+
Labels: map[string]string{
422+
"k1": "v1",
423+
},
415424
},
416425
},
417426
{
@@ -427,26 +436,27 @@ func TestCombineTimeSeriesAndDeduplication(t *testing.T) {
427436
{
428437
Metric: &googlemetricpb.Metric{
429438
Type: "a/b/c",
439+
Labels: map[string]string{
440+
"k1": "v1",
441+
},
430442
},
431443
},
432444
{
433445
Metric: &googlemetricpb.Metric{
434-
Type: "A/b/c",
446+
Type: "a/b/c",
447+
Labels: map[string]string{
448+
"k1": "v2",
449+
},
435450
},
436451
},
437452
{
438453
Metric: &googlemetricpb.Metric{
439-
Type: "X/Y/Z",
454+
Type: "A/b/c",
440455
},
441456
},
442-
},
443-
},
444-
{
445-
Name: monitoring.MetricProjectPath(se.o.ProjectID),
446-
TimeSeries: []*monitoringpb.TimeSeries{
447457
{
448458
Metric: &googlemetricpb.Metric{
449-
Type: "a/b/c",
459+
Type: "X/Y/Z",
450460
},
451461
},
452462
},
@@ -457,6 +467,9 @@ func TestCombineTimeSeriesAndDeduplication(t *testing.T) {
457467
{
458468
Metric: &googlemetricpb.Metric{
459469
Type: "a/b/c",
470+
Labels: map[string]string{
471+
"k1": "v1",
472+
},
460473
},
461474
},
462475
},

stats_test.go

Lines changed: 4 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,6 @@ func TestExporter_makeReq(t *testing.T) {
138138
},
139139
},
140140
},
141-
},
142-
},
143-
{
144-
Name: monitoring.MetricProjectPath("proj-id"),
145-
TimeSeries: []*monitoringpb.TimeSeries{
146141
{
147142
Metric: &metricpb.Metric{
148143
Type: "custom.googleapis.com/opencensus/example.com/views/testview",
@@ -218,11 +213,6 @@ func TestExporter_makeReq(t *testing.T) {
218213
},
219214
},
220215
},
221-
},
222-
},
223-
{
224-
Name: monitoring.MetricProjectPath("proj-id"),
225-
TimeSeries: []*monitoringpb.TimeSeries{
226216
{
227217
Metric: &metricpb.Metric{
228218
Type: "external.googleapis.com/example.com/views/testview",
@@ -293,11 +283,6 @@ func TestExporter_makeReq(t *testing.T) {
293283
},
294284
},
295285
},
296-
},
297-
},
298-
{
299-
Name: monitoring.MetricProjectPath("proj-id"),
300-
TimeSeries: []*monitoringpb.TimeSeries{
301286
{
302287
Metric: &metricpb.Metric{
303288
Type: "custom.googleapis.com/opencensus/example.com/views/testview",
@@ -364,11 +349,6 @@ func TestExporter_makeReq(t *testing.T) {
364349
},
365350
},
366351
},
367-
},
368-
},
369-
{
370-
Name: monitoring.MetricProjectPath("proj-id"),
371-
TimeSeries: []*monitoringpb.TimeSeries{
372352
{
373353
Metric: &metricpb.Metric{
374354
Type: "custom.googleapis.com/opencensus/lasttestview",
@@ -542,21 +522,21 @@ func TestExporter_makeReq_batching(t *testing.T) {
542522
name: "4 vds; 3 limit",
543523
iter: 2,
544524
limit: 3,
545-
wantReqs: 4,
525+
wantReqs: 3,
546526
wantTotal: 4,
547527
},
548528
{
549529
name: "4 vds; 4 limit",
550530
iter: 2,
551531
limit: 4,
552-
wantReqs: 4,
532+
wantReqs: 2,
553533
wantTotal: 4,
554534
},
555535
{
556536
name: "4 vds; 5 limit",
557537
iter: 2,
558538
limit: 5,
559-
wantReqs: 4,
539+
wantReqs: 2,
560540
wantTotal: 4,
561541
},
562542
}
@@ -996,11 +976,6 @@ func TestExporter_makeReq_withCustomMonitoredResource(t *testing.T) {
996976
},
997977
},
998978
},
999-
},
1000-
},
1001-
{
1002-
Name: monitoring.MetricProjectPath("proj-id"),
1003-
TimeSeries: []*monitoringpb.TimeSeries{
1004979
{
1005980
Metric: &metricpb.Metric{
1006981
Type: "custom.googleapis.com/opencensus/testview",
@@ -1074,11 +1049,6 @@ func TestExporter_makeReq_withCustomMonitoredResource(t *testing.T) {
10741049
},
10751050
},
10761051
},
1077-
},
1078-
},
1079-
{
1080-
Name: monitoring.MetricProjectPath("proj-id"),
1081-
TimeSeries: []*monitoringpb.TimeSeries{
10821052
{
10831053
Metric: &metricpb.Metric{
10841054
Type: "custom.googleapis.com/opencensus/testview",
@@ -1154,11 +1124,6 @@ func TestExporter_makeReq_withCustomMonitoredResource(t *testing.T) {
11541124
},
11551125
},
11561126
},
1157-
},
1158-
},
1159-
{
1160-
Name: monitoring.MetricProjectPath("proj-id"),
1161-
TimeSeries: []*monitoringpb.TimeSeries{
11621127
{
11631128
Metric: &metricpb.Metric{
11641129
Type: "custom.googleapis.com/opencensus/testview",
@@ -1232,11 +1197,6 @@ func TestExporter_makeReq_withCustomMonitoredResource(t *testing.T) {
12321197
},
12331198
},
12341199
},
1235-
},
1236-
},
1237-
{
1238-
Name: monitoring.MetricProjectPath("proj-id"),
1239-
TimeSeries: []*monitoringpb.TimeSeries{
12401200
{
12411201
Metric: &metricpb.Metric{
12421202
Type: "custom.googleapis.com/opencensus/testview",
@@ -1303,11 +1263,6 @@ func TestExporter_makeReq_withCustomMonitoredResource(t *testing.T) {
13031263
},
13041264
},
13051265
},
1306-
},
1307-
},
1308-
{
1309-
Name: monitoring.MetricProjectPath("proj-id"),
1310-
TimeSeries: []*monitoringpb.TimeSeries{
13111266
{
13121267
Metric: &metricpb.Metric{
13131268
Type: "custom.googleapis.com/opencensus/testview",
@@ -1414,7 +1369,7 @@ func TestExporter_customContext(t *testing.T) {
14141369
if ctx.Err() != context.DeadlineExceeded {
14151370
t.Errorf("expected context to time out; got %v", ctx.Err())
14161371
}
1417-
if timedOut != 3 {
1372+
if timedOut != 2 {
14181373
t.Errorf("expected two functions to time out; got %d", timedOut)
14191374
}
14201375
}

0 commit comments

Comments
 (0)