Skip to content

Commit 9fd1d2e

Browse files
committed
Make the batch processor limit data points rather than metrics.
1 parent 51281a7 commit 9fd1d2e

File tree

6 files changed

+103
-51
lines changed

6 files changed

+103
-51
lines changed

consumer/pdata/metric.go

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -127,31 +127,41 @@ func (md Metrics) MetricAndDataPointCount() (metricCount int, dataPointCount int
127127
ilm := ilms.At(j)
128128
metrics := ilm.Metrics()
129129
metricCount += metrics.Len()
130-
ms := ilm.Metrics()
131-
for k := 0; k < ms.Len(); k++ {
132-
m := ms.At(k)
133-
switch m.DataType() {
134-
case MetricDataTypeIntGauge:
135-
dataPointCount += m.IntGauge().DataPoints().Len()
136-
case MetricDataTypeDoubleGauge:
137-
dataPointCount += m.DoubleGauge().DataPoints().Len()
138-
case MetricDataTypeIntSum:
139-
dataPointCount += m.IntSum().DataPoints().Len()
140-
case MetricDataTypeDoubleSum:
141-
dataPointCount += m.DoubleSum().DataPoints().Len()
142-
case MetricDataTypeIntHistogram:
143-
dataPointCount += m.IntHistogram().DataPoints().Len()
144-
case MetricDataTypeHistogram:
145-
dataPointCount += m.Histogram().DataPoints().Len()
146-
case MetricDataTypeSummary:
147-
dataPointCount += m.Summary().DataPoints().Len()
148-
}
149-
}
130+
dataPointCount += ilm.Metrics().DataPointCount()
150131
}
151132
}
152133
return
153134
}
154135

136+
// DataPointCount calculates the total number of data points.
137+
func (ms MetricSlice) DataPointCount() (dataPointCount int) {
138+
for k := 0; k < ms.Len(); k++ {
139+
dataPointCount += ms.At(k).DataPointCount()
140+
}
141+
return
142+
}
143+
144+
// DataPointCount calculates the total number of data points.
145+
func (ms Metric) DataPointCount() (dataPointCount int) {
146+
switch ms.DataType() {
147+
case MetricDataTypeIntGauge:
148+
dataPointCount = ms.IntGauge().DataPoints().Len()
149+
case MetricDataTypeDoubleGauge:
150+
dataPointCount = ms.DoubleGauge().DataPoints().Len()
151+
case MetricDataTypeIntSum:
152+
dataPointCount = ms.IntSum().DataPoints().Len()
153+
case MetricDataTypeDoubleSum:
154+
dataPointCount = ms.DoubleSum().DataPoints().Len()
155+
case MetricDataTypeIntHistogram:
156+
dataPointCount = ms.IntHistogram().DataPoints().Len()
157+
case MetricDataTypeHistogram:
158+
dataPointCount = ms.Histogram().DataPoints().Len()
159+
case MetricDataTypeSummary:
160+
dataPointCount = ms.Summary().DataPoints().Len()
161+
}
162+
return
163+
}
164+
155165
// MetricDataType specifies the type of data in a Metric.
156166
type MetricDataType int32
157167

processor/batchprocessor/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ any data drops such as sampling.
1515
Please refer to [config.go](./config.go) for the config spec.
1616

1717
The following configuration options can be modified:
18-
- `send_batch_size` (default = 8192): Number of spans or metrics after which a
19-
batch will be sent regardless of the timeout.
18+
- `send_batch_size` (default = 8192): Number of spans or data point in metrics
19+
after which a batch will be sent regardless of the timeout.
2020
- `timeout` (default = 200ms): Time duration after which a batch will be sent
2121
regardless of size.
2222
- `send_batch_max_size` (default = 0): The upper limit of the batch size.

processor/batchprocessor/batch_processor.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,9 @@ func (bt *batchTraces) size() int {
263263
}
264264

265265
type batchMetrics struct {
266-
nextConsumer consumer.Metrics
267-
metricData pdata.Metrics
268-
metricCount int
266+
nextConsumer consumer.Metrics
267+
metricData pdata.Metrics
268+
dataPointCount int
269269
}
270270

