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

Fix: add batch limit for stackdriver exporter #644

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,15 @@ export function createTimeSeriesList(
return timeSeriesList;
}

/** Returns an array with arrays of the given size. */
export function partitionList(list: TimeSeries[], chunkSize: number) {
const results = [];
while (list.length) {
results.push(list.splice(0, chunkSize));
}
return results;
}

/** Creates Metric type. */
function createMetricType(name: string, metricPrefix: string): string {
return path.join(metricPrefix, name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { getDefaultResource } from './common-utils';
import {
createMetricDescriptorData,
createTimeSeriesList,
partitionList,
} from './stackdriver-monitoring-utils';
import {
MonitoredResource,
Expand All @@ -49,6 +50,10 @@ const OC_HEADER = {
'x-opencensus-outgoing-request': 0x1,
};

// Stackdriver Monitoring v3 only accepts up to 200 TimeSeries per
// CreateTimeSeries call.
const MAX_BATCH_EXPORT_SIZE = 200;

google.options({ headers: OC_HEADER });
const monitoring = google.monitoring('v3');
let auth = globalAuth;
Expand Down Expand Up @@ -184,6 +189,15 @@ export class StackdriverStatsExporter implements StatsEventListener {
return Promise.resolve();
}

for (const batchedTimeSeries of partitionList(
timeSeries,
MAX_BATCH_EXPORT_SIZE
)) {
this._createTimeSeries(batchedTimeSeries);
}
}

private async _createTimeSeries(timeSeries: TimeSeries[]) {
return this.authorize().then(authClient => {
const request = {
name: `projects/${this.projectId}`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ import {
createTimeSeriesList,
OPENCENSUS_TASK_VALUE_DEFAULT,
TEST_ONLY,
partitionList,
} from '../src/stackdriver-monitoring-utils';
import {
Distribution,
MetricDescriptor,
MetricKind,
ValueType,
TimeSeries,
} from '../src/types';
import * as nocks from './nocks';

Expand Down Expand Up @@ -616,4 +618,34 @@ describe('Stackdriver Stats Exporter Utils', () => {
});
});
});

describe('partitionList()', () => {
const timeSeriesList: TimeSeries[] = [];
for (let i = 0; i < 205; i++) {
timeSeriesList.push({
metric: {
type: 'custom.googleapis.com/opencensus/metric-name-' + i,
labels: {},
},
resource: { type: 'global', labels: {} },
metricKind: MetricKind.GAUGE,
valueType: ValueType.INT64,
points: [
{
interval: { endTime: '2019-01-09T01:52:55.00000001Z' },
value: {
int64Value: i,
},
},
],
});
}

it('should return a partition lists', () => {
const list = partitionList(timeSeriesList, 200);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to test the exporter directly rather than the helper function? That would enable check that the helper function is used correctly and would implicitly check the helper (which could then even be made non-exported).

I'm open to leaving as-is for now if you prefer though.

assert.strictEqual(list.length, 2);
assert.strictEqual(list[0].length, 200);
assert.strictEqual(list[1].length, 5);
});
});
});