From 79d9ff802f65629dcea01f7343c2f106b0cffcf2 Mon Sep 17 00:00:00 2001 From: Mayur Kale Date: Mon, 26 Aug 2019 15:03:16 -0700 Subject: [PATCH] Fix: add batch limit for stackdriver exporter --- .../src/stackdriver-monitoring-utils.ts | 9 ++++++ .../src/stackdriver-monitoring.ts | 14 ++++++++ .../test/test-stackdriver-monitoring-utils.ts | 32 +++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/packages/opencensus-exporter-stackdriver/src/stackdriver-monitoring-utils.ts b/packages/opencensus-exporter-stackdriver/src/stackdriver-monitoring-utils.ts index 277783626..22cf3a86c 100644 --- a/packages/opencensus-exporter-stackdriver/src/stackdriver-monitoring-utils.ts +++ b/packages/opencensus-exporter-stackdriver/src/stackdriver-monitoring-utils.ts @@ -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); diff --git a/packages/opencensus-exporter-stackdriver/src/stackdriver-monitoring.ts b/packages/opencensus-exporter-stackdriver/src/stackdriver-monitoring.ts index e1a914673..b2cb91096 100644 --- a/packages/opencensus-exporter-stackdriver/src/stackdriver-monitoring.ts +++ b/packages/opencensus-exporter-stackdriver/src/stackdriver-monitoring.ts @@ -34,6 +34,7 @@ import { getDefaultResource } from './common-utils'; import { createMetricDescriptorData, createTimeSeriesList, + partitionList, } from './stackdriver-monitoring-utils'; import { MonitoredResource, @@ -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; @@ -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}`, diff --git a/packages/opencensus-exporter-stackdriver/test/test-stackdriver-monitoring-utils.ts b/packages/opencensus-exporter-stackdriver/test/test-stackdriver-monitoring-utils.ts index 8feae4e88..202d05f7d 100644 --- a/packages/opencensus-exporter-stackdriver/test/test-stackdriver-monitoring-utils.ts +++ b/packages/opencensus-exporter-stackdriver/test/test-stackdriver-monitoring-utils.ts @@ -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'; @@ -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); + assert.strictEqual(list.length, 2); + assert.strictEqual(list[0].length, 200); + assert.strictEqual(list[1].length, 5); + }); + }); });