Skip to content

Commit

Permalink
LowMemory metrics temporality preference (#3915)
Browse files Browse the repository at this point in the history
Co-authored-by: Marc Pichler <[email protected]>
  • Loading branch information
martinkuba and pichlermarc authored Jun 30, 2023
1 parent bb8a4f7 commit 070b685
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 36 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ For experimental package changes, see the [experimental CHANGELOG](experimental/

### :rocket: (Enhancement)

* feat(exporter-metrics-otlp-*)!: add LowMemory metrics temporality preference [#3915](https://github.com/open-telemetry/opentelemetry-js/pull/3915)
* Breaking: From now on `AggregationTemporalityPreference` has to be used instead of `AggregationTemporality` when configuring the exporter.
* Adds support for [LowMemory temporality preference](https://github.com/open-telemetry/opentelemetry-specification/blob/f09624bb97e9be3be259733b93be507df18927bd/specification/metrics/sdk_exporters/otlp.md#additional-configuration)
* Adds support for `lowmemory` in `OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE`

### :bug: (Bug Fix)

* fix(sdk-metrics): Update default Histogram's boundary to match OTEL's spec [#3893](https://github.com/open-telemetry/opentelemetry-js/pull/3893/) @chigia001
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ In addition to settings passed to the constructor, the exporter also supports co
| OTEL_EXPORTER_OTLP_CLIENT_KEY | The path to the file containing private client key to use when verifying an OTLP trace, metric or log client's TLS credentials. Must provide a client certificate/chain when providing a private client key. By default no client key file is used. |
| OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE | The path to the file containing trusted client certificate/chain for clients private key to use when verifying an OTLP metric server's TLS credentials. Must provide a private client key when providing a certificate/chain. By default no chain file is used. |
| OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE | The path to the file containing trusted client certificate/chain for clients private key to use when verifying an OTLP trace, metric and log server's TLS credentials. Must provide a private client key when providing a certificate/chain. By default no chain file is used. |
| OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE | The exporters aggregation temporality preference. Valid values are `cumulative`, and `delta`. `cumulative` selects cumulative temporality for all instrument kinds. `delta` selects delta aggregation temporality for Counter, Asynchronous Counter and Histogram instrument kinds, and selects cumulative aggregation for UpDownCounter and Asynchronous UpDownCounter instrument kinds. By default `cumulative` is used. |
| OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE | The exporters aggregation temporality preference. Valid values are `cumulative`, `delta`, and `lowmemory`. `cumulative` selects cumulative temporality for all instrument kinds. `delta` selects delta aggregation temporality for Counter, Asynchronous Counter and Histogram instrument kinds, and selects cumulative aggregation for UpDownCounter and Asynchronous UpDownCounter instrument kinds. `lowmemory` select delta aggregation temporality for Synchronous Counter and Histogram instrument kinds, and selects cumulative aggregation for Synchronous UpDownCounter, Asynchronous Counter and Asynchronous UpDownCounter instrument kinds. By default `cumulative` is used. |

> Settings configured programmatically take precedence over environment variables. Per-signal environment variables take precedence over non-per-signal environment variables.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,13 @@ import {
setUp,
shutdown,
} from './metricsHelper';
import {
AggregationTemporality,
ResourceMetrics,
} from '@opentelemetry/sdk-metrics';
import { ResourceMetrics } from '@opentelemetry/sdk-metrics';
import {
IExportMetricsServiceRequest,
IResourceMetrics,
} from '@opentelemetry/otlp-transformer';
import { VERSION } from '../src/version';
import { AggregationTemporalityPreference } from '@opentelemetry/exporter-metrics-otlp-http';

const metricsServiceProtoPath =
'opentelemetry/proto/collector/metrics/v1/metrics_service.proto';
Expand Down Expand Up @@ -144,7 +142,7 @@ const testOTLPMetricExporter = (params: TestParams) => {
url: address,
credentials,
metadata: metadata,
temporalityPreference: AggregationTemporality.CUMULATIVE,
temporalityPreference: AggregationTemporalityPreference.CUMULATIVE,
});

setUp();
Expand Down Expand Up @@ -199,7 +197,7 @@ const testOTLPMetricExporter = (params: TestParams) => {
headers: {
foo: 'bar',
},
temporalityPreference: AggregationTemporality.CUMULATIVE,
temporalityPreference: AggregationTemporalityPreference.CUMULATIVE,
});
const args = warnStub.args[0];
assert.strictEqual(args[0], 'Headers cannot be set when using grpc');
Expand All @@ -211,7 +209,7 @@ const testOTLPMetricExporter = (params: TestParams) => {
}
collectorExporter = new OTLPMetricExporter({
url: `${address}/v1/metrics`,
temporalityPreference: AggregationTemporality.CUMULATIVE,
temporalityPreference: AggregationTemporalityPreference.CUMULATIVE,
});
const args = warnStub.args[0];
assert.strictEqual(
Expand Down Expand Up @@ -294,7 +292,7 @@ describe('OTLPMetricExporter - node (getDefaultUrl)', () => {
const url = 'http://foo.bar.com';
const collectorExporter = new OTLPMetricExporter({
url,
temporalityPreference: AggregationTemporality.CUMULATIVE,
temporalityPreference: AggregationTemporalityPreference.CUMULATIVE,
});
setTimeout(() => {
assert.strictEqual(collectorExporter._otlpExporter.url, 'foo.bar.com');
Expand Down Expand Up @@ -343,7 +341,7 @@ describe('when configuring via environment', () => {
envSource.OTEL_EXPORTER_OTLP_METRICS_HEADERS = 'foo=boo';
const collectorExporter = new OTLPMetricExporter({
metadata,
temporalityPreference: AggregationTemporality.CUMULATIVE,
temporalityPreference: AggregationTemporalityPreference.CUMULATIVE,
});
assert.deepStrictEqual(
collectorExporter._otlpExporter.metadata?.get('foo'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ In addition to settings passed to the constructor, the exporter also supports co
|---------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| OTEL_EXPORTER_OTLP_ENDPOINT | The endpoint to send metrics to. This will also be used for the traces exporter if `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` is not configured. By default `http://localhost:4318` will be used. `/v1/metrics` will be automatically appended to configured values. |
| OTEL_EXPORTER_OTLP_METRICS_ENDPOINT | The endpoint to send metrics to. By default `https://localhost:4318/v1/metrics` will be used. `v1/metrics` will not be appended automatically and has to be added explicitly. |
| OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE | The exporters aggregation temporality preference. Valid values are `cumulative`, and `delta`. `cumulative` selects cumulative temporality for all instrument kinds. `delta` selects delta aggregation temporality for Counter, Asynchronous Counter and Histogram instrument kinds, and selects cumulative aggregation for UpDownCounter and Asynchronous UpDownCounter instrument kinds. By default `cumulative` is used. |
| OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE | The exporters aggregation temporality preference. Valid values are `cumulative`, `delta`, and `lowmemory`. `cumulative` selects cumulative temporality for all instrument kinds. `delta` selects delta aggregation temporality for Counter, Asynchronous Counter and Histogram instrument kinds, and selects cumulative aggregation for UpDownCounter and Asynchronous UpDownCounter instrument kinds. `lowmemory` selects delta aggregation temporality for Counter and Histogram instrument kinds, and selects cumulative aggregation for UpDownCounter, Asynchronous Counter and Asynchronous UpDownCounter instrument kinds. By default `cumulative` is used. |

> Settings configured programmatically take precedence over environment variables. Per-signal environment variables take
> precedence over non-per-signal environment variables.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ import {
PushMetricExporter,
ResourceMetrics,
} from '@opentelemetry/sdk-metrics';
import { OTLPMetricExporterOptions } from './OTLPMetricExporterOptions';
import {
AggregationTemporalityPreference,
OTLPMetricExporterOptions,
} from './OTLPMetricExporterOptions';
import { OTLPExporterBase } from '@opentelemetry/otlp-exporter-base';
import { IExportMetricsServiceRequest } from '@opentelemetry/otlp-transformer';
import { diag } from '@opentelemetry/api';
Expand All @@ -45,6 +48,21 @@ export const DeltaTemporalitySelector: AggregationTemporalitySelector = (
}
};

export const LowMemoryTemporalitySelector: AggregationTemporalitySelector = (
instrumentType: InstrumentType
) => {
switch (instrumentType) {
case InstrumentType.COUNTER:
case InstrumentType.HISTOGRAM:
return AggregationTemporality.DELTA;
case InstrumentType.UP_DOWN_COUNTER:
case InstrumentType.OBSERVABLE_UP_DOWN_COUNTER:
case InstrumentType.OBSERVABLE_COUNTER:
case InstrumentType.OBSERVABLE_GAUGE:
return AggregationTemporality.CUMULATIVE;
}
};

function chooseTemporalitySelectorFromEnvironment() {
const env = getEnv();
const configuredTemporality =
Expand All @@ -56,6 +74,9 @@ function chooseTemporalitySelectorFromEnvironment() {
if (configuredTemporality === 'delta') {
return DeltaTemporalitySelector;
}
if (configuredTemporality === 'lowmemory') {
return LowMemoryTemporalitySelector;
}

diag.warn(
`OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE is set to '${env.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE}', but only 'cumulative' and 'delta' are allowed. Using default ('cumulative') instead.`
Expand All @@ -64,12 +85,18 @@ function chooseTemporalitySelectorFromEnvironment() {
}

function chooseTemporalitySelector(
temporalityPreference?: AggregationTemporality
temporalityPreference?:
| AggregationTemporalityPreference
| AggregationTemporality
): AggregationTemporalitySelector {
// Directly passed preference has priority.
if (temporalityPreference != null) {
if (temporalityPreference === AggregationTemporality.DELTA) {
if (temporalityPreference === AggregationTemporalityPreference.DELTA) {
return DeltaTemporalitySelector;
} else if (
temporalityPreference === AggregationTemporalityPreference.LOWMEMORY
) {
return LowMemoryTemporalitySelector;
}
return CumulativeTemporalitySelector;
}
Expand All @@ -86,7 +113,7 @@ export class OTLPMetricExporterBase<
> implements PushMetricExporter
{
public _otlpExporter: T;
protected _aggregationTemporalitySelector: AggregationTemporalitySelector;
private _aggregationTemporalitySelector: AggregationTemporalitySelector;

constructor(exporter: T, config?: OTLPMetricExporterOptions) {
this._otlpExporter = exporter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,17 @@
* limitations under the License.
*/

import { AggregationTemporality } from '@opentelemetry/sdk-metrics';
import { OTLPExporterConfigBase } from '@opentelemetry/otlp-exporter-base';
import { AggregationTemporality } from '@opentelemetry/sdk-metrics';

export interface OTLPMetricExporterOptions extends OTLPExporterConfigBase {
temporalityPreference?: AggregationTemporality;
temporalityPreference?:
| AggregationTemporalityPreference
| AggregationTemporality;
}

export enum AggregationTemporalityPreference {
DELTA,
CUMULATIVE,
LOWMEMORY,
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ import {
Histogram,
} from '@opentelemetry/api';
import { ExportResultCode, hrTimeToNanoseconds } from '@opentelemetry/core';
import {
AggregationTemporality,
ResourceMetrics,
} from '@opentelemetry/sdk-metrics';
import { ResourceMetrics } from '@opentelemetry/sdk-metrics';
import * as assert from 'assert';
import * as sinon from 'sinon';
import { OTLPMetricExporter } from '../../src/platform/browser';
Expand All @@ -44,7 +41,10 @@ import {
setUp,
shutdown,
} from '../metricsHelper';
import { OTLPMetricExporterOptions } from '../../src';
import {
AggregationTemporalityPreference,
OTLPMetricExporterOptions,
} from '../../src';
import { OTLPExporterConfigBase } from '@opentelemetry/otlp-exporter-base';
import { IExportMetricsServiceRequest } from '@opentelemetry/otlp-transformer';

Expand Down Expand Up @@ -102,7 +102,7 @@ describe('OTLPMetricExporter - web', () => {
beforeEach(() => {
collectorExporter = new OTLPMetricExporter({
url: 'http://foo.bar.com',
temporalityPreference: AggregationTemporality.CUMULATIVE,
temporalityPreference: AggregationTemporalityPreference.CUMULATIVE,
});
});

Expand Down Expand Up @@ -230,7 +230,7 @@ describe('OTLPMetricExporter - web', () => {
(window.navigator as any).sendBeacon = false;
collectorExporter = new OTLPMetricExporter({
url: 'http://foo.bar.com',
temporalityPreference: AggregationTemporality.CUMULATIVE,
temporalityPreference: AggregationTemporalityPreference.CUMULATIVE,
});
// Overwrites the start time to make tests consistent
Object.defineProperty(collectorExporter, '_startTime', {
Expand Down Expand Up @@ -386,7 +386,7 @@ describe('OTLPMetricExporter - web', () => {
beforeEach(() => {
collectorExporterConfig = {
headers: customHeaders,
temporalityPreference: AggregationTemporality.CUMULATIVE,
temporalityPreference: AggregationTemporalityPreference.CUMULATIVE,
};
server = sinon.fakeServer.create();
});
Expand Down Expand Up @@ -518,7 +518,7 @@ describe('when configuring via environment', () => {
envSource.OTEL_EXPORTER_OTLP_HEADERS = 'foo=bar';
const collectorExporter = new OTLPMetricExporter({
headers: {},
temporalityPreference: AggregationTemporality.CUMULATIVE,
temporalityPreference: AggregationTemporalityPreference.CUMULATIVE,
});
assert.strictEqual(
collectorExporter['_otlpExporter']['_headers'].foo,
Expand All @@ -531,7 +531,7 @@ describe('when configuring via environment', () => {
envSource.OTEL_EXPORTER_OTLP_METRICS_HEADERS = 'foo=boo';
const collectorExporter = new OTLPMetricExporter({
headers: {},
temporalityPreference: AggregationTemporality.CUMULATIVE,
temporalityPreference: AggregationTemporalityPreference.CUMULATIVE,
});
assert.strictEqual(
collectorExporter['_otlpExporter']['_headers'].foo,
Expand Down
Loading

0 comments on commit 070b685

Please sign in to comment.