@@ -281,111 +281,212 @@ export function setMeterProvider(config: ConfigurationModel): void {
281281 readerPeriodic . interval = interval ;
282282 }
283283
284- const timeout = getNumberFromEnv ( 'OTEL_METRIC_EXPORT_TIMEOUT' ) ;
285- if ( timeout ) {
286- readerPeriodic . timeout = timeout ;
287- }
288- if ( readerPeriodic . exporter . otlp_http == null ) {
289- readerPeriodic . exporter . otlp_http = { } ;
290- }
291-
292- const endpoint =
293- getStringFromEnv ( 'OTEL_EXPORTER_OTLP_METRICS_ENDPOINT' ) ??
294- ( getStringFromEnv ( 'OTEL_EXPORTER_OTLP_ENDPOINT' )
295- ? `${ getStringFromEnv ( 'OTEL_EXPORTER_OTLP_ENDPOINT' ) } /v1/metrics`
296- : null ) ;
297- if ( endpoint ) {
298- readerPeriodic . exporter . otlp_http . endpoint = endpoint ;
299- }
300-
301- const certificateFile =
302- getStringFromEnv ( 'OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE' ) ??
303- getStringFromEnv ( 'OTEL_EXPORTER_OTLP_CERTIFICATE' ) ;
304- if ( certificateFile ) {
305- readerPeriodic . exporter . otlp_http . certificate_file = certificateFile ;
306- }
307-
308- const clientKeyFile =
309- getStringFromEnv ( 'OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY' ) ??
310- getStringFromEnv ( 'OTEL_EXPORTER_OTLP_CLIENT_KEY' ) ;
311- if ( clientKeyFile ) {
312- readerPeriodic . exporter . otlp_http . client_key_file = clientKeyFile ;
313- }
314-
315- const clientCertificateFile =
316- getStringFromEnv ( 'OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE' ) ??
317- getStringFromEnv ( 'OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE' ) ;
318- if ( clientCertificateFile ) {
319- readerPeriodic . exporter . otlp_http . client_certificate_file =
320- clientCertificateFile ;
321- }
322-
323- const compression =
324- getStringFromEnv ( 'OTEL_EXPORTER_OTLP_METRICS_COMPRESSION' ) ??
325- getStringFromEnv ( 'OTEL_EXPORTER_OTLP_COMPRESSION' ) ;
326- if ( compression ) {
327- readerPeriodic . exporter . otlp_http . compression = compression ;
328- }
329-
330- const timeoutEx =
331- getNumberFromEnv ( 'OTEL_EXPORTER_OTLP_METRICS_TIMEOUT' ) ??
332- getNumberFromEnv ( 'OTEL_EXPORTER_OTLP_TIMEOUT' ) ;
333- if ( timeoutEx ) {
334- readerPeriodic . exporter . otlp_http . timeout = timeoutEx ;
284+ const exportersType = Array . from (
285+ new Set ( getStringListFromEnv ( 'OTEL_METRICS_EXPORTER' ) )
286+ ) ;
287+ if ( exportersType . length === 0 ) {
288+ exportersType . push ( 'otlp' ) ;
335289 }
336290
337- const headersList =
338- getStringFromEnv ( 'OTEL_EXPORTER_OTLP_METRICS_HEADERS' ) ??
339- getStringFromEnv ( 'OTEL_EXPORTER_OTLP_HEADERS' ) ;
340- if ( headersList ) {
341- readerPeriodic . exporter . otlp_http . headers_list = headersList ;
291+ config . meter_provider . readers = [ ] ;
292+ if ( exportersType . includes ( 'none' ) ) {
293+ diag . info (
294+ `OTEL_METRICS_EXPORTER contains "none". Meter provider will not be initialized.`
295+ ) ;
296+ return ;
342297 }
343-
344- const temporalityPreference = getStringFromEnv (
345- 'OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE'
346- ) ;
347- if ( temporalityPreference ) {
348- switch ( temporalityPreference ) {
349- case 'cumulative' :
350- readerPeriodic . exporter . otlp_http . temporality_preference =
351- ExporterTemporalityPreference . Cumulative ;
352- break ;
353- case 'delta' :
354- readerPeriodic . exporter . otlp_http . temporality_preference =
355- ExporterTemporalityPreference . Delta ;
356- break ;
357- case 'low_memory' :
358- readerPeriodic . exporter . otlp_http . temporality_preference =
359- ExporterTemporalityPreference . LowMemory ;
360- break ;
361- default :
362- readerPeriodic . exporter . otlp_http . temporality_preference =
363- ExporterTemporalityPreference . Cumulative ;
364- break ;
298+ for ( let i = 0 ; i < exportersType . length ; i ++ ) {
299+ const exporterType = exportersType [ i ] ;
300+ const readerPeriodicInfo = { ...readerPeriodic } ;
301+ const timeout = getNumberFromEnv ( 'OTEL_METRIC_EXPORT_TIMEOUT' ) ?? 30000 ;
302+ if ( timeout ) {
303+ readerPeriodicInfo . timeout = timeout ;
365304 }
366- }
367305
368- const defaultHistogramAggregation = getStringFromEnv (
369- 'OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION'
370- ) ;
371- if ( defaultHistogramAggregation ) {
372- switch ( defaultHistogramAggregation ) {
373- case 'explicit_bucket_histogram' :
374- readerPeriodic . exporter . otlp_http . default_histogram_aggregation =
375- ExporterDefaultHistogramAggregation . ExplicitBucketHistogram ;
376- break ;
377- case 'base2_exponential_bucket_histogram' :
378- readerPeriodic . exporter . otlp_http . default_histogram_aggregation =
379- ExporterDefaultHistogramAggregation . Base2ExponentialBucketHistogram ;
380- break ;
381- default :
382- readerPeriodic . exporter . otlp_http . default_histogram_aggregation =
383- ExporterDefaultHistogramAggregation . ExplicitBucketHistogram ;
384- break ;
306+ // TODO: add prometheus exporter support
307+ if ( exporterType === 'console' ) {
308+ readerPeriodicInfo . exporter = { console : { } } ;
309+ } else {
310+ // 'otlp' and default
311+ const protocol =
312+ getStringFromEnv ( 'OTEL_EXPORTER_OTLP_METRICS_PROTOCOL' ) ??
313+ getStringFromEnv ( 'OTEL_EXPORTER_OTLP_PROTOCOL' ) ??
314+ 'http/protobuf' ;
315+ const certificateFile =
316+ getStringFromEnv ( 'OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE' ) ??
317+ getStringFromEnv ( 'OTEL_EXPORTER_OTLP_CERTIFICATE' ) ;
318+ const clientKeyFile =
319+ getStringFromEnv ( 'OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY' ) ??
320+ getStringFromEnv ( 'OTEL_EXPORTER_OTLP_CLIENT_KEY' ) ;
321+ const clientCertificateFile =
322+ getStringFromEnv ( 'OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE' ) ??
323+ getStringFromEnv ( 'OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE' ) ;
324+ const compression =
325+ getStringFromEnv ( 'OTEL_EXPORTER_OTLP_METRICS_COMPRESSION' ) ??
326+ getStringFromEnv ( 'OTEL_EXPORTER_OTLP_COMPRESSION' ) ;
327+ const timeoutExporter =
328+ getNumberFromEnv ( 'OTEL_EXPORTER_OTLP_METRICS_TIMEOUT' ) ??
329+ getNumberFromEnv ( 'OTEL_EXPORTER_OTLP_TIMEOUT' ) ??
330+ 10000 ;
331+ const headersList =
332+ getStringFromEnv ( 'OTEL_EXPORTER_OTLP_METRICS_HEADERS' ) ??
333+ getStringFromEnv ( 'OTEL_EXPORTER_OTLP_HEADERS' ) ;
334+ const temporalityPreference =
335+ getStringFromEnv (
336+ 'OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE'
337+ ) ?? 'cumulative' ;
338+ const defaultHistogramAggregation =
339+ getStringFromEnv (
340+ 'OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION'
341+ ) ?? 'explicit_bucket_histogram' ;
342+
343+ if ( protocol === 'grpc' ) {
344+ delete readerPeriodicInfo . exporter . otlp_http ;
345+ readerPeriodicInfo . exporter . otlp_grpc = { } ;
346+ const endpoint =
347+ getStringFromEnv ( 'OTEL_EXPORTER_OTLP_METRICS_ENDPOINT' ) ??
348+ getStringFromEnv ( 'OTEL_EXPORTER_OTLP_ENDPOINT' ) ??
349+ 'http://localhost:4317' ;
350+ if ( endpoint ) {
351+ readerPeriodicInfo . exporter . otlp_grpc . endpoint = endpoint ;
352+ }
353+ if ( certificateFile ) {
354+ readerPeriodicInfo . exporter . otlp_grpc . certificate_file =
355+ certificateFile ;
356+ }
357+ if ( clientKeyFile ) {
358+ readerPeriodicInfo . exporter . otlp_grpc . client_key_file =
359+ clientKeyFile ;
360+ }
361+ if ( clientCertificateFile ) {
362+ readerPeriodicInfo . exporter . otlp_grpc . client_certificate_file =
363+ clientCertificateFile ;
364+ }
365+ if ( compression ) {
366+ readerPeriodicInfo . exporter . otlp_grpc . compression = compression ;
367+ }
368+ if ( timeoutExporter ) {
369+ readerPeriodicInfo . exporter . otlp_grpc . timeout = timeoutExporter ;
370+ }
371+ if ( headersList ) {
372+ readerPeriodicInfo . exporter . otlp_grpc . headers_list = headersList ;
373+ }
374+ if ( temporalityPreference ) {
375+ switch ( temporalityPreference ) {
376+ case 'cumulative' :
377+ readerPeriodicInfo . exporter . otlp_grpc . temporality_preference =
378+ ExporterTemporalityPreference . Cumulative ;
379+ break ;
380+ case 'delta' :
381+ readerPeriodicInfo . exporter . otlp_grpc . temporality_preference =
382+ ExporterTemporalityPreference . Delta ;
383+ break ;
384+ case 'low_memory' :
385+ readerPeriodicInfo . exporter . otlp_grpc . temporality_preference =
386+ ExporterTemporalityPreference . LowMemory ;
387+ break ;
388+ default :
389+ readerPeriodicInfo . exporter . otlp_grpc . temporality_preference =
390+ ExporterTemporalityPreference . Cumulative ;
391+ break ;
392+ }
393+ }
394+ if ( defaultHistogramAggregation ) {
395+ switch ( defaultHistogramAggregation ) {
396+ case 'explicit_bucket_histogram' :
397+ readerPeriodicInfo . exporter . otlp_grpc . default_histogram_aggregation =
398+ ExporterDefaultHistogramAggregation . ExplicitBucketHistogram ;
399+ break ;
400+ case 'base2_exponential_bucket_histogram' :
401+ readerPeriodicInfo . exporter . otlp_grpc . default_histogram_aggregation =
402+ ExporterDefaultHistogramAggregation . Base2ExponentialBucketHistogram ;
403+ break ;
404+ default :
405+ readerPeriodicInfo . exporter . otlp_grpc . default_histogram_aggregation =
406+ ExporterDefaultHistogramAggregation . ExplicitBucketHistogram ;
407+ break ;
408+ }
409+ }
410+ } else {
411+ if ( readerPeriodicInfo . exporter . otlp_http == null ) {
412+ readerPeriodicInfo . exporter . otlp_http = { } ;
413+ }
414+ const endpoint =
415+ getStringFromEnv ( 'OTEL_EXPORTER_OTLP_METRICS_ENDPOINT' ) ??
416+ ( getStringFromEnv ( 'OTEL_EXPORTER_OTLP_ENDPOINT' )
417+ ? `${ getStringFromEnv ( 'OTEL_EXPORTER_OTLP_ENDPOINT' ) } /v1/metrics`
418+ : null ) ;
419+ if ( endpoint ) {
420+ readerPeriodicInfo . exporter . otlp_http . endpoint = endpoint ;
421+ }
422+ if ( certificateFile ) {
423+ readerPeriodicInfo . exporter . otlp_http . certificate_file =
424+ certificateFile ;
425+ }
426+ if ( clientKeyFile ) {
427+ readerPeriodicInfo . exporter . otlp_http . client_key_file =
428+ clientKeyFile ;
429+ }
430+ if ( clientCertificateFile ) {
431+ readerPeriodicInfo . exporter . otlp_http . client_certificate_file =
432+ clientCertificateFile ;
433+ }
434+ if ( compression ) {
435+ readerPeriodicInfo . exporter . otlp_http . compression = compression ;
436+ }
437+ if ( timeoutExporter ) {
438+ readerPeriodicInfo . exporter . otlp_http . timeout = timeoutExporter ;
439+ }
440+ if ( headersList ) {
441+ readerPeriodicInfo . exporter . otlp_http . headers_list = headersList ;
442+ }
443+ if ( temporalityPreference ) {
444+ switch ( temporalityPreference ) {
445+ case 'cumulative' :
446+ readerPeriodicInfo . exporter . otlp_http . temporality_preference =
447+ ExporterTemporalityPreference . Cumulative ;
448+ break ;
449+ case 'delta' :
450+ readerPeriodicInfo . exporter . otlp_http . temporality_preference =
451+ ExporterTemporalityPreference . Delta ;
452+ break ;
453+ case 'low_memory' :
454+ readerPeriodicInfo . exporter . otlp_http . temporality_preference =
455+ ExporterTemporalityPreference . LowMemory ;
456+ break ;
457+ default :
458+ readerPeriodicInfo . exporter . otlp_http . temporality_preference =
459+ ExporterTemporalityPreference . Cumulative ;
460+ break ;
461+ }
462+ }
463+ if ( defaultHistogramAggregation ) {
464+ switch ( defaultHistogramAggregation ) {
465+ case 'explicit_bucket_histogram' :
466+ readerPeriodicInfo . exporter . otlp_http . default_histogram_aggregation =
467+ ExporterDefaultHistogramAggregation . ExplicitBucketHistogram ;
468+ break ;
469+ case 'base2_exponential_bucket_histogram' :
470+ readerPeriodicInfo . exporter . otlp_http . default_histogram_aggregation =
471+ ExporterDefaultHistogramAggregation . Base2ExponentialBucketHistogram ;
472+ break ;
473+ default :
474+ readerPeriodicInfo . exporter . otlp_http . default_histogram_aggregation =
475+ ExporterDefaultHistogramAggregation . ExplicitBucketHistogram ;
476+ break ;
477+ }
478+ }
479+ if ( protocol === 'http/json' ) {
480+ readerPeriodicInfo . exporter . otlp_http . encoding =
481+ OtlpHttpEncoding . JSON ;
482+ } else if ( protocol === 'http/protobuf' ) {
483+ readerPeriodicInfo . exporter . otlp_http . encoding =
484+ OtlpHttpEncoding . Protobuf ;
485+ }
486+ }
385487 }
488+ config . meter_provider . readers . push ( { periodic : readerPeriodicInfo } ) ;
386489 }
387-
388- config . meter_provider . readers [ 0 ] . periodic = readerPeriodic ;
389490 }
390491 const exemplarFilter = getStringFromEnv ( 'OTEL_METRICS_EXEMPLAR_FILTER' ) ;
391492 if ( exemplarFilter ) {
0 commit comments