271271
func newBatchMetrics(nextConsumer consumer.Metrics) *batchMetrics {
@@ -274,19 +274,19 @@ func newBatchMetrics(nextConsumer consumer.Metrics) *batchMetrics {
274274

275275
func (bm *batchMetrics) export(ctx context.Context, sendBatchMaxSize int) error {
276276
var req pdata.Metrics
277-
if sendBatchMaxSize > 0 && bm.metricCount > sendBatchMaxSize {
277+
if sendBatchMaxSize > 0 && bm.dataPointCount > sendBatchMaxSize {
278278
req = splitMetrics(sendBatchMaxSize, bm.metricData)
279-
bm.metricCount -= sendBatchMaxSize
279+
bm.dataPointCount -= sendBatchMaxSize
280280
} else {
281281
req = bm.metricData
282282
bm.metricData = pdata.NewMetrics()
283-
bm.metricCount = 0
283+
bm.dataPointCount = 0
284284
}
285285
return bm.nextConsumer.ConsumeMetrics(ctx, req)
286286
}
287287

288288
func (bm *batchMetrics) itemCount() int {
289-
return bm.metricCount
289+
return bm.dataPointCount
290290
}
291291

292292
func (bm *batchMetrics) size() int {
@@ -296,11 +296,11 @@ func (bm *batchMetrics) size() int {
296296
func (bm *batchMetrics) add(item interface{}) {
297297
md := item.(pdata.Metrics)
298298

299-
newMetricsCount := md.MetricCount()
300-
if newMetricsCount == 0 {
299+
_, newDataPointCount := md.MetricAndDataPointCount()
300+
if newDataPointCount == 0 {
301301
return
302302
}
303-
bm.metricCount += newMetricsCount
303+
bm.dataPointCount += newDataPointCount
304304
md.ResourceMetrics().MoveAndAppendTo(bm.metricData.ResourceMetrics())
305305
}
306306

processor/batchprocessor/batch_processor_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,8 @@ func TestBatchMetricProcessor_BatchSize(t *testing.T) {
320320

321321
requestCount := 100
322322
metricsPerRequest := 5
323+
dataPointsPreMetric := 2 // Since the int counter uses two datapoints.
324+
dataPointsPerRequest := metricsPerRequest * dataPointsPreMetric
323325
sink := new(consumertest.MetricsSink)
324326

325327
createParams := component.ProcessorCreateParams{Logger: zap.NewNop()}
@@ -339,8 +341,8 @@ func TestBatchMetricProcessor_BatchSize(t *testing.T) {
339341
elapsed := time.Since(start)
340342
require.LessOrEqual(t, elapsed.Nanoseconds(), cfg.Timeout.Nanoseconds())
341343

342-
expectedBatchesNum := requestCount * metricsPerRequest / int(cfg.SendBatchSize)
343-
expectedBatchingFactor := int(cfg.SendBatchSize) / metricsPerRequest
344+
expectedBatchesNum := requestCount * dataPointsPerRequest / int(cfg.SendBatchSize)
345+
expectedBatchingFactor := int(cfg.SendBatchSize) / dataPointsPerRequest
344346

345347
require.Equal(t, requestCount*metricsPerRequest, sink.MetricsCount())
346348
receivedMds := sink.AllMetrics()
@@ -357,7 +359,7 @@ func TestBatchMetricProcessor_BatchSize(t *testing.T) {
357359
assert.Equal(t, 1, len(viewData))
358360
distData := viewData[0].Data.(*view.DistributionData)
359361
assert.Equal(t, int64(expectedBatchesNum), distData.Count)
360-
assert.Equal(t, sink.MetricsCount(), int(distData.Sum()))
362+
assert.Equal(t, sink.MetricsCount()*dataPointsPreMetric, int(distData.Sum()))
361363
assert.Equal(t, cfg.SendBatchSize, uint32(distData.Min))
362364
assert.Equal(t, cfg.SendBatchSize, uint32(distData.Max))
363365

processor/batchprocessor/splitmetrics.go

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,17 @@ import (
2020

2121
// splitMetrics removes metrics from the input data and returns a new data of the specified size.
2222
func splitMetrics(size int, src pdata.Metrics) pdata.Metrics {
23-
if src.MetricCount() <= size {
23+
_, dataPoints := src.MetricAndDataPointCount()
24+
if dataPoints <= size {
2425
return src
2526
}
26-
totalCopiedMetrics := 0
27+
shouldSend := false
28+
totalCopiedDataPoints := 0
2729
dest := pdata.NewMetrics()
2830

2931
src.ResourceMetrics().RemoveIf(func(srcRs pdata.ResourceMetrics) bool {
3032
// If we are done skip everything else.
31-
if totalCopiedMetrics == size {
33+
if shouldSend {
3234
return false
3335
}
3436

@@ -37,28 +39,29 @@ func splitMetrics(size int, src pdata.Metrics) pdata.Metrics {
3739

3840
srcRs.InstrumentationLibraryMetrics().RemoveIf(func(srcIlm pdata.InstrumentationLibraryMetrics) bool {
3941
// If we are done skip everything else.
40-
if totalCopiedMetrics == size {
42+
if shouldSend {
4143
return false
4244
}
4345

4446
destIlm := destRs.InstrumentationLibraryMetrics().AppendEmpty()
4547
srcIlm.InstrumentationLibrary().CopyTo(destIlm.InstrumentationLibrary())
4648

4749
// If possible to move all metrics do that.
48-
srcMetricsLen := srcIlm.Metrics().Len()
49-
if size-totalCopiedMetrics >= srcMetricsLen {
50-
totalCopiedMetrics += srcMetricsLen
50+
srcDataPointCount := srcIlm.Metrics().DataPointCount()
51+
if size-totalCopiedDataPoints >= srcDataPointCount {
52+
totalCopiedDataPoints += srcDataPointCount
5153
srcIlm.Metrics().MoveAndAppendTo(destIlm.Metrics())
5254
return true
5355
}
5456

5557
srcIlm.Metrics().RemoveIf(func(srcMetric pdata.Metric) bool {
5658
// If we are done skip everything else.
57-
if totalCopiedMetrics == size {
59+
if srcMetric.DataPointCount()+totalCopiedDataPoints > size {
60+
shouldSend = true
5861
return false
5962
}
6063
srcMetric.CopyTo(destIlm.Metrics().AppendEmpty())
61-
totalCopiedMetrics++
64+
totalCopiedDataPoints += srcMetric.DataPointCount()
6265
return true
6366
})
6467
return false

processor/batchprocessor/splitmetrics_test.go

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ func TestSplitMetrics_noop(t *testing.T) {
3636
func TestSplitMetrics(t *testing.T) {
3737
md := testdata.GenerateMetricsManyMetricsSameResource(20)
3838
metrics := md.ResourceMetrics().At(0).InstrumentationLibraryMetrics().At(0).Metrics()
39+
dataPointCount := metrics.At(0).DataPointCount()
3940
for i := 0; i < metrics.Len(); i++ {
4041
metrics.At(i).SetName(getTestMetricName(0, i))
42+
assert.Equal(t, dataPointCount, metrics.At(i).DataPointCount())
4143
}
4244
cp := pdata.NewMetrics()
4345
cpMetrics := cp.ResourceMetrics().AppendEmpty().InstrumentationLibraryMetrics().AppendEmpty().Metrics()
@@ -52,9 +54,10 @@ func TestSplitMetrics(t *testing.T) {
5254
metrics.At(3).CopyTo(cpMetrics.At(3))
5355
metrics.At(4).CopyTo(cpMetrics.At(4))
5456

55-
splitSize := 5
57+
splitMetricCount := 5
58+
splitSize := splitMetricCount * dataPointCount
5659
split := splitMetrics(splitSize, md)
57-
assert.Equal(t, splitSize, split.MetricCount())
60+
assert.Equal(t, splitMetricCount, split.MetricCount())
5861
assert.Equal(t, cp, split)
5962
assert.Equal(t, 15, md.MetricCount())
6063
assert.Equal(t, "test-metric-int-0-0", split.ResourceMetrics().At(0).InstrumentationLibraryMetrics().At(0).Metrics().At(0).Name())
@@ -79,8 +82,10 @@ func TestSplitMetrics(t *testing.T) {
7982
func TestSplitMetricsMultipleResourceSpans(t *testing.T) {
8083
md := testdata.GenerateMetricsManyMetricsSameResource(20)
8184
metrics := md.ResourceMetrics().At(0).InstrumentationLibraryMetrics().At(0).Metrics()
85+
dataPointCount := metrics.At(0).DataPointCount()
8286
for i := 0; i < metrics.Len(); i++ {
8387
metrics.At(i).SetName(getTestMetricName(0, i))
88+
assert.Equal(t, dataPointCount, metrics.At(i).DataPointCount())
8489
}
8590
// add second index to resource metrics
8691
testdata.GenerateMetricsManyMetricsSameResource(20).
@@ -90,9 +95,10 @@ func TestSplitMetricsMultipleResourceSpans(t *testing.T) {
9095
metrics.At(i).SetName(getTestMetricName(1, i))
9196
}
9297

93-
splitSize := 5
98+
splitMetricCount := 5
99+
splitSize := splitMetricCount * dataPointCount
94100
split := splitMetrics(splitSize, md)
95-
assert.Equal(t, splitSize, split.MetricCount())
101+
assert.Equal(t, splitMetricCount, split.MetricCount())
96102
assert.Equal(t, 35, md.MetricCount())
97103
assert.Equal(t, "test-metric-int-0-0", split.ResourceMetrics().At(0).InstrumentationLibraryMetrics().At(0).Metrics().At(0).Name())
98104
assert.Equal(t, "test-metric-int-0-4", split.ResourceMetrics().At(0).InstrumentationLibraryMetrics().At(0).Metrics().At(4).Name())
@@ -101,8 +107,10 @@ func TestSplitMetricsMultipleResourceSpans(t *testing.T) {
101107
func TestSplitMetricsMultipleResourceSpans_SplitSizeGreaterThanMetricSize(t *testing.T) {
102108
td := testdata.GenerateMetricsManyMetricsSameResource(20)
103109
metrics := td.ResourceMetrics().At(0).InstrumentationLibraryMetrics().At(0).Metrics()
110+
dataPointCount := metrics.At(0).DataPointCount()
104111
for i := 0; i < metrics.Len(); i++ {
105112
metrics.At(i).SetName(getTestMetricName(0, i))
113+
assert.Equal(t, dataPointCount, metrics.At(i).DataPointCount())
106114
}
107115
td.ResourceMetrics().Resize(2)
108116
// add second index to resource metrics
@@ -113,10 +121,11 @@ func TestSplitMetricsMultipleResourceSpans_SplitSizeGreaterThanMetricSize(t *tes
113121
metrics.At(i).SetName(getTestMetricName(1, i))
114122
}
115123

116-
splitSize := 25
124+
splitMetricCount := 25
125+
splitSize := splitMetricCount * dataPointCount
117126
split := splitMetrics(splitSize, td)
118-
assert.Equal(t, splitSize, split.MetricCount())
119-
assert.Equal(t, 40-splitSize, td.MetricCount())
127+
assert.Equal(t, splitMetricCount, split.MetricCount())
128+
assert.Equal(t, 40-splitMetricCount, td.MetricCount())
120129
assert.Equal(t, 1, td.ResourceMetrics().Len())
121130
assert.Equal(t, "test-metric-int-0-0", split.ResourceMetrics().At(0).InstrumentationLibraryMetrics().At(0).Metrics().At(0).Name())
122131
assert.Equal(t, "test-metric-int-0-19", split.ResourceMetrics().At(0).InstrumentationLibraryMetrics().At(0).Metrics().At(19).Name())
@@ -166,3 +175,31 @@ func BenchmarkCloneMetrics(b *testing.B) {
166175
}
167176
}
168177
}
178+
179+
func TestSplitMetricsNotFull(t *testing.T) {
180+
md := testdata.GenerateMetricsManyMetricsSameResource(10)
181+
metrics := md.ResourceMetrics().At(0).InstrumentationLibraryMetrics().At(0).Metrics()
182+
dataPointCount := 2
183+
for i := 0; i < metrics.Len(); i++ {
184+
metrics.At(i).SetName(getTestMetricName(0, i))
185+
assert.Equal(t, dataPointCount, metrics.At(i).DataPointCount())
186+
}
187+
188+
splitSize := 9
189+
split := splitMetrics(splitSize, md)
190+
assert.Equal(t, 4, split.MetricCount())
191+
assert.Equal(t, 6, md.MetricCount())
192+
assert.Equal(t, "test-metric-int-0-0", split.ResourceMetrics().At(0).InstrumentationLibraryMetrics().At(0).Metrics().At(0).Name())
193+
assert.Equal(t, "test-metric-int-0-3", split.ResourceMetrics().At(0).InstrumentationLibraryMetrics().At(0).Metrics().At(3).Name())
194+
195+
split = splitMetrics(splitSize, md)
196+
assert.Equal(t, 4, split.MetricCount())
197+
assert.Equal(t, 2, md.MetricCount())
198+
assert.Equal(t, "test-metric-int-0-4", split.ResourceMetrics().At(0).InstrumentationLibraryMetrics().At(0).Metrics().At(0).Name())
199+
assert.Equal(t, "test-metric-int-0-7", split.ResourceMetrics().At(0).InstrumentationLibraryMetrics().At(0).Metrics().At(3).Name())
200+
201+
split = splitMetrics(splitSize, md)
202+
assert.Equal(t, 2, split.MetricCount())
203+
assert.Equal(t, "test-metric-int-0-8", split.ResourceMetrics().At(0).InstrumentationLibraryMetrics().At(0).Metrics().At(0).Name())
204+
assert.Equal(t, "test-metric-int-0-9", split.ResourceMetrics().At(0).InstrumentationLibraryMetrics().At(0).Metrics().At(1).Name())
205+
}

0 commit comments

Comments
 (0)