diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 44e89e8133..7913109e53 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -14,6 +14,7 @@ All notable changes to experimental packages in this project will be documented * feat: enable tree shaking [#3329](https://github.com/open-telemetry/opentelemetry-js/pull/3329) @pkanal * feat(prometheus): serialize resource as target_info gauge [#3300](https://github.com/open-telemetry/opentelemetry-js/pull/3300) @pichlermarc * deps: remove unused proto-loader dependencies and update grpc-js and proto-loader versions [#3337](https://github.com/open-telemetry/opentelemetry-js/pull/3337) @seemk +* feat(metrics-exporters): configure temporality via environment variable [#3305](https://github.com/open-telemetry/opentelemetry-js/pull/3305) @pichlermarc ### :bug: (Bug Fix) diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/README.md b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/README.md index e00bf05e41..3aee8d08a4 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/README.md +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/README.md @@ -17,16 +17,19 @@ npm install --save @opentelemetry/exporter-metrics-otlp-grpc ## Service Name The OpenTelemetry Collector Exporter does not have a service name configuration. -In order to set the service name, use the `service.name` resource attribute as prescribed in the [OpenTelemetry Resource Semantic Conventions][semconv-resource-service-name]. -To see sample code and documentation for the traces exporter, as well as instructions for using TLS, visit the [Collector Trace Exporter for web and node][trace-exporter-url]. +In order to set the service name, use the `service.name` resource attribute as prescribed in +the [OpenTelemetry Resource Semantic Conventions][semconv-resource-service-name]. +To see sample code and documentation for the traces exporter, as well as instructions for using TLS, visit +the [Collector Trace Exporter for web and node][trace-exporter-url]. ## Metrics in Node - GRPC -The OTLPMetricsExporter in Node expects the URL to only be the hostname. It will not work with `/v1/metrics`. All options that work with trace also work with metrics. +The OTLPMetricsExporter in Node expects the URL to only be the hostname. It will not work with `/v1/metrics`. All +options that work with trace also work with metrics. ```js const { MeterProvider, PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics'); -const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-grpc'); +const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-grpc'); const collectorOptions = { // url is optional and can be omitted - default is http://localhost:4317 url: 'http://:', @@ -52,20 +55,24 @@ counter.add(10, { 'key': 'value' }); ## Environment Variable Configuration - | Environment variable | Description | - |----------------------|-------------| - | OTEL_EXPORTER_OTLP_METRICS_COMPRESSION | The compression type to use on OTLP metric requests. Options include gzip. By default no compression will be used. | - | OTEL_EXPORTER_OTLP_COMPRESSION | The compression type to use on OTLP trace, metric, and log requests. Options include gzip. By default no compression will be used. | - | OTEL_EXPORTER_OTLP_METRICS_INSECURE | Whether to enable client transport security for the exporter's gRPC connection for metric requests. This option only applies to OTLP/gRPC when an endpoint is provided without the http or https scheme. Options include true or false. By default insecure is false which creates a secure connection. | - | OTEL_EXPORTER_OTLP_INSECURE | Whether to enable client transport security for the exporter's gRPC connection for trace, metric and log requests. This option only applies to OTLP/gRPC when an endpoint is provided without the http or https scheme. Options include true or false. By default insecure is false which creates a secure connection. | - | OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE | The path to the file containing trusted root certificate to use when verifying an OTLP metric server's TLS credentials. By default the host platform's trusted root certificate is used.| - | OTEL_EXPORTER_OTLP_CERTIFICATE | The path to the file containing trusted root certificate to use when verifying an OTLP trace, metric, or log server's TLS credentials. By default the host platform's trusted root certificate is used. | - | OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY | The path to the file containing private client key to use when verifying an OTLP metric 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_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. | - - > Settings configured programmatically take precedence over environment variables. Per-signal environment variables take precedence over non-per-signal environment variables. +In addition to settings passed to the constructor, the exporter also supports configuration via environment variables: + +| Environment variable | Description | +|----------------------|-------------| +| 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 `localhost:4317` will be used. | +| OTEL_EXPORTER_OTLP_METRICS_ENDPOINT | The endpoint to send metrics to. By default `localhost:4317` will be used. | +| OTEL_EXPORTER_OTLP_COMPRESSION | The compression type to use on OTLP trace, metric, and log requests. Options include gzip. By default no compression will be used. | +| OTEL_EXPORTER_OTLP_METRICS_INSECURE | Whether to enable client transport security for the exporter's gRPC connection for metric requests. This option only applies to OTLP/gRPC when an endpoint is provided without the http or https scheme. Options include true or false. By default insecure is false which creates a secure connection. | +| OTEL_EXPORTER_OTLP_INSECURE | Whether to enable client transport security for the exporter's gRPC connection for trace, metric and log requests. This option only applies to OTLP/gRPC when an endpoint is provided without the http or https scheme. Options include true or false. By default insecure is false which creates a secure connection. | +| OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE | The path to the file containing trusted root certificate to use when verifying an OTLP metric server's TLS credentials. By default the host platform's trusted root certificate is used.| +| OTEL_EXPORTER_OTLP_CERTIFICATE | The path to the file containing trusted root certificate to use when verifying an OTLP trace, metric, or log server's TLS credentials. By default the host platform's trusted root certificate is used. | +| OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY | The path to the file containing private client key to use when verifying an OTLP metric 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_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. | + +> Settings configured programmatically take precedence over environment variables. Per-signal environment variables take precedence over non-per-signal environment variables. ## Running opentelemetry-collector locally to see the metrics diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/src/OTLPMetricExporter.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/src/OTLPMetricExporter.ts index 5f7d979fd3..3a512e3df4 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/src/OTLPMetricExporter.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/src/OTLPMetricExporter.ts @@ -15,7 +15,6 @@ */ import { - defaultOptions, OTLPMetricExporterBase, OTLPMetricExporterOptions } from '@opentelemetry/exporter-metrics-otlp-http'; @@ -33,7 +32,7 @@ import { createExportMetricsServiceRequest, IExportMetricsServiceRequest } from class OTLPMetricExporterProxy extends OTLPGRPCExporterNodeBase { - constructor(config: OTLPGRPCExporterConfigNode & OTLPMetricExporterOptions= defaultOptions) { + constructor(config?: OTLPGRPCExporterConfigNode & OTLPMetricExporterOptions) { super(config); const headers = baggageUtils.parseKeyPairsIntoRecord(getEnv().OTEL_EXPORTER_OTLP_METRICS_HEADERS); this.metadata ||= new Metadata(); @@ -73,7 +72,7 @@ class OTLPMetricExporterProxy extends OTLPGRPCExporterNodeBase{ - constructor(config: OTLPGRPCExporterConfigNode & OTLPMetricExporterOptions = defaultOptions) { + constructor(config?: OTLPGRPCExporterConfigNode & OTLPMetricExporterOptions) { super(new OTLPMetricExporterProxy(config), config); } } diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/README.md b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/README.md index d495e53b38..4dcbda9dae 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/README.md +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/README.md @@ -17,8 +17,10 @@ npm install --save @opentelemetry/exporter-metrics-otlp-http ## Service Name The OpenTelemetry Collector Metrics Exporter does not have a service name configuration. -In order to set the service name, use the `service.name` resource attribute as prescribed in the [OpenTelemetry Resource Semantic Conventions][semconv-resource-service-name]. -To see sample code and documentation for the traces exporter, visit the [Collector Trace Exporter for web and node][trace-exporter-url]. +In order to set the service name, use the `service.name` resource attribute as prescribed in +the [OpenTelemetry Resource Semantic Conventions][semconv-resource-service-name]. +To see sample code and documentation for the traces exporter, visit +the [Collector Trace Exporter for web and node][trace-exporter-url]. ## Metrics in Web @@ -27,6 +29,7 @@ The OTLPMetricExporter in Web expects the endpoint to end in `/v1/metrics`. ```js import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'; import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http'; + const collectorOptions = { url: '', // url is optional and can be omitted - default is http://localhost:4318/v1/metrics headers: {}, // an optional object containing custom headers to be sent with each request @@ -50,7 +53,7 @@ counter.add(10, { 'key': 'value' }); ```js const { MeterProvider, PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics'); -const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-http'); +const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-http'); const collectorOptions = { url: '', // url is optional and can be omitted - default is http://localhost:4318/v1/metrics concurrencyLimit: 1, // an optional limit on pending requests @@ -70,35 +73,18 @@ counter.add(10, { 'key': 'value' }); ``` -## GRPC - -For exporting metrics with GRPC please check [exporter-metrics-otlp-grpc][npm-url-grpc] - -## PROTOBUF - -For exporting metrics with PROTOBUF please check [exporter-metrics-otlp-proto][npm-url-proto] - -## Configuration options as environment variables - -Instead of providing options to `OTLPMetricExporter` and `OTLPTraceExporter` explicitly, environment variables may be provided instead. - -```sh -OTEL_EXPORTER_OTLP_ENDPOINT=https://localhost:4318 -# this will automatically append the version and signal path -# e.g. https://localhost:4318/v1/traces for `OTLPTraceExporter` and https://localhost:4318/v1/metrics for `OTLPMetricExporter` -``` - -If the trace and metric exporter endpoints have different providers, the env var for per-signal endpoints are available to use +## Environment Variable Configuration -```sh -OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://trace-service:4318/v1/traces -OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=https://metric-service:4318/v1/metrics -# version and signal needs to be explicit -``` +In addition to settings passed to the constructor, the exporter also supports configuration via environment variables: -> The per-signal endpoints take precedence and overrides `OTEL_EXPORTER_OTLP_ENDPOINT` +| Environment variable | Description | +|---------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 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. | -For more details, see [OpenTelemetry Specification on Protocol Exporter][opentelemetry-spec-protocol-exporter]. +> Settings configured programmatically take precedence over environment variables. Per-signal environment variables take +> precedence over non-per-signal environment variables. ## Running opentelemetry-collector locally to see the metrics @@ -110,6 +96,8 @@ For more details, see [OpenTelemetry Specification on Protocol Exporter][opentel - For more information on OpenTelemetry, visit: - For more about OpenTelemetry JavaScript: - For help or feedback on this project, join us in [GitHub Discussions][discussions-url] +- For exporting metrics via gRPC please check [exporter-metrics-otlp-grpc][npm-url-grpc] +- For exporting metrics via protobuf please check [exporter-metrics-otlp-proto][npm-url-proto] ## License diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/OTLPMetricExporterBase.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/OTLPMetricExporterBase.ts index b970a150d0..fca5a54d25 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/OTLPMetricExporterBase.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/OTLPMetricExporterBase.ts @@ -14,7 +14,10 @@ * limitations under the License. */ -import { ExportResult } from '@opentelemetry/core'; +import { + ExportResult, + getEnv +} from '@opentelemetry/core'; import { AggregationTemporality, AggregationTemporalitySelector, @@ -22,9 +25,12 @@ import { PushMetricExporter, ResourceMetrics } from '@opentelemetry/sdk-metrics'; -import { defaultOptions, OTLPMetricExporterOptions } from './OTLPMetricExporterOptions'; +import { + OTLPMetricExporterOptions +} from './OTLPMetricExporterOptions'; import { OTLPExporterBase } from '@opentelemetry/otlp-exporter-base'; import { IExportMetricsServiceRequest } from '@opentelemetry/otlp-transformer'; +import { diag } from '@opentelemetry/api'; export const CumulativeTemporalitySelector: AggregationTemporalitySelector = () => AggregationTemporality.CUMULATIVE; @@ -41,14 +47,33 @@ export const DeltaTemporalitySelector: AggregationTemporalitySelector = (instrum } }; -function chooseTemporalitySelector(temporalityPreference?: AggregationTemporality): AggregationTemporalitySelector { - if (temporalityPreference === AggregationTemporality.DELTA) { +function chooseTemporalitySelectorFromEnvironment() { + const env = getEnv(); + const configuredTemporality = env.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE.trim().toLowerCase(); + + if (configuredTemporality === 'cumulative') { + return CumulativeTemporalitySelector; + } + if (configuredTemporality === 'delta') { return DeltaTemporalitySelector; } + 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.`); return CumulativeTemporalitySelector; } +function chooseTemporalitySelector(temporalityPreference?: AggregationTemporality): AggregationTemporalitySelector { + // Directly passed preference has priority. + if (temporalityPreference != null) { + if (temporalityPreference === AggregationTemporality.DELTA) { + return DeltaTemporalitySelector; + } + return CumulativeTemporalitySelector; + } + + return chooseTemporalitySelectorFromEnvironment(); +} + export class OTLPMetricExporterBase> @@ -57,9 +82,9 @@ implements PushMetricExporter { protected _aggregationTemporalitySelector: AggregationTemporalitySelector; constructor(exporter: T, - config: OTLPMetricExporterOptions = defaultOptions) { + config?: OTLPMetricExporterOptions) { this._otlpExporter = exporter; - this._aggregationTemporalitySelector = chooseTemporalitySelector(config.temporalityPreference); + this._aggregationTemporalitySelector = chooseTemporalitySelector(config?.temporalityPreference); } export(metrics: ResourceMetrics, resultCallback: (result: ExportResult) => void): void { diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/OTLPMetricExporterOptions.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/OTLPMetricExporterOptions.ts index 986a85890b..324c4ea27f 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/OTLPMetricExporterOptions.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/OTLPMetricExporterOptions.ts @@ -20,5 +20,3 @@ import { OTLPExporterConfigBase } from '@opentelemetry/otlp-exporter-base'; export interface OTLPMetricExporterOptions extends OTLPExporterConfigBase { temporalityPreference?: AggregationTemporality } -export const defaultExporterTemporality = AggregationTemporality.CUMULATIVE; -export const defaultOptions = {temporalityPreference: defaultExporterTemporality}; diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/browser/OTLPMetricExporter.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/browser/OTLPMetricExporter.ts index afc42de108..00c7c0c32c 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/browser/OTLPMetricExporter.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/browser/OTLPMetricExporter.ts @@ -16,7 +16,7 @@ import { ResourceMetrics } from '@opentelemetry/sdk-metrics'; import { baggageUtils, getEnv } from '@opentelemetry/core'; -import { defaultOptions, OTLPMetricExporterOptions } from '../../OTLPMetricExporterOptions'; +import { OTLPMetricExporterOptions } from '../../OTLPMetricExporterOptions'; import { OTLPMetricExporterBase } from '../../OTLPMetricExporterBase'; import { OTLPExporterBrowserBase, @@ -31,7 +31,7 @@ const DEFAULT_COLLECTOR_URL = `http://localhost:4318/${DEFAULT_COLLECTOR_RESOURC class OTLPExporterBrowserProxy extends OTLPExporterBrowserBase { - constructor(config: OTLPMetricExporterOptions & OTLPExporterConfigBase = defaultOptions) { + constructor(config?: OTLPMetricExporterOptions & OTLPExporterConfigBase) { super(config); this._headers = Object.assign( this._headers, @@ -60,7 +60,7 @@ class OTLPExporterBrowserProxy extends OTLPExporterBrowserBase { - constructor(config: OTLPExporterConfigBase & OTLPMetricExporterOptions = defaultOptions) { + constructor(config?: OTLPExporterConfigBase & OTLPMetricExporterOptions) { super(new OTLPExporterBrowserProxy(config), config); } } diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/node/OTLPMetricExporter.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/node/OTLPMetricExporter.ts index 579fe95696..d09693a253 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/node/OTLPMetricExporter.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/node/OTLPMetricExporter.ts @@ -16,7 +16,7 @@ import { ResourceMetrics } from '@opentelemetry/sdk-metrics'; import { getEnv, baggageUtils} from '@opentelemetry/core'; -import { defaultOptions, OTLPMetricExporterOptions } from '../../OTLPMetricExporterOptions'; +import { OTLPMetricExporterOptions } from '../../OTLPMetricExporterOptions'; import { OTLPMetricExporterBase } from '../../OTLPMetricExporterBase'; import { OTLPExporterNodeBase, @@ -31,7 +31,7 @@ const DEFAULT_COLLECTOR_URL = `http://localhost:4318/${DEFAULT_COLLECTOR_RESOURC class OTLPExporterNodeProxy extends OTLPExporterNodeBase { - constructor(config: OTLPExporterNodeConfigBase & OTLPMetricExporterOptions = defaultOptions) { + constructor(config?: OTLPExporterNodeConfigBase & OTLPMetricExporterOptions) { super(config); this.headers = Object.assign( this.headers, @@ -60,7 +60,7 @@ class OTLPExporterNodeProxy extends OTLPExporterNodeBase { - constructor(config: OTLPExporterNodeConfigBase & OTLPMetricExporterOptions = defaultOptions) { + constructor(config?: OTLPExporterNodeConfigBase & OTLPMetricExporterOptions) { super(new OTLPExporterNodeProxy(config), config); } } diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/common/CollectorMetricExporter.test.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/common/CollectorMetricExporter.test.ts index 38c0b3bcc7..406e20f612 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/common/CollectorMetricExporter.test.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/common/CollectorMetricExporter.test.ts @@ -20,22 +20,34 @@ import { } from '@opentelemetry/sdk-metrics'; import * as assert from 'assert'; import * as sinon from 'sinon'; -import { collect, mockCounter, mockObservableGauge, setUp, shutdown } from '../metricsHelper'; -import { OTLPExporterBase, OTLPExporterConfigBase } from '@opentelemetry/otlp-exporter-base'; +import { + collect, + mockCounter, + mockObservableGauge, + setUp, + shutdown +} from '../metricsHelper'; +import { + OTLPExporterBase, + OTLPExporterConfigBase +} from '@opentelemetry/otlp-exporter-base'; import { IExportMetricsServiceRequest } from '@opentelemetry/otlp-transformer'; type CollectorExporterConfig = OTLPExporterConfigBase; -class OTLPMetricExporter extends OTLPExporterBase< - CollectorExporterConfig, + +class OTLPMetricExporter extends OTLPExporterBase { + IExportMetricsServiceRequest> { onInit() {} + onShutdown() {} + send() {} + getDefaultUrl(config: CollectorExporterConfig) { return config.url || ''; } + convert(metrics: ResourceMetrics[]): IExportMetricsServiceRequest { return { resourceMetrics: [] }; } @@ -125,7 +137,7 @@ describe('OTLPMetricExporter - common', () => { describe('when exporter is shutdown', () => { it( 'should not export anything but return callback with code' + - ' "FailedNotRetryable"', + ' "FailedNotRetryable"', async () => { await collectorExporter.shutdown(); spySend.resetHistory(); diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/CollectorMetricExporter.test.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/CollectorMetricExporter.test.ts index 77c5023153..68dd569d89 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/CollectorMetricExporter.test.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/CollectorMetricExporter.test.ts @@ -15,12 +15,17 @@ */ -import { diag, DiagLogger } from '@opentelemetry/api'; +import { + diag, + DiagLogger +} from '@opentelemetry/api'; import * as core from '@opentelemetry/core'; import * as assert from 'assert'; import * as http from 'http'; import * as sinon from 'sinon'; import { + CumulativeTemporalitySelector, + DeltaTemporalitySelector, OTLPMetricExporterOptions } from '../../src'; @@ -28,22 +33,31 @@ import { OTLPMetricExporter } from '../../src/platform/node'; import { + collect, ensureCounterIsCorrect, ensureExportMetricsServiceRequestIsSet, - ensureObservableGaugeIsCorrect, ensureHistogramIsCorrect, + ensureObservableGaugeIsCorrect, + HISTOGRAM_AGGREGATION_VIEW, mockCounter, - mockObservableGauge, mockHistogram, - collect, - shutdown, + mockObservableGauge, setUp, - HISTOGRAM_AGGREGATION_VIEW, + shutdown, } from '../metricsHelper'; import { MockedResponse } from './nodeHelpers'; -import { AggregationTemporality, ResourceMetrics } from '@opentelemetry/sdk-metrics'; -import { Stream, PassThrough } from 'stream'; -import { OTLPExporterError, OTLPExporterNodeConfigBase } from '@opentelemetry/otlp-exporter-base'; +import { + AggregationTemporality, + ResourceMetrics +} from '@opentelemetry/sdk-metrics'; +import { + PassThrough, + Stream +} from 'stream'; +import { + OTLPExporterError, + OTLPExporterNodeConfigBase +} from '@opentelemetry/otlp-exporter-base'; import { IExportMetricsServiceRequest } from '@opentelemetry/otlp-transformer'; let fakeRequest: PassThrough; @@ -190,6 +204,34 @@ describe('OTLPMetricExporter - node with json over http', () => { envSource.OTEL_EXPORTER_OTLP_METRICS_HEADERS = ''; envSource.OTEL_EXPORTER_OTLP_HEADERS = ''; }); + it('should use delta temporality defined via env', () => { + for (const envValue of ['delta', 'DELTA', 'DeLTa', 'delta ']) { + envSource.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE = envValue; + const exporter = new OTLPMetricExporter(); + assert.strictEqual(exporter['_aggregationTemporalitySelector'], DeltaTemporalitySelector); + } + }); + it('should use cumulative temporality defined via env', () => { + for (const envValue of ['cumulative', 'CUMULATIVE', 'CuMULaTIvE', 'cumulative ']) { + envSource.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE = envValue; + const exporter = new OTLPMetricExporter(); + assert.strictEqual(exporter['_aggregationTemporalitySelector'], CumulativeTemporalitySelector); + } + }); + it('should configure cumulative temporality with invalid value in env', () => { + for (const envValue of ['invalid', ' ']) { + envSource.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE = envValue; + const exporter = new OTLPMetricExporter(); + assert.strictEqual(exporter['_aggregationTemporalitySelector'], CumulativeTemporalitySelector); + } + }); + it('should respect explicit config over environment variable', () => { + envSource.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE = 'cumulative'; + const exporter = new OTLPMetricExporter({ + temporalityPreference: AggregationTemporality.DELTA + }); + assert.strictEqual(exporter['_aggregationTemporalitySelector'], DeltaTemporalitySelector); + }); }); describe('export', () => { diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/README.md b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/README.md index a5d812236d..6a2e160bac 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/README.md +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/README.md @@ -43,6 +43,19 @@ counter.add(10, { 'key': 'value' }); ``` +## Environment Variable Configuration + +In addition to settings passed to the constructor, the exporter also supports configuration via environment variables: + +| Environment variable | Description | +|---------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 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. | + +> Settings configured programmatically take precedence over environment variables. Per-signal environment variables take +> precedence over non-per-signal environment variables. + ## Running opentelemetry-collector locally to see the metrics 1. Go to `examples/otlp-exporter-node` diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/src/OTLPMetricExporter.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/src/OTLPMetricExporter.ts index e3d8a60155..e62a8e0ece 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/src/OTLPMetricExporter.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/src/OTLPMetricExporter.ts @@ -15,7 +15,6 @@ */ import { - defaultOptions, OTLPMetricExporterOptions } from '@opentelemetry/exporter-metrics-otlp-http'; import { ServiceClientType, OTLPProtoExporterNodeBase } from '@opentelemetry/otlp-proto-exporter-base'; @@ -34,7 +33,7 @@ const DEFAULT_COLLECTOR_URL = `http://localhost:4318/${DEFAULT_COLLECTOR_RESOURC class OTLPMetricExporterNodeProxy extends OTLPProtoExporterNodeBase { - constructor(config: OTLPExporterNodeConfigBase & OTLPMetricExporterOptions = defaultOptions) { + constructor(config?: OTLPExporterNodeConfigBase & OTLPMetricExporterOptions) { super(config); this.headers = Object.assign( this.headers, @@ -64,7 +63,7 @@ class OTLPMetricExporterNodeProxy extends OTLPProtoExporterNodeBase { - constructor(config: OTLPExporterNodeConfigBase & OTLPMetricExporterOptions = defaultOptions) { + constructor(config?: OTLPExporterNodeConfigBase & OTLPMetricExporterOptions) { super(new OTLPMetricExporterNodeProxy(config), config); } } diff --git a/packages/opentelemetry-core/src/utils/environment.ts b/packages/opentelemetry-core/src/utils/environment.ts index 8d50e2cb9b..fcb0614c61 100644 --- a/packages/opentelemetry-core/src/utils/environment.ts +++ b/packages/opentelemetry-core/src/utils/environment.ts @@ -106,6 +106,7 @@ export type ENVIRONMENT = { OTEL_EXPORTER_OTLP_PROTOCOL?: string, OTEL_EXPORTER_OTLP_TRACES_PROTOCOL?: string, OTEL_EXPORTER_OTLP_METRICS_PROTOCOL?: string, + OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE?: string } & ENVIRONMENT_NUMBERS & ENVIRONMENT_LISTS; @@ -178,6 +179,7 @@ export const DEFAULT_ENVIRONMENT: Required = { OTEL_EXPORTER_OTLP_PROTOCOL: 'http/protobuf', OTEL_EXPORTER_OTLP_TRACES_PROTOCOL: 'http/protobuf', OTEL_EXPORTER_OTLP_METRICS_PROTOCOL: 'http/protobuf', + OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE: 'cumulative' }; /**