diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 42ea1b00f93..4f8774c512e 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -17,7 +17,8 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2 * feat(configuration): set tracer provider exporter type from env variables [#6106](https://github.com/open-telemetry/opentelemetry-js/pull/6106) @maryliag * feat(configuration): set meter provider exporter type from env variable [#6105](https://github.com/open-telemetry/opentelemetry-js/pull/6105) @maryliag * refactor(configuration): throw warning and not error for invalid files [#6124](https://github.com/open-telemetry/opentelemetry-js/pull/6124) @maryliag -* refactor(configuration): dont have a default value for node resource detectors [#x](https://github.com/open-telemetry/opentelemetry-js/pull/x) @maryliag +* refactor(configuration): dont have a default value for node resource detectors [#6131](https://github.com/open-telemetry/opentelemetry-js/pull/6131) @maryliag +* feat(configuration): doesnt set meter,tracer,logger provider by default [#6130](https://github.com/open-telemetry/opentelemetry-js/pull/6130) @maryliag ### :bug: Bug Fixes diff --git a/experimental/packages/configuration/src/EnvironmentConfigFactory.ts b/experimental/packages/configuration/src/EnvironmentConfigFactory.ts index 16718d7991b..918a044a4f1 100644 --- a/experimental/packages/configuration/src/EnvironmentConfigFactory.ts +++ b/experimental/packages/configuration/src/EnvironmentConfigFactory.ts @@ -30,9 +30,19 @@ import { ExemplarFilter, ExporterDefaultHistogramAggregation, ExporterTemporalityPreference, + initializeDefaultMeterProviderConfiguration, + PeriodicMetricReader, } from './models/meterProviderModel'; import { OtlpHttpEncoding } from './models/commonModel'; import { diag } from '@opentelemetry/api'; +import { + BatchSpanProcessor, + initializeDefaultTracerProviderConfiguration, +} from './models/tracerProviderModel'; +import { + BatchLogRecordProcessor, + initializeDefaultLoggerProviderConfiguration, +} from './models/loggerProviderModel'; /** * EnvironmentConfigProvider provides a configuration based on environment variables. @@ -141,9 +151,20 @@ export function setPropagators(config: ConfigurationModel): void { } export function setTracerProvider(config: ConfigurationModel): void { - if (config.tracer_provider == null) { - config.tracer_provider = { processors: [] }; + const exportersType = Array.from( + new Set(getStringListFromEnv('OTEL_TRACES_EXPORTER')) + ); + if (exportersType.length === 0) { + return; + } + if (exportersType.includes('none')) { + diag.info( + `OTEL_TRACES_EXPORTER contains "none". Tracer provider will not be initialized.` + ); + return; } + config.tracer_provider = initializeDefaultTracerProviderConfiguration(); + if (config.tracer_provider.limits == null) { config.tracer_provider.limits = {}; } @@ -188,377 +209,355 @@ export function setTracerProvider(config: ConfigurationModel): void { linkAttributeCountLimit; } - const batch = config.tracer_provider.processors[0]?.batch; - if (batch) { - const scheduleDelay = getNumberFromEnv('OTEL_BSP_SCHEDULE_DELAY'); - if (scheduleDelay) { - batch.schedule_delay = scheduleDelay; - } - - const exportTimeout = getNumberFromEnv('OTEL_BSP_EXPORT_TIMEOUT'); - if (exportTimeout) { - batch.export_timeout = exportTimeout; - } + const batch: BatchSpanProcessor = { exporter: {} }; + const scheduleDelay = getNumberFromEnv('OTEL_BSP_SCHEDULE_DELAY') ?? 5000; + if (scheduleDelay) { + batch.schedule_delay = scheduleDelay; + } - const maxQueueSize = getNumberFromEnv('OTEL_BSP_MAX_QUEUE_SIZE'); - if (maxQueueSize) { - batch.max_queue_size = maxQueueSize; - } + const exportTimeout = getNumberFromEnv('OTEL_BSP_EXPORT_TIMEOUT') ?? 30000; + if (exportTimeout) { + batch.export_timeout = exportTimeout; + } - const maxExportBatchSize = getNumberFromEnv( - 'OTEL_BSP_MAX_EXPORT_BATCH_SIZE' - ); - if (maxExportBatchSize) { - batch.max_export_batch_size = maxExportBatchSize; - } + const maxQueueSize = getNumberFromEnv('OTEL_BSP_MAX_QUEUE_SIZE') ?? 2048; + if (maxQueueSize) { + batch.max_queue_size = maxQueueSize; + } - const exportersType = Array.from( - new Set(getStringListFromEnv('OTEL_TRACES_EXPORTER')) - ); - if (exportersType.length === 0) { - exportersType.push('otlp'); - } + const maxExportBatchSize = + getNumberFromEnv('OTEL_BSP_MAX_EXPORT_BATCH_SIZE') ?? 512; + if (maxExportBatchSize) { + batch.max_export_batch_size = maxExportBatchSize; + } - config.tracer_provider.processors = []; - if (exportersType.includes('none')) { - diag.info( - `OTEL_TRACES_EXPORTER contains "none". Tracer provider will not be initialized.` - ); - return; - } - for (let i = 0; i < exportersType.length; i++) { - const exporterType = exportersType[i]; - const batchInfo = { ...batch }; - if (exporterType === 'console') { - config.tracer_provider.processors.push({ - simple: { exporter: { console: {} } }, - }); - } else if (exporterType === 'zipkin') { - batchInfo.exporter = { - zipkin: { - endpoint: - getStringFromEnv('OTEL_EXPORTER_ZIPKIN_ENDPOINT') ?? - 'http://localhost:9411/api/v2/spans', - timeout: getNumberFromEnv('OTEL_EXPORTER_ZIPKIN_TIMEOUT') ?? 10000, - }, - }; - config.tracer_provider.processors.push({ batch: batchInfo }); + for (let i = 0; i < exportersType.length; i++) { + const exporterType = exportersType[i]; + const batchInfo = { ...batch }; + if (exporterType === 'console') { + config.tracer_provider.processors.push({ + simple: { exporter: { console: {} } }, + }); + } else if (exporterType === 'zipkin') { + batchInfo.exporter = { + zipkin: { + endpoint: + getStringFromEnv('OTEL_EXPORTER_ZIPKIN_ENDPOINT') ?? + 'http://localhost:9411/api/v2/spans', + timeout: getNumberFromEnv('OTEL_EXPORTER_ZIPKIN_TIMEOUT') ?? 10000, + }, + }; + config.tracer_provider.processors.push({ batch: batchInfo }); + } else { + // 'otlp' and default + const protocol = + getStringFromEnv('OTEL_EXPORTER_OTLP_TRACES_PROTOCOL') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_PROTOCOL') ?? + 'http/protobuf'; + const certificateFile = + getStringFromEnv('OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_CERTIFICATE'); + const clientKeyFile = + getStringFromEnv('OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_CLIENT_KEY'); + const clientCertificateFile = + getStringFromEnv('OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE'); + const compression = + getStringFromEnv('OTEL_EXPORTER_OTLP_TRACES_COMPRESSION') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_COMPRESSION'); + const timeout = + getNumberFromEnv('OTEL_EXPORTER_OTLP_TRACES_TIMEOUT') ?? + getNumberFromEnv('OTEL_EXPORTER_OTLP_TIMEOUT') ?? + 10000; + const headersList = + getStringFromEnv('OTEL_EXPORTER_OTLP_TRACES_HEADERS') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_HEADERS'); + + if (protocol === 'grpc') { + delete batchInfo.exporter.otlp_http; + batchInfo.exporter.otlp_grpc = {}; + const endpoint = + getStringFromEnv('OTEL_EXPORTER_OTLP_TRACES_ENDPOINT') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT') ?? + 'http://localhost:4317'; + if (endpoint) { + batchInfo.exporter.otlp_grpc.endpoint = endpoint; + } + if (certificateFile) { + batchInfo.exporter.otlp_grpc.certificate_file = certificateFile; + } + if (clientKeyFile) { + batchInfo.exporter.otlp_grpc.client_key_file = clientKeyFile; + } + if (clientCertificateFile) { + batchInfo.exporter.otlp_grpc.client_certificate_file = + clientCertificateFile; + } + if (compression) { + batchInfo.exporter.otlp_grpc.compression = compression; + } + if (timeout) { + batchInfo.exporter.otlp_grpc.timeout = timeout; + } + if (headersList) { + batchInfo.exporter.otlp_grpc.headers_list = headersList; + } } else { - // 'otlp' and default - const protocol = - getStringFromEnv('OTEL_EXPORTER_OTLP_TRACES_PROTOCOL') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_PROTOCOL') ?? - 'http/protobuf'; - const certificateFile = - getStringFromEnv('OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_CERTIFICATE'); - const clientKeyFile = - getStringFromEnv('OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_CLIENT_KEY'); - const clientCertificateFile = - getStringFromEnv('OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE'); - const compression = - getStringFromEnv('OTEL_EXPORTER_OTLP_TRACES_COMPRESSION') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_COMPRESSION'); - const timeout = - getNumberFromEnv('OTEL_EXPORTER_OTLP_TRACES_TIMEOUT') ?? - getNumberFromEnv('OTEL_EXPORTER_OTLP_TIMEOUT') ?? - 10000; - const headersList = - getStringFromEnv('OTEL_EXPORTER_OTLP_TRACES_HEADERS') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_HEADERS'); - - if (protocol === 'grpc') { - delete batchInfo.exporter.otlp_http; - batchInfo.exporter.otlp_grpc = {}; - const endpoint = - getStringFromEnv('OTEL_EXPORTER_OTLP_TRACES_ENDPOINT') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT') ?? - 'http://localhost:4317'; - if (endpoint) { - batchInfo.exporter.otlp_grpc.endpoint = endpoint; - } - if (certificateFile) { - batchInfo.exporter.otlp_grpc.certificate_file = certificateFile; - } - if (clientKeyFile) { - batchInfo.exporter.otlp_grpc.client_key_file = clientKeyFile; - } - if (clientCertificateFile) { - batchInfo.exporter.otlp_grpc.client_certificate_file = - clientCertificateFile; - } - if (compression) { - batchInfo.exporter.otlp_grpc.compression = compression; - } - if (timeout) { - batchInfo.exporter.otlp_grpc.timeout = timeout; - } - if (headersList) { - batchInfo.exporter.otlp_grpc.headers_list = headersList; - } - } else { - if (batchInfo.exporter.otlp_http == null) { - batchInfo.exporter.otlp_http = {}; - } - const endpoint = - getStringFromEnv('OTEL_EXPORTER_OTLP_TRACES_ENDPOINT') ?? - (getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT') - ? `${getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT')}/v1/traces` - : null); - if (endpoint) { - batchInfo.exporter.otlp_http.endpoint = endpoint; - } - if (certificateFile) { - batchInfo.exporter.otlp_http.certificate_file = certificateFile; - } - if (clientKeyFile) { - batchInfo.exporter.otlp_http.client_key_file = clientKeyFile; - } - if (clientCertificateFile) { - batchInfo.exporter.otlp_http.client_certificate_file = - clientCertificateFile; - } - if (compression) { - batchInfo.exporter.otlp_http.compression = compression; - } - if (timeout) { - batchInfo.exporter.otlp_http.timeout = timeout; - } - if (headersList) { - batchInfo.exporter.otlp_http.headers_list = headersList; - } + if (batchInfo.exporter.otlp_http == null) { + batchInfo.exporter.otlp_http = {}; + } + const endpoint = + getStringFromEnv('OTEL_EXPORTER_OTLP_TRACES_ENDPOINT') ?? + (getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT') + ? `${getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT')}/v1/traces` + : 'http://localhost:4318/v1/traces'); + if (endpoint) { + batchInfo.exporter.otlp_http.endpoint = endpoint; + } + if (certificateFile) { + batchInfo.exporter.otlp_http.certificate_file = certificateFile; + } + if (clientKeyFile) { + batchInfo.exporter.otlp_http.client_key_file = clientKeyFile; + } + if (clientCertificateFile) { + batchInfo.exporter.otlp_http.client_certificate_file = + clientCertificateFile; + } + if (compression) { + batchInfo.exporter.otlp_http.compression = compression; + } + if (timeout) { + batchInfo.exporter.otlp_http.timeout = timeout; + } + if (headersList) { + batchInfo.exporter.otlp_http.headers_list = headersList; + } + if (protocol === 'http/json') { + batchInfo.exporter.otlp_http.encoding = OtlpHttpEncoding.JSON; + } else if (protocol === 'http/protobuf') { + batchInfo.exporter.otlp_http.encoding = OtlpHttpEncoding.Protobuf; } - - config.tracer_provider.processors.push({ batch: batchInfo }); } + + config.tracer_provider.processors.push({ batch: batchInfo }); } } } export function setMeterProvider(config: ConfigurationModel): void { - const readerPeriodic = - config.meter_provider?.readers && config.meter_provider?.readers.length > 0 - ? config.meter_provider?.readers[0].periodic - : undefined; - if (config.meter_provider == null) { - config.meter_provider = { readers: [{}] }; - } - if (readerPeriodic) { - const interval = getNumberFromEnv('OTEL_METRIC_EXPORT_INTERVAL'); - if (interval) { - readerPeriodic.interval = interval; - } - - const exportersType = Array.from( - new Set(getStringListFromEnv('OTEL_METRICS_EXPORTER')) + const exportersType = Array.from( + new Set(getStringListFromEnv('OTEL_METRICS_EXPORTER')) + ); + if (exportersType.length === 0) { + return; + } + if (exportersType.includes('none')) { + diag.info( + `OTEL_METRICS_EXPORTER contains "none". Meter provider will not be initialized.` ); - if (exportersType.length === 0) { - exportersType.push('otlp'); - } + return; + } + config.meter_provider = initializeDefaultMeterProviderConfiguration(); - config.meter_provider.readers = []; - if (exportersType.includes('none')) { - diag.info( - `OTEL_METRICS_EXPORTER contains "none". Meter provider will not be initialized.` - ); - return; + const readerPeriodic: PeriodicMetricReader = { exporter: {} }; + const interval = getNumberFromEnv('OTEL_METRIC_EXPORT_INTERVAL') ?? 60000; + if (interval) { + readerPeriodic.interval = interval; + } + for (let i = 0; i < exportersType.length; i++) { + const exporterType = exportersType[i]; + const readerPeriodicInfo = { ...readerPeriodic }; + const timeout = getNumberFromEnv('OTEL_METRIC_EXPORT_TIMEOUT') ?? 30000; + if (timeout) { + readerPeriodicInfo.timeout = timeout; } - for (let i = 0; i < exportersType.length; i++) { - const exporterType = exportersType[i]; - const readerPeriodicInfo = { ...readerPeriodic }; - const timeout = getNumberFromEnv('OTEL_METRIC_EXPORT_TIMEOUT') ?? 30000; - if (timeout) { - readerPeriodicInfo.timeout = timeout; - } - // TODO: add prometheus exporter support - if (exporterType === 'console') { - readerPeriodicInfo.exporter = { console: {} }; - } else { - // 'otlp' and default - const protocol = - getStringFromEnv('OTEL_EXPORTER_OTLP_METRICS_PROTOCOL') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_PROTOCOL') ?? - 'http/protobuf'; - const certificateFile = - getStringFromEnv('OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_CERTIFICATE'); - const clientKeyFile = - getStringFromEnv('OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_CLIENT_KEY'); - const clientCertificateFile = - getStringFromEnv('OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE'); - const compression = - getStringFromEnv('OTEL_EXPORTER_OTLP_METRICS_COMPRESSION') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_COMPRESSION'); - const timeoutExporter = - getNumberFromEnv('OTEL_EXPORTER_OTLP_METRICS_TIMEOUT') ?? - getNumberFromEnv('OTEL_EXPORTER_OTLP_TIMEOUT') ?? - 10000; - const headersList = - getStringFromEnv('OTEL_EXPORTER_OTLP_METRICS_HEADERS') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_HEADERS'); - const temporalityPreference = - getStringFromEnv( - 'OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE' - ) ?? 'cumulative'; - const defaultHistogramAggregation = - getStringFromEnv( - 'OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION' - ) ?? 'explicit_bucket_histogram'; - - if (protocol === 'grpc') { - delete readerPeriodicInfo.exporter.otlp_http; - readerPeriodicInfo.exporter.otlp_grpc = {}; - const endpoint = - getStringFromEnv('OTEL_EXPORTER_OTLP_METRICS_ENDPOINT') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT') ?? - 'http://localhost:4317'; - if (endpoint) { - readerPeriodicInfo.exporter.otlp_grpc.endpoint = endpoint; - } - if (certificateFile) { - readerPeriodicInfo.exporter.otlp_grpc.certificate_file = - certificateFile; - } - if (clientKeyFile) { - readerPeriodicInfo.exporter.otlp_grpc.client_key_file = - clientKeyFile; - } - if (clientCertificateFile) { - readerPeriodicInfo.exporter.otlp_grpc.client_certificate_file = - clientCertificateFile; - } - if (compression) { - readerPeriodicInfo.exporter.otlp_grpc.compression = compression; - } - if (timeoutExporter) { - readerPeriodicInfo.exporter.otlp_grpc.timeout = timeoutExporter; - } - if (headersList) { - readerPeriodicInfo.exporter.otlp_grpc.headers_list = headersList; - } - if (temporalityPreference) { - switch (temporalityPreference) { - case 'cumulative': - readerPeriodicInfo.exporter.otlp_grpc.temporality_preference = - ExporterTemporalityPreference.Cumulative; - break; - case 'delta': - readerPeriodicInfo.exporter.otlp_grpc.temporality_preference = - ExporterTemporalityPreference.Delta; - break; - case 'low_memory': - readerPeriodicInfo.exporter.otlp_grpc.temporality_preference = - ExporterTemporalityPreference.LowMemory; - break; - default: - readerPeriodicInfo.exporter.otlp_grpc.temporality_preference = - ExporterTemporalityPreference.Cumulative; - break; - } - } - if (defaultHistogramAggregation) { - switch (defaultHistogramAggregation) { - case 'explicit_bucket_histogram': - readerPeriodicInfo.exporter.otlp_grpc.default_histogram_aggregation = - ExporterDefaultHistogramAggregation.ExplicitBucketHistogram; - break; - case 'base2_exponential_bucket_histogram': - readerPeriodicInfo.exporter.otlp_grpc.default_histogram_aggregation = - ExporterDefaultHistogramAggregation.Base2ExponentialBucketHistogram; - break; - default: - readerPeriodicInfo.exporter.otlp_grpc.default_histogram_aggregation = - ExporterDefaultHistogramAggregation.ExplicitBucketHistogram; - break; - } - } - } else { - if (readerPeriodicInfo.exporter.otlp_http == null) { - readerPeriodicInfo.exporter.otlp_http = {}; - } - const endpoint = - getStringFromEnv('OTEL_EXPORTER_OTLP_METRICS_ENDPOINT') ?? - (getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT') - ? `${getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT')}/v1/metrics` - : null); - if (endpoint) { - readerPeriodicInfo.exporter.otlp_http.endpoint = endpoint; - } - if (certificateFile) { - readerPeriodicInfo.exporter.otlp_http.certificate_file = - certificateFile; - } - if (clientKeyFile) { - readerPeriodicInfo.exporter.otlp_http.client_key_file = - clientKeyFile; - } - if (clientCertificateFile) { - readerPeriodicInfo.exporter.otlp_http.client_certificate_file = - clientCertificateFile; - } - if (compression) { - readerPeriodicInfo.exporter.otlp_http.compression = compression; - } - if (timeoutExporter) { - readerPeriodicInfo.exporter.otlp_http.timeout = timeoutExporter; - } - if (headersList) { - readerPeriodicInfo.exporter.otlp_http.headers_list = headersList; + // TODO: add prometheus exporter support + if (exporterType === 'console') { + readerPeriodicInfo.exporter = { console: {} }; + } else { + // 'otlp' and default + const protocol = + getStringFromEnv('OTEL_EXPORTER_OTLP_METRICS_PROTOCOL') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_PROTOCOL') ?? + 'http/protobuf'; + const certificateFile = + getStringFromEnv('OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_CERTIFICATE'); + const clientKeyFile = + getStringFromEnv('OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_CLIENT_KEY'); + const clientCertificateFile = + getStringFromEnv('OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE'); + const compression = + getStringFromEnv('OTEL_EXPORTER_OTLP_METRICS_COMPRESSION') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_COMPRESSION'); + const timeoutExporter = + getNumberFromEnv('OTEL_EXPORTER_OTLP_METRICS_TIMEOUT') ?? + getNumberFromEnv('OTEL_EXPORTER_OTLP_TIMEOUT') ?? + 10000; + const headersList = + getStringFromEnv('OTEL_EXPORTER_OTLP_METRICS_HEADERS') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_HEADERS'); + const temporalityPreference = + getStringFromEnv('OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE') ?? + 'cumulative'; + const defaultHistogramAggregation = + getStringFromEnv( + 'OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION' + ) ?? 'explicit_bucket_histogram'; + + if (protocol === 'grpc') { + delete readerPeriodicInfo.exporter.otlp_http; + readerPeriodicInfo.exporter.otlp_grpc = {}; + const endpoint = + getStringFromEnv('OTEL_EXPORTER_OTLP_METRICS_ENDPOINT') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT') ?? + 'http://localhost:4317'; + if (endpoint) { + readerPeriodicInfo.exporter.otlp_grpc.endpoint = endpoint; + } + if (certificateFile) { + readerPeriodicInfo.exporter.otlp_grpc.certificate_file = + certificateFile; + } + if (clientKeyFile) { + readerPeriodicInfo.exporter.otlp_grpc.client_key_file = clientKeyFile; + } + if (clientCertificateFile) { + readerPeriodicInfo.exporter.otlp_grpc.client_certificate_file = + clientCertificateFile; + } + if (compression) { + readerPeriodicInfo.exporter.otlp_grpc.compression = compression; + } + if (timeoutExporter) { + readerPeriodicInfo.exporter.otlp_grpc.timeout = timeoutExporter; + } + if (headersList) { + readerPeriodicInfo.exporter.otlp_grpc.headers_list = headersList; + } + if (temporalityPreference) { + switch (temporalityPreference) { + case 'cumulative': + readerPeriodicInfo.exporter.otlp_grpc.temporality_preference = + ExporterTemporalityPreference.Cumulative; + break; + case 'delta': + readerPeriodicInfo.exporter.otlp_grpc.temporality_preference = + ExporterTemporalityPreference.Delta; + break; + case 'low_memory': + readerPeriodicInfo.exporter.otlp_grpc.temporality_preference = + ExporterTemporalityPreference.LowMemory; + break; + default: + readerPeriodicInfo.exporter.otlp_grpc.temporality_preference = + ExporterTemporalityPreference.Cumulative; + break; } - if (temporalityPreference) { - switch (temporalityPreference) { - case 'cumulative': - readerPeriodicInfo.exporter.otlp_http.temporality_preference = - ExporterTemporalityPreference.Cumulative; - break; - case 'delta': - readerPeriodicInfo.exporter.otlp_http.temporality_preference = - ExporterTemporalityPreference.Delta; - break; - case 'low_memory': - readerPeriodicInfo.exporter.otlp_http.temporality_preference = - ExporterTemporalityPreference.LowMemory; - break; - default: - readerPeriodicInfo.exporter.otlp_http.temporality_preference = - ExporterTemporalityPreference.Cumulative; - break; - } + } + if (defaultHistogramAggregation) { + switch (defaultHistogramAggregation) { + case 'explicit_bucket_histogram': + readerPeriodicInfo.exporter.otlp_grpc.default_histogram_aggregation = + ExporterDefaultHistogramAggregation.ExplicitBucketHistogram; + break; + case 'base2_exponential_bucket_histogram': + readerPeriodicInfo.exporter.otlp_grpc.default_histogram_aggregation = + ExporterDefaultHistogramAggregation.Base2ExponentialBucketHistogram; + break; + default: + readerPeriodicInfo.exporter.otlp_grpc.default_histogram_aggregation = + ExporterDefaultHistogramAggregation.ExplicitBucketHistogram; + break; } - if (defaultHistogramAggregation) { - switch (defaultHistogramAggregation) { - case 'explicit_bucket_histogram': - readerPeriodicInfo.exporter.otlp_http.default_histogram_aggregation = - ExporterDefaultHistogramAggregation.ExplicitBucketHistogram; - break; - case 'base2_exponential_bucket_histogram': - readerPeriodicInfo.exporter.otlp_http.default_histogram_aggregation = - ExporterDefaultHistogramAggregation.Base2ExponentialBucketHistogram; - break; - default: - readerPeriodicInfo.exporter.otlp_http.default_histogram_aggregation = - ExporterDefaultHistogramAggregation.ExplicitBucketHistogram; - break; - } + } + } else { + if (readerPeriodicInfo.exporter.otlp_http == null) { + readerPeriodicInfo.exporter.otlp_http = {}; + } + const endpoint = + getStringFromEnv('OTEL_EXPORTER_OTLP_METRICS_ENDPOINT') ?? + (getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT') + ? `${getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT')}/v1/metrics` + : 'http://localhost:4318/v1/metrics'); + if (endpoint) { + readerPeriodicInfo.exporter.otlp_http.endpoint = endpoint; + } + if (certificateFile) { + readerPeriodicInfo.exporter.otlp_http.certificate_file = + certificateFile; + } + if (clientKeyFile) { + readerPeriodicInfo.exporter.otlp_http.client_key_file = clientKeyFile; + } + if (clientCertificateFile) { + readerPeriodicInfo.exporter.otlp_http.client_certificate_file = + clientCertificateFile; + } + if (compression) { + readerPeriodicInfo.exporter.otlp_http.compression = compression; + } + if (timeoutExporter) { + readerPeriodicInfo.exporter.otlp_http.timeout = timeoutExporter; + } + if (headersList) { + readerPeriodicInfo.exporter.otlp_http.headers_list = headersList; + } + if (temporalityPreference) { + switch (temporalityPreference) { + case 'cumulative': + readerPeriodicInfo.exporter.otlp_http.temporality_preference = + ExporterTemporalityPreference.Cumulative; + break; + case 'delta': + readerPeriodicInfo.exporter.otlp_http.temporality_preference = + ExporterTemporalityPreference.Delta; + break; + case 'low_memory': + readerPeriodicInfo.exporter.otlp_http.temporality_preference = + ExporterTemporalityPreference.LowMemory; + break; + default: + readerPeriodicInfo.exporter.otlp_http.temporality_preference = + ExporterTemporalityPreference.Cumulative; + break; } - if (protocol === 'http/json') { - readerPeriodicInfo.exporter.otlp_http.encoding = - OtlpHttpEncoding.JSON; - } else if (protocol === 'http/protobuf') { - readerPeriodicInfo.exporter.otlp_http.encoding = - OtlpHttpEncoding.Protobuf; + } + if (defaultHistogramAggregation) { + switch (defaultHistogramAggregation) { + case 'explicit_bucket_histogram': + readerPeriodicInfo.exporter.otlp_http.default_histogram_aggregation = + ExporterDefaultHistogramAggregation.ExplicitBucketHistogram; + break; + case 'base2_exponential_bucket_histogram': + readerPeriodicInfo.exporter.otlp_http.default_histogram_aggregation = + ExporterDefaultHistogramAggregation.Base2ExponentialBucketHistogram; + break; + default: + readerPeriodicInfo.exporter.otlp_http.default_histogram_aggregation = + ExporterDefaultHistogramAggregation.ExplicitBucketHistogram; + break; } } + if (protocol === 'http/json') { + readerPeriodicInfo.exporter.otlp_http.encoding = + OtlpHttpEncoding.JSON; + } else if (protocol === 'http/protobuf') { + readerPeriodicInfo.exporter.otlp_http.encoding = + OtlpHttpEncoding.Protobuf; + } } - config.meter_provider.readers.push({ periodic: readerPeriodicInfo }); } + config.meter_provider.readers.push({ periodic: readerPeriodicInfo }); } - const exemplarFilter = getStringFromEnv('OTEL_METRICS_EXEMPLAR_FILTER'); + + const exemplarFilter = + getStringFromEnv('OTEL_METRICS_EXEMPLAR_FILTER') ?? 'trace_based'; if (exemplarFilter) { switch (exemplarFilter) { case 'trace_based': @@ -578,9 +577,20 @@ export function setMeterProvider(config: ConfigurationModel): void { } export function setLoggerProvider(config: ConfigurationModel): void { - if (config.logger_provider == null) { - config.logger_provider = { processors: [] }; + const exportersType = Array.from( + new Set(getStringListFromEnv('OTEL_LOGS_EXPORTER')) + ); + if (exportersType.length === 0) { + return; + } + if (exportersType.includes('none')) { + diag.info( + `OTEL_LOGS_EXPORTER contains "none". Logger provider will not be initialized.` + ); + return; } + config.logger_provider = initializeDefaultLoggerProviderConfiguration(); + const attributeValueLengthLimit = getNumberFromEnv( 'OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT' ); @@ -601,151 +611,129 @@ export function setLoggerProvider(config: ConfigurationModel): void { } } - const batch = - config.logger_provider?.processors && - config.logger_provider?.processors.length > 0 - ? config.logger_provider?.processors[0].batch - : undefined; - if (batch) { - const scheduleDelay = getNumberFromEnv('OTEL_BLRP_SCHEDULE_DELAY'); - if (scheduleDelay) { - batch.schedule_delay = scheduleDelay; - } - - const exportTimeout = getNumberFromEnv('OTEL_BLRP_EXPORT_TIMEOUT'); - if (exportTimeout) { - batch.export_timeout = exportTimeout; - } - - const maxQueueSize = getNumberFromEnv('OTEL_BLRP_MAX_QUEUE_SIZE'); - if (maxQueueSize) { - batch.max_queue_size = maxQueueSize; - } + const batch: BatchLogRecordProcessor = { exporter: {} }; + const scheduleDelay = getNumberFromEnv('OTEL_BLRP_SCHEDULE_DELAY') ?? 1000; + if (scheduleDelay) { + batch.schedule_delay = scheduleDelay; + } - const maxExportBatchSize = getNumberFromEnv( - 'OTEL_BLRP_MAX_EXPORT_BATCH_SIZE' - ); - if (maxExportBatchSize) { - batch.max_export_batch_size = maxExportBatchSize; - } + const exportTimeout = getNumberFromEnv('OTEL_BLRP_EXPORT_TIMEOUT') ?? 30000; + if (exportTimeout) { + batch.export_timeout = exportTimeout; + } - const exportersType = Array.from( - new Set(getStringListFromEnv('OTEL_LOGS_EXPORTER')) - ); - if (exportersType.length === 0) { - exportersType.push('otlp'); - } + const maxQueueSize = getNumberFromEnv('OTEL_BLRP_MAX_QUEUE_SIZE') ?? 2048; + if (maxQueueSize) { + batch.max_queue_size = maxQueueSize; + } - config.logger_provider.processors = []; - if (exportersType.includes('none')) { - diag.info( - `OTEL_LOGS_EXPORTER contains "none". Logger provider will not be initialized.` - ); - return; - } + const maxExportBatchSize = + getNumberFromEnv('OTEL_BLRP_MAX_EXPORT_BATCH_SIZE') ?? 512; + if (maxExportBatchSize) { + batch.max_export_batch_size = maxExportBatchSize; + } - for (let i = 0; i < exportersType.length; i++) { - const exporterType = exportersType[i]; - const batchInfo = { ...batch }; - if (exporterType === 'console') { - config.logger_provider.processors.push({ - simple: { exporter: { console: {} } }, - }); + for (let i = 0; i < exportersType.length; i++) { + const exporterType = exportersType[i]; + const batchInfo = { ...batch }; + if (exporterType === 'console') { + config.logger_provider.processors.push({ + simple: { exporter: { console: {} } }, + }); + } else { + // 'otlp' and default + const protocol = + getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_PROTOCOL') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_PROTOCOL') ?? + 'http/protobuf'; + const certificateFile = + getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_CERTIFICATE'); + const clientKeyFile = + getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_CLIENT_KEY'); + const clientCertificateFile = + getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE'); + const compression = + getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_COMPRESSION') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_COMPRESSION'); + const timeout = + getNumberFromEnv('OTEL_EXPORTER_OTLP_LOGS_TIMEOUT') ?? + getNumberFromEnv('OTEL_EXPORTER_OTLP_TIMEOUT') ?? + 10000; + const headersList = + getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_HEADERS') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_HEADERS'); + + if (protocol === 'grpc') { + delete batchInfo.exporter.otlp_http; + batchInfo.exporter.otlp_grpc = {}; + const endpoint = + getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_ENDPOINT') ?? + getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT') ?? + 'http://localhost:4317'; + if (endpoint) { + batchInfo.exporter.otlp_grpc.endpoint = endpoint; + } + if (certificateFile) { + batchInfo.exporter.otlp_grpc.certificate_file = certificateFile; + } + if (clientKeyFile) { + batchInfo.exporter.otlp_grpc.client_key_file = clientKeyFile; + } + if (clientCertificateFile) { + batchInfo.exporter.otlp_grpc.client_certificate_file = + clientCertificateFile; + } + if (compression) { + batchInfo.exporter.otlp_grpc.compression = compression; + } + if (timeout) { + batchInfo.exporter.otlp_grpc.timeout = timeout; + } + if (headersList) { + batchInfo.exporter.otlp_grpc.headers_list = headersList; + } } else { - // 'otlp' and default - const protocol = - getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_PROTOCOL') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_PROTOCOL') ?? - 'http/protobuf'; - const certificateFile = - getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_CERTIFICATE'); - const clientKeyFile = - getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_CLIENT_KEY'); - const clientCertificateFile = - getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE'); - const compression = - getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_COMPRESSION') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_COMPRESSION'); - const timeout = - getNumberFromEnv('OTEL_EXPORTER_OTLP_LOGS_TIMEOUT') ?? - getNumberFromEnv('OTEL_EXPORTER_OTLP_TIMEOUT') ?? - 10000; - const headersList = - getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_HEADERS') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_HEADERS'); - - if (protocol === 'grpc') { - delete batchInfo.exporter.otlp_http; - batchInfo.exporter.otlp_grpc = {}; - const endpoint = - getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_ENDPOINT') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT') ?? - 'http://localhost:4317'; - if (endpoint) { - batchInfo.exporter.otlp_grpc.endpoint = endpoint; - } - if (certificateFile) { - batchInfo.exporter.otlp_grpc.certificate_file = certificateFile; - } - if (clientKeyFile) { - batchInfo.exporter.otlp_grpc.client_key_file = clientKeyFile; - } - if (clientCertificateFile) { - batchInfo.exporter.otlp_grpc.client_certificate_file = - clientCertificateFile; - } - if (compression) { - batchInfo.exporter.otlp_grpc.compression = compression; - } - if (timeout) { - batchInfo.exporter.otlp_grpc.timeout = timeout; - } - if (headersList) { - batchInfo.exporter.otlp_grpc.headers_list = headersList; - } - } else { - if (batchInfo.exporter.otlp_http == null) { - batchInfo.exporter.otlp_http = {}; - } - const endpoint = - getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_ENDPOINT') ?? - (getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT') - ? `${getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT')}/v1/logs` - : null); - if (endpoint) { - batchInfo.exporter.otlp_http.endpoint = endpoint; - } - if (certificateFile) { - batchInfo.exporter.otlp_http.certificate_file = certificateFile; - } - if (clientKeyFile) { - batchInfo.exporter.otlp_http.client_key_file = clientKeyFile; - } - if (clientCertificateFile) { - batchInfo.exporter.otlp_http.client_certificate_file = - clientCertificateFile; - } - if (compression) { - batchInfo.exporter.otlp_http.compression = compression; - } - if (timeout) { - batchInfo.exporter.otlp_http.timeout = timeout; - } - if (headersList) { - batchInfo.exporter.otlp_http.headers_list = headersList; - } + if (batchInfo.exporter.otlp_http == null) { + batchInfo.exporter.otlp_http = {}; + } + const endpoint = + getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_ENDPOINT') ?? + (getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT') + ? `${getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT')}/v1/logs` + : 'http://localhost:4318/v1/logs'); + if (endpoint) { + batchInfo.exporter.otlp_http.endpoint = endpoint; + } + if (certificateFile) { + batchInfo.exporter.otlp_http.certificate_file = certificateFile; + } + if (clientKeyFile) { + batchInfo.exporter.otlp_http.client_key_file = clientKeyFile; + } + if (clientCertificateFile) { + batchInfo.exporter.otlp_http.client_certificate_file = + clientCertificateFile; + } + if (compression) { + batchInfo.exporter.otlp_http.compression = compression; + } + if (timeout) { + batchInfo.exporter.otlp_http.timeout = timeout; + } + if (headersList) { + batchInfo.exporter.otlp_http.headers_list = headersList; + } - if (protocol === 'http/json') { - batchInfo.exporter.otlp_http.encoding = OtlpHttpEncoding.JSON; - } else if (protocol === 'http/protobuf') { - batchInfo.exporter.otlp_http.encoding = OtlpHttpEncoding.Protobuf; - } + if (protocol === 'http/json') { + batchInfo.exporter.otlp_http.encoding = OtlpHttpEncoding.JSON; + } else if (protocol === 'http/protobuf') { + batchInfo.exporter.otlp_http.encoding = OtlpHttpEncoding.Protobuf; } - config.logger_provider.processors.push({ batch: batchInfo }); } + config.logger_provider.processors.push({ batch: batchInfo }); } } } diff --git a/experimental/packages/configuration/src/FileConfigFactory.ts b/experimental/packages/configuration/src/FileConfigFactory.ts index 9aa3fd1ae3a..5b3885a7987 100644 --- a/experimental/packages/configuration/src/FileConfigFactory.ts +++ b/experimental/packages/configuration/src/FileConfigFactory.ts @@ -34,11 +34,13 @@ import { } from './utils'; import { NameStringValuePair, OtlpHttpEncoding } from './models/commonModel'; import { + initializeDefaultTracerProviderConfiguration, SpanExporter, SpanProcessor, TracerProvider, } from './models/tracerProviderModel'; import { + initializeDefaultLoggerProviderConfiguration, LoggerProvider, LogRecordExporter, LogRecordProcessor, @@ -50,6 +52,7 @@ import { ExemplarFilter, ExporterDefaultHistogramAggregation, ExporterTemporalityPreference, + initializeDefaultMeterProviderConfiguration, InstrumentType, MeterProvider, MetricProducer, @@ -450,12 +453,8 @@ export function setTracerProvider( config: ConfigurationModel, tracerProvider: TracerProvider ): void { - if (tracerProvider) { - if (config.tracer_provider == null) { - config.tracer_provider = { - processors: [], - }; - } + if (tracerProvider && tracerProvider.processors?.length > 0) { + config.tracer_provider = initializeDefaultTracerProviderConfiguration(); // Limits if (tracerProvider['limits']) { if (config.tracer_provider.limits == null) { @@ -510,54 +509,55 @@ export function setTracerProvider( } // Processors - if (tracerProvider['processors']) { - if (tracerProvider['processors'].length > 0) { - config.tracer_provider.processors = []; - } - for (let i = 0; i < tracerProvider['processors'].length; i++) { - const processorType = Object.keys(tracerProvider['processors'][i])[0]; - if (processorType === 'batch') { - const element = tracerProvider['processors'][i]['batch']; - if (element) { - const parsedExporter = parseConfigSpanOrLogRecordExporter( - element['exporter'], - ProviderType.TRACER - ); - const batchConfig: SpanProcessor = { - batch: { - schedule_delay: - getNumberFromConfigFile(element['schedule_delay']) ?? 5000, - export_timeout: - getNumberFromConfigFile(element['export_timeout']) ?? 30000, - max_queue_size: - getNumberFromConfigFile(element['max_queue_size']) ?? 2048, - max_export_batch_size: - getNumberFromConfigFile(element['max_export_batch_size']) ?? - 512, - exporter: parsedExporter as SpanExporter, - }, - }; - - config.tracer_provider.processors.push(batchConfig); - } - } else if (processorType === 'simple') { - const element = tracerProvider['processors'][i]['simple']; - if (element) { - const parsedExporter = parseConfigSpanOrLogRecordExporter( - element['exporter'], - ProviderType.TRACER - ); - const simpleConfig: SpanProcessor = { - simple: { - exporter: parsedExporter as SpanExporter, - }, - }; + for (let i = 0; i < tracerProvider['processors'].length; i++) { + const processorType = Object.keys(tracerProvider['processors'][i])[0]; + if (processorType === 'batch') { + const element = tracerProvider['processors'][i]['batch']; + if (element) { + const parsedExporter = parseConfigSpanOrLogRecordExporter( + element['exporter'], + ProviderType.TRACER + ); + const batchConfig: SpanProcessor = { + batch: { + schedule_delay: + getNumberFromConfigFile(element['schedule_delay']) ?? 5000, + export_timeout: + getNumberFromConfigFile(element['export_timeout']) ?? 30000, + max_queue_size: + getNumberFromConfigFile(element['max_queue_size']) ?? 2048, + max_export_batch_size: + getNumberFromConfigFile(element['max_export_batch_size']) ?? + 512, + exporter: parsedExporter as SpanExporter, + }, + }; + + config.tracer_provider.processors.push(batchConfig); + } + } else if (processorType === 'simple') { + const element = tracerProvider['processors'][i]['simple']; + if (element) { + const parsedExporter = parseConfigSpanOrLogRecordExporter( + element['exporter'], + ProviderType.TRACER + ); + const simpleConfig: SpanProcessor = { + simple: { + exporter: parsedExporter as SpanExporter, + }, + }; - config.tracer_provider.processors.push(simpleConfig); - } + config.tracer_provider.processors.push(simpleConfig); } } } + } else if ( + tracerProvider && + (tracerProvider.processors == null || + tracerProvider.processors.length === 0) + ) { + diag.warn('TracerProvider must have at least one processor configured'); } } @@ -777,10 +777,8 @@ export function setMeterProvider( config: ConfigurationModel, meterProvider: MeterProvider ): void { - if (meterProvider) { - if (config.meter_provider == null) { - config.meter_provider = { readers: [] }; - } + if (meterProvider && meterProvider.readers?.length > 0) { + config.meter_provider = initializeDefaultMeterProviderConfiguration(); const exemplarFilter = getStringFromConfigFile( meterProvider['exemplar_filter'] ); @@ -801,82 +799,78 @@ export function setMeterProvider( } } - if (meterProvider['readers'] && meterProvider['readers'].length > 0) { - config.meter_provider.readers = []; - - for (let i = 0; i < meterProvider['readers'].length; i++) { - const readerType = Object.keys(meterProvider['readers'][i])[0]; - if (readerType === 'pull') { - const element = meterProvider['readers'][i]['pull']; - if (element) { - const exporter: PullMetricExporter = { - 'prometheus/development': { - host: - getStringFromConfigFile( - element['exporter']['prometheus/development']['host'] - ) ?? 'localhost', - port: - getNumberFromConfigFile( - element['exporter']['prometheus/development']['port'] - ) ?? 9464, - without_scope_info: - getBooleanFromConfigFile( + for (let i = 0; i < meterProvider.readers.length; i++) { + const readerType = Object.keys(meterProvider['readers'][i])[0]; + if (readerType === 'pull') { + const element = meterProvider['readers'][i]['pull']; + if (element) { + const exporter: PullMetricExporter = { + 'prometheus/development': { + host: + getStringFromConfigFile( + element['exporter']['prometheus/development']['host'] + ) ?? 'localhost', + port: + getNumberFromConfigFile( + element['exporter']['prometheus/development']['port'] + ) ?? 9464, + without_scope_info: + getBooleanFromConfigFile( + element['exporter']['prometheus/development'][ + 'without_scope_info' + ] + ) ?? false, + with_resource_constant_labels: { + included: + getStringListFromConfigFile( element['exporter']['prometheus/development'][ - 'without_scope_info' - ] - ) ?? false, - with_resource_constant_labels: { - included: - getStringListFromConfigFile( - element['exporter']['prometheus/development'][ - 'with_resource_constant_labels' - ]['included'] - ) ?? [], - excluded: - getStringListFromConfigFile( - element['exporter']['prometheus/development'][ - 'with_resource_constant_labels' - ]['excluded'] - ) ?? [], - }, - }, - }; - - const pullReader: MetricReader = { - pull: { - exporter: exporter, - cardinality_limits: getCardinalityLimits( - element['cardinality_limits'] - ), + 'with_resource_constant_labels' + ]['included'] + ) ?? [], + excluded: + getStringListFromConfigFile( + element['exporter']['prometheus/development'][ + 'with_resource_constant_labels' + ]['excluded'] + ) ?? [], }, - }; - const p = getProducers(element['producers']); - if (p.length > 0 && pullReader.pull) { - pullReader.pull.producers = p; - } - config.meter_provider.readers.push(pullReader); + }, + }; + + const pullReader: MetricReader = { + pull: { + exporter: exporter, + cardinality_limits: getCardinalityLimits( + element['cardinality_limits'] + ), + }, + }; + const p = getProducers(element['producers']); + if (p.length > 0 && pullReader.pull) { + pullReader.pull.producers = p; } - } else if (readerType === 'periodic') { - const element = meterProvider['readers'][i]['periodic']; - if (element) { - const parsedExporter = parseMetricExporter(element['exporter']); - - const periodicReader: MetricReader = { - periodic: { - exporter: parsedExporter, - cardinality_limits: getCardinalityLimits( - element['cardinality_limits'] - ), - interval: getNumberFromConfigFile(element['interval']) ?? 60000, - timeout: getNumberFromConfigFile(element['timeout']) ?? 30000, - }, - }; - const p = getProducers(element['producers']); - if (p.length > 0 && periodicReader.periodic) { - periodicReader.periodic.producers = p; - } - config.meter_provider.readers.push(periodicReader); + config.meter_provider.readers.push(pullReader); + } + } else if (readerType === 'periodic') { + const element = meterProvider['readers'][i]['periodic']; + if (element) { + const parsedExporter = parseMetricExporter(element['exporter']); + + const periodicReader: MetricReader = { + periodic: { + exporter: parsedExporter, + cardinality_limits: getCardinalityLimits( + element['cardinality_limits'] + ), + interval: getNumberFromConfigFile(element['interval']) ?? 60000, + timeout: getNumberFromConfigFile(element['timeout']) ?? 30000, + }, + }; + const p = getProducers(element['producers']); + if (p.length > 0 && periodicReader.periodic) { + periodicReader.periodic.producers = p; } + config.meter_provider.readers.push(periodicReader); } } } @@ -1055,6 +1049,11 @@ export function setMeterProvider( config.meter_provider.views.push(view); } } + } else if ( + meterProvider && + (meterProvider.readers == null || meterProvider.readers.length === 0) + ) { + diag.warn('MeterProvider must have at least one reader configured'); } } @@ -1062,10 +1061,8 @@ export function setLoggerProvider( config: ConfigurationModel, loggerProvider: LoggerProvider ): void { - if (loggerProvider) { - if (config.logger_provider == null) { - config.logger_provider = { processors: [] }; - } + if (loggerProvider && loggerProvider.processors?.length > 0) { + config.logger_provider = initializeDefaultLoggerProviderConfiguration(); // Limits if (loggerProvider['limits']) { const attributeValueLengthLimit = getNumberFromConfigFile( @@ -1090,54 +1087,46 @@ export function setLoggerProvider( } // Processors - if (loggerProvider['processors']) { - if (loggerProvider['processors'].length > 0) { - if (config.logger_provider == null) { - config.logger_provider = { processors: [] }; + for (let i = 0; i < loggerProvider['processors'].length; i++) { + const processorType = Object.keys(loggerProvider['processors'][i])[0]; + if (processorType === 'batch') { + const element = loggerProvider['processors'][i]['batch']; + if (element) { + const parsedExporter = parseConfigSpanOrLogRecordExporter( + element['exporter'], + ProviderType.LOGGER + ); + const batchConfig: LogRecordProcessor = { + batch: { + schedule_delay: + getNumberFromConfigFile(element['schedule_delay']) ?? 1000, + export_timeout: + getNumberFromConfigFile(element['export_timeout']) ?? 30000, + max_queue_size: + getNumberFromConfigFile(element['max_queue_size']) ?? 2048, + max_export_batch_size: + getNumberFromConfigFile(element['max_export_batch_size']) ?? + 512, + exporter: parsedExporter as LogRecordExporter, + }, + }; + + config.logger_provider.processors.push(batchConfig); } - config.logger_provider.processors = []; - for (let i = 0; i < loggerProvider['processors'].length; i++) { - const processorType = Object.keys(loggerProvider['processors'][i])[0]; - if (processorType === 'batch') { - const element = loggerProvider['processors'][i]['batch']; - if (element) { - const parsedExporter = parseConfigSpanOrLogRecordExporter( - element['exporter'], - ProviderType.LOGGER - ); - const batchConfig: LogRecordProcessor = { - batch: { - schedule_delay: - getNumberFromConfigFile(element['schedule_delay']) ?? 1000, - export_timeout: - getNumberFromConfigFile(element['export_timeout']) ?? 30000, - max_queue_size: - getNumberFromConfigFile(element['max_queue_size']) ?? 2048, - max_export_batch_size: - getNumberFromConfigFile(element['max_export_batch_size']) ?? - 512, - exporter: parsedExporter as LogRecordExporter, - }, - }; - - config.logger_provider.processors.push(batchConfig); - } - } else if (processorType === 'simple') { - const element = loggerProvider['processors'][i]['simple']; - if (element) { - const parsedExporter = parseConfigSpanOrLogRecordExporter( - element['exporter'], - ProviderType.LOGGER - ); - const simpleConfig: LogRecordProcessor = { - simple: { - exporter: parsedExporter, - }, - }; + } else if (processorType === 'simple') { + const element = loggerProvider['processors'][i]['simple']; + if (element) { + const parsedExporter = parseConfigSpanOrLogRecordExporter( + element['exporter'], + ProviderType.LOGGER + ); + const simpleConfig: LogRecordProcessor = { + simple: { + exporter: parsedExporter, + }, + }; - config.logger_provider.processors.push(simpleConfig); - } - } + config.logger_provider.processors.push(simpleConfig); } } } @@ -1150,9 +1139,6 @@ export function setLoggerProvider( ] ); if (defaultConfigDisabled || defaultConfigDisabled === false) { - if (config.logger_provider == null) { - config.logger_provider = { processors: [] }; - } config.logger_provider['logger_configurator/development'] = { default_config: { disabled: defaultConfigDisabled, @@ -1187,9 +1173,6 @@ export function setLoggerProvider( }); } } - if (config.logger_provider == null) { - config.logger_provider = { processors: [] }; - } if (config.logger_provider['logger_configurator/development'] == null) { config.logger_provider['logger_configurator/development'] = {}; } @@ -1197,5 +1180,11 @@ export function setLoggerProvider( loggers; } } + } else if ( + loggerProvider && + (loggerProvider.processors == null || + loggerProvider.processors.length === 0) + ) { + diag.warn('LoggerProvider must have at least one processor configured'); } } diff --git a/experimental/packages/configuration/src/models/configModel.ts b/experimental/packages/configuration/src/models/configModel.ts index dd323b9ba38..16ebd8ff451 100644 --- a/experimental/packages/configuration/src/models/configModel.ts +++ b/experimental/packages/configuration/src/models/configModel.ts @@ -16,19 +16,10 @@ 'use strict'; import { DiagLogLevel } from '@opentelemetry/api'; -import { - initializeDefaultTracerProviderConfiguration, - TracerProvider, -} from './tracerProviderModel'; -import { - initializeDefaultLoggerProviderConfiguration, - LoggerProvider, -} from './loggerProviderModel'; +import { TracerProvider } from './tracerProviderModel'; +import { LoggerProvider } from './loggerProviderModel'; import { Resource } from './resourceModel'; -import { - initializeDefaultMeterProviderConfiguration, - MeterProvider, -} from './meterProviderModel'; +import { MeterProvider } from './meterProviderModel'; export interface ConfigurationModel { /** @@ -94,9 +85,6 @@ export function initializeDefaultConfiguration(): ConfigurationModel { composite: [{ tracecontext: null }, { baggage: null }], composite_list: 'tracecontext,baggage', }, - tracer_provider: initializeDefaultTracerProviderConfiguration(), - meter_provider: initializeDefaultMeterProviderConfiguration(), - logger_provider: initializeDefaultLoggerProviderConfiguration(), }; return config; diff --git a/experimental/packages/configuration/src/models/loggerProviderModel.ts b/experimental/packages/configuration/src/models/loggerProviderModel.ts index 1816a28d993..607ccb43c1f 100644 --- a/experimental/packages/configuration/src/models/loggerProviderModel.ts +++ b/experimental/packages/configuration/src/models/loggerProviderModel.ts @@ -18,29 +18,12 @@ import { OtlpFileExporter, OtlpGrpcExporter, - OtlpHttpEncoding, OtlpHttpExporter, } from './commonModel'; export function initializeDefaultLoggerProviderConfiguration(): LoggerProvider { return { - processors: [ - { - batch: { - schedule_delay: 1000, - export_timeout: 30000, - max_queue_size: 2048, - max_export_batch_size: 512, - exporter: { - otlp_http: { - endpoint: 'http://localhost:4318/v1/logs', - timeout: 10000, - encoding: OtlpHttpEncoding.Protobuf, - }, - }, - }, - }, - ], + processors: [], limits: { attribute_count_limit: 128, }, diff --git a/experimental/packages/configuration/src/models/meterProviderModel.ts b/experimental/packages/configuration/src/models/meterProviderModel.ts index 4759530e2b3..df0654096bc 100644 --- a/experimental/packages/configuration/src/models/meterProviderModel.ts +++ b/experimental/packages/configuration/src/models/meterProviderModel.ts @@ -23,24 +23,7 @@ import { export function initializeDefaultMeterProviderConfiguration(): MeterProvider { return { - readers: [ - { - periodic: { - interval: 60000, - timeout: 30000, - exporter: { - otlp_http: { - endpoint: 'http://localhost:4318/v1/metrics', - timeout: 10000, - temporality_preference: ExporterTemporalityPreference.Cumulative, - default_histogram_aggregation: - ExporterDefaultHistogramAggregation.ExplicitBucketHistogram, - encoding: OtlpHttpEncoding.Protobuf, - }, - }, - }, - }, - ], + readers: [], exemplar_filter: ExemplarFilter.TraceBased, }; } diff --git a/experimental/packages/configuration/src/models/tracerProviderModel.ts b/experimental/packages/configuration/src/models/tracerProviderModel.ts index 5e337a66a1a..fae23d2e32e 100644 --- a/experimental/packages/configuration/src/models/tracerProviderModel.ts +++ b/experimental/packages/configuration/src/models/tracerProviderModel.ts @@ -18,29 +18,12 @@ import { OtlpFileExporter, OtlpGrpcExporter, - OtlpHttpEncoding, OtlpHttpExporter, } from './commonModel'; export function initializeDefaultTracerProviderConfiguration(): TracerProvider { return { - processors: [ - { - batch: { - schedule_delay: 5000, - export_timeout: 30000, - max_queue_size: 2048, - max_export_batch_size: 512, - exporter: { - otlp_http: { - endpoint: 'http://localhost:4318/v1/traces', - timeout: 10000, - encoding: OtlpHttpEncoding.Protobuf, - }, - }, - }, - }, - ], + processors: [], limits: { attribute_count_limit: 128, event_count_limit: 128, diff --git a/experimental/packages/configuration/test/ConfigFactory.test.ts b/experimental/packages/configuration/test/ConfigFactory.test.ts index dbd1e73fcea..8499ff4dbbf 100644 --- a/experimental/packages/configuration/test/ConfigFactory.test.ts +++ b/experimental/packages/configuration/test/ConfigFactory.test.ts @@ -25,25 +25,24 @@ import { ExporterDefaultHistogramAggregation, ExporterTemporalityPreference, InstrumentType, + MeterProvider, + MetricReader, } from '../src/models/meterProviderModel'; import { setAttributeLimits, - setLoggerProvider, setMeterProvider, setPropagators, setResources, - setTracerProvider, } from '../src/EnvironmentConfigFactory'; import { parseConfigFile, setResourceAttributes, setAttributeLimits as setFileAttributeLimits, setPropagator, - setTracerProvider as setFileTracerProvider, - setLoggerProvider as setFileLoggerProvider, setMeterProvider as setFileMeterProvider, getTemporalityPreference, } from '../src/FileConfigFactory'; +import { TracerProvider } from '../src/models/tracerProviderModel'; const defaultConfig: ConfigurationModel = { disabled: false, @@ -56,82 +55,24 @@ const defaultConfig: ConfigurationModel = { composite: [{ tracecontext: null }, { baggage: null }], composite_list: 'tracecontext,baggage', }, - tracer_provider: { - processors: [ - { - batch: { - schedule_delay: 5000, - export_timeout: 30000, - max_queue_size: 2048, - max_export_batch_size: 512, - exporter: { - otlp_http: { - endpoint: 'http://localhost:4318/v1/traces', - timeout: 10000, - encoding: OtlpHttpEncoding.Protobuf, - }, - }, - }, - }, - ], - limits: { - attribute_count_limit: 128, - event_count_limit: 128, - link_count_limit: 128, - event_attribute_count_limit: 128, - link_attribute_count_limit: 128, - }, - sampler: { - parent_based: { - root: { always_on: undefined }, - remote_parent_sampled: { always_on: undefined }, - remote_parent_not_sampled: { always_off: undefined }, - local_parent_sampled: { always_on: undefined }, - local_parent_not_sampled: { always_off: undefined }, - }, - }, - }, - meter_provider: { - readers: [ - { - periodic: { - interval: 60000, - timeout: 30000, - exporter: { - otlp_http: { - endpoint: 'http://localhost:4318/v1/metrics', - timeout: 10000, - temporality_preference: ExporterTemporalityPreference.Cumulative, - default_histogram_aggregation: - ExporterDefaultHistogramAggregation.ExplicitBucketHistogram, - encoding: OtlpHttpEncoding.Protobuf, - }, - }, - }, - }, - ], - exemplar_filter: ExemplarFilter.TraceBased, +}; + +const defaultTracerProvider: TracerProvider = { + processors: [], + limits: { + attribute_count_limit: 128, + event_count_limit: 128, + link_count_limit: 128, + event_attribute_count_limit: 128, + link_attribute_count_limit: 128, }, - logger_provider: { - processors: [ - { - batch: { - schedule_delay: 1000, - export_timeout: 30000, - max_queue_size: 2048, - max_export_batch_size: 512, - exporter: { - otlp_http: { - endpoint: 'http://localhost:4318/v1/logs', - timeout: 10000, - encoding: OtlpHttpEncoding.Protobuf, - }, - }, - }, - }, - ], - limits: { - attribute_count_limit: 128, + sampler: { + parent_based: { + root: { always_on: undefined }, + remote_parent_sampled: { always_on: undefined }, + remote_parent_not_sampled: { always_off: undefined }, + local_parent_sampled: { always_on: undefined }, + local_parent_not_sampled: { always_off: undefined }, }, }, }; @@ -298,7 +239,6 @@ const configFromFile: ConfigurationModel = { }, }, ], - limits: { attribute_count_limit: 128, attribute_value_length_limit: 4096, @@ -738,6 +678,49 @@ const defaultConfigFromFileWithEnvVariables: ConfigurationModel = { }, }; +const readerExample: MetricReader = { + periodic: { + interval: 60000, + timeout: 30000, + exporter: { + otlp_http: { + endpoint: 'http://localhost:4318/v1/metrics', + certificate_file: '/app/cert.pem', + client_key_file: '/app/cert.pem', + client_certificate_file: '/app/cert.pem', + headers: [ + { + name: 'api-key', + value: '1234', + }, + ], + headers_list: 'api-key=1234', + compression: 'gzip', + timeout: 10000, + encoding: OtlpHttpEncoding.Protobuf, + temporality_preference: ExporterTemporalityPreference.Delta, + default_histogram_aggregation: + ExporterDefaultHistogramAggregation.Base2ExponentialBucketHistogram, + }, + }, + producers: [ + { + prometheus: undefined, + }, + ], + cardinality_limits: { + default: 2000, + counter: 2000, + gauge: 2000, + histogram: 2000, + observable_counter: 2000, + observable_gauge: 2000, + observable_up_down_counter: 2000, + up_down_counter: 2000, + }, + }, +}; + describe('ConfigFactory', function () { const _origEnvVariables = { ...process.env }; @@ -860,6 +843,7 @@ describe('ConfigFactory', function () { }); it('should return config with custom tracer_provider', function () { + process.env.OTEL_TRACES_EXPORTER = 'otlp'; process.env.OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT = '100'; process.env.OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT = '200'; process.env.OTEL_SPAN_EVENT_COUNT_LIMIT = '300'; @@ -929,12 +913,43 @@ describe('ConfigFactory', function () { assert.deepStrictEqual(configFactory.getConfigModel(), expectedConfig); }); + it('should return config with tracer_provider otlp and json protocol', function () { + process.env.OTEL_TRACES_EXPORTER = 'otlp'; + process.env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL = 'http/json'; + + const expectedConfig: ConfigurationModel = { + ...defaultConfig, + tracer_provider: { + ...defaultTracerProvider, + processors: [ + { + batch: { + schedule_delay: 5000, + export_timeout: 30000, + max_queue_size: 2048, + max_export_batch_size: 512, + exporter: { + otlp_http: { + endpoint: 'http://localhost:4318/v1/traces', + timeout: 10000, + encoding: OtlpHttpEncoding.JSON, + }, + }, + }, + }, + ], + }, + }; + const configFactory = createConfigFactory(); + assert.deepStrictEqual(configFactory.getConfigModel(), expectedConfig); + }); + it('should return config with tracer_provider with console exporter', function () { process.env.OTEL_TRACES_EXPORTER = 'console'; const expectedConfig: ConfigurationModel = { ...defaultConfig, tracer_provider: { - ...defaultConfig.tracer_provider, + ...defaultTracerProvider, processors: [ { simple: { @@ -955,7 +970,7 @@ describe('ConfigFactory', function () { const expectedConfig: ConfigurationModel = { ...defaultConfig, tracer_provider: { - ...defaultConfig.tracer_provider, + ...defaultTracerProvider, processors: [ { batch: { @@ -978,7 +993,7 @@ describe('ConfigFactory', function () { assert.deepStrictEqual(configProvider.getConfigModel(), expectedConfig); }); - it('should return config with tracer_provider with default zipkin exporter', function () { + it('should return config with tracer_provider with custom zipkin exporter', function () { process.env.OTEL_TRACES_EXPORTER = 'zipkin'; process.env.OTEL_EXPORTER_ZIPKIN_ENDPOINT = 'http://custom:9411/api/v2/spans'; @@ -986,7 +1001,7 @@ describe('ConfigFactory', function () { const expectedConfig: ConfigurationModel = { ...defaultConfig, tracer_provider: { - ...defaultConfig.tracer_provider, + ...defaultTracerProvider, processors: [ { batch: { @@ -1017,7 +1032,7 @@ describe('ConfigFactory', function () { const expectedConfig: ConfigurationModel = { ...defaultConfig, tracer_provider: { - ...defaultConfig.tracer_provider, + ...defaultTracerProvider, processors: [ { batch: { @@ -1064,15 +1079,8 @@ describe('ConfigFactory', function () { it('should return config with tracer_provider with no exporter', function () { process.env.OTEL_TRACES_EXPORTER = 'none,console'; - const expectedConfig: ConfigurationModel = { - ...defaultConfig, - tracer_provider: { - ...defaultConfig.tracer_provider, - processors: [], - }, - }; const configProvider = createConfigFactory(); - assert.deepStrictEqual(configProvider.getConfigModel(), expectedConfig); + assert.deepStrictEqual(configProvider.getConfigModel(), defaultConfig); }); it('should return config with tracer_provider with otlp grpc exporter', function () { @@ -1087,7 +1095,7 @@ describe('ConfigFactory', function () { const expectedConfig: ConfigurationModel = { ...defaultConfig, tracer_provider: { - ...defaultConfig.tracer_provider, + ...defaultTracerProvider, processors: [ { batch: { @@ -1118,6 +1126,7 @@ describe('ConfigFactory', function () { it('should return config with custom meter_provider', function () { process.env.OTEL_METRIC_EXPORT_INTERVAL = '100'; process.env.OTEL_METRIC_EXPORT_TIMEOUT = '200'; + process.env.OTEL_METRICS_EXPORTER = 'otlp'; process.env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT = 'http://test.com:4318/v1/metrics'; process.env.OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE = @@ -1192,16 +1201,8 @@ describe('ConfigFactory', function () { it('should return config with meter_provider with no exporter', function () { process.env.OTEL_METRICS_EXPORTER = 'none,console'; - - const expectedConfig: ConfigurationModel = { - ...defaultConfig, - meter_provider: { - readers: [], - exemplar_filter: ExemplarFilter.TraceBased, - }, - }; const configFactory = createConfigFactory(); - assert.deepStrictEqual(configFactory.getConfigModel(), expectedConfig); + assert.deepStrictEqual(configFactory.getConfigModel(), defaultConfig); }); it('should return config with meter_provider with list of exporters', function () { @@ -1425,6 +1426,7 @@ describe('ConfigFactory', function () { process.env.OTEL_BLRP_EXPORT_TIMEOUT = '400'; process.env.OTEL_BLRP_MAX_QUEUE_SIZE = '500'; process.env.OTEL_BLRP_MAX_EXPORT_BATCH_SIZE = '600'; + process.env.OTEL_LOGS_EXPORTER = 'otlp'; process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = 'http://test.com:4318/v1/logs'; process.env.OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE = 'certificate_file.txt'; @@ -1494,17 +1496,8 @@ describe('ConfigFactory', function () { it('should return config with logger_provider with no exporter', function () { process.env.OTEL_LOGS_EXPORTER = 'none,console'; - const expectedConfig: ConfigurationModel = { - ...defaultConfig, - logger_provider: { - limits: { - attribute_count_limit: 128, - }, - processors: [], - }, - }; const configFactory = createConfigFactory(); - assert.deepStrictEqual(configFactory.getConfigModel(), expectedConfig); + assert.deepStrictEqual(configFactory.getConfigModel(), defaultConfig); }); it('should return config with logger_provider with exporter list', function () { @@ -1631,13 +1624,20 @@ describe('ConfigFactory', function () { process.env.OTEL_EXPORTER_OTLP_COMPRESSION = 'backup_compression'; process.env.OTEL_EXPORTER_OTLP_TIMEOUT = '12000'; process.env.OTEL_EXPORTER_OTLP_HEADERS = 'backup_headers=123'; + process.env.OTEL_TRACES_EXPORTER = 'otlp'; + process.env.OTEL_METRICS_EXPORTER = 'otlp'; + process.env.OTEL_LOGS_EXPORTER = 'otlp'; const expectedConfig: ConfigurationModel = { ...defaultConfig, tracer_provider: { + ...defaultTracerProvider, processors: [ { batch: { - ...defaultConfig.tracer_provider?.processors[0].batch, + export_timeout: 30000, + max_export_batch_size: 512, + max_queue_size: 2048, + schedule_delay: 5000, exporter: { otlp_http: { endpoint: 'http://backup.com:4318/v1/traces', @@ -1653,11 +1653,9 @@ describe('ConfigFactory', function () { }, }, ], - limits: defaultConfig.tracer_provider?.limits, - sampler: defaultConfig.tracer_provider?.sampler, }, meter_provider: { - ...defaultConfig.meter_provider, + exemplar_filter: ExemplarFilter.TraceBased, readers: [ { periodic: { @@ -1684,7 +1682,9 @@ describe('ConfigFactory', function () { ], }, logger_provider: { - ...defaultConfig.logger_provider, + limits: { + attribute_count_limit: 128, + }, processors: [ { batch: { @@ -1743,185 +1743,65 @@ describe('ConfigFactory', function () { assert.deepStrictEqual(config, { propagator: {} }); config = {}; - setTracerProvider(config); - assert.deepStrictEqual(config, { - tracer_provider: { limits: {}, processors: [] }, - }); - - config = {}; - process.env.OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT = '3'; - setLoggerProvider(config); - assert.deepStrictEqual(config, { - logger_provider: { - limits: { - attribute_count_limit: 128, - attribute_value_length_limit: 3, - }, - processors: [], - }, - }); - - config = { - meter_provider: { - readers: [{ periodic: { exporter: { otlp_http: undefined } } }], - }, - }; - process.env.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE = - 'cumulative'; - setMeterProvider(config); - assert.deepStrictEqual(config, { - meter_provider: { - readers: [ - { - periodic: { - exporter: { - otlp_http: { - default_histogram_aggregation: 'explicit_bucket_histogram', - encoding: 'protobuf', - temporality_preference: 'cumulative', - timeout: 10000, - }, - }, - timeout: 30000, - }, - }, - ], - }, - }); - process.env.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE = 'low_memory'; + process.env.OTEL_METRICS_EXEMPLAR_FILTER = 'always_off'; + process.env.OTEL_METRICS_EXPORTER = 'otlp'; setMeterProvider(config); - assert.deepStrictEqual(config, { - meter_provider: { - readers: [ - { - periodic: { - exporter: { - otlp_http: { - default_histogram_aggregation: 'explicit_bucket_histogram', - encoding: 'protobuf', - temporality_preference: 'low_memory', - timeout: 10000, - }, - }, - timeout: 30000, - }, - }, - ], - }, - }); - process.env.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE = 'default'; - setMeterProvider(config); - assert.deepStrictEqual(config, { - meter_provider: { - readers: [ - { - periodic: { - exporter: { - otlp_http: { - default_histogram_aggregation: 'explicit_bucket_histogram', - encoding: 'protobuf', - temporality_preference: 'cumulative', - timeout: 10000, - }, + let expectedMeterProvider: MeterProvider = { + exemplar_filter: ExemplarFilter.AlwaysOff, + readers: [ + { + periodic: { + exporter: { + otlp_http: { + default_histogram_aggregation: + ExporterDefaultHistogramAggregation.ExplicitBucketHistogram, + encoding: OtlpHttpEncoding.Protobuf, + endpoint: 'http://localhost:4318/v1/metrics', + temporality_preference: + ExporterTemporalityPreference.LowMemory, + timeout: 10000, }, - timeout: 30000, }, + interval: 60000, + timeout: 30000, }, - ], - }, - }); - delete process.env.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE; - - config = { - meter_provider: { - readers: [{ periodic: { exporter: { otlp_http: undefined } } }], - }, + }, + ], }; - process.env.OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION = - 'explicit_bucket_histogram'; - setMeterProvider(config); - assert.deepStrictEqual(config, { - meter_provider: { - readers: [ - { - periodic: { - exporter: { - otlp_http: { - default_histogram_aggregation: 'explicit_bucket_histogram', - encoding: 'protobuf', - temporality_preference: 'cumulative', - timeout: 10000, - }, - }, - timeout: 30000, - }, - }, - ], - }, - }); + assert.deepStrictEqual(config.meter_provider, expectedMeterProvider); + config = {}; + process.env.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE = 'default'; process.env.OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION = 'default'; + process.env.OTEL_METRICS_EXEMPLAR_FILTER = 'default'; setMeterProvider(config); - assert.deepStrictEqual(config, { - meter_provider: { - readers: [ - { - periodic: { - exporter: { - otlp_http: { - default_histogram_aggregation: 'explicit_bucket_histogram', - encoding: 'protobuf', - temporality_preference: 'cumulative', - timeout: 10000, - }, + expectedMeterProvider = { + exemplar_filter: ExemplarFilter.TraceBased, + readers: [ + { + periodic: { + exporter: { + otlp_http: { + default_histogram_aggregation: + ExporterDefaultHistogramAggregation.ExplicitBucketHistogram, + encoding: OtlpHttpEncoding.Protobuf, + endpoint: 'http://localhost:4318/v1/metrics', + temporality_preference: + ExporterTemporalityPreference.Cumulative, + timeout: 10000, }, - timeout: 30000, }, + interval: 60000, + timeout: 30000, }, - ], - }, - }); - - config = {}; - setMeterProvider(config); - assert.deepStrictEqual(config, { - meter_provider: { - readers: [{}], - }, - }); - - process.env.OTEL_METRICS_EXEMPLAR_FILTER = 'trace_based'; - setMeterProvider(config); - assert.deepStrictEqual(config, { - meter_provider: { - readers: [{}], - exemplar_filter: 'trace_based', - }, - }); - - config = {}; - process.env.OTEL_METRICS_EXEMPLAR_FILTER = 'always_off'; - setMeterProvider(config); - assert.deepStrictEqual(config, { - meter_provider: { - readers: [{}], - exemplar_filter: 'always_off', - }, - }); - - config = {}; - process.env.OTEL_METRICS_EXEMPLAR_FILTER = 'default'; - setMeterProvider(config); - assert.deepStrictEqual(config, { - meter_provider: { - readers: [{}], - exemplar_filter: 'trace_based', - }, - }); + }, + ], + }; + assert.deepStrictEqual(config.meter_provider, expectedMeterProvider); }); }); @@ -2181,6 +2061,25 @@ describe('ConfigFactory', function () { ); }); + it('checks for incomplete providers', function () { + const warnSpy = Sinon.spy(diag, 'warn'); + process.env.OTEL_EXPERIMENTAL_CONFIG_FILE = + 'test/fixtures/invalid-providers.yaml'; + createConfigFactory(); + Sinon.assert.calledWith( + warnSpy.firstCall, + 'TracerProvider must have at least one processor configured' + ); + Sinon.assert.calledWith( + warnSpy.secondCall, + 'MeterProvider must have at least one reader configured' + ); + Sinon.assert.calledWith( + warnSpy.thirdCall, + 'LoggerProvider must have at least one processor configured' + ); + }); + it('checks to keep good code coverage', function () { process.env.OTEL_EXPERIMENTAL_CONFIG_FILE = 'test/fixtures/test-for-coverage.yaml'; @@ -2205,93 +2104,71 @@ describe('ConfigFactory', function () { propagator: { composite: [{ tracecontext: null }] }, }); - config = {}; - setFileTracerProvider(config, { processors: [] }); - assert.deepStrictEqual(config, { - tracer_provider: { processors: [] }, - }); - - config = {}; - setFileLoggerProvider(config, { processors: [] }); - assert.deepStrictEqual(config, { - logger_provider: { processors: [] }, - }); - const res = getTemporalityPreference( ExporterTemporalityPreference.LowMemory ); assert.deepStrictEqual(res, 'low_memory'); - config = {}; - setFileMeterProvider(config, { readers: [] }); - assert.deepStrictEqual(config, { - meter_provider: { readers: [] }, - }); - config = {}; setFileMeterProvider(config, { - readers: [], + readers: [readerExample], exemplar_filter: ExemplarFilter.AlwaysOn, - }); - assert.deepStrictEqual(config, { - meter_provider: { readers: [], exemplar_filter: 'always_on' }, - }); - - config = {}; - setFileMeterProvider(config, { - readers: [], views: [{ selector: { instrument_type: InstrumentType.Counter } }], }); assert.deepStrictEqual(config, { meter_provider: { - readers: [], + exemplar_filter: 'always_on', + readers: [readerExample], views: [{ selector: { instrument_type: 'counter' } }], }, }); config = {}; setFileMeterProvider(config, { - readers: [], + readers: [readerExample], views: [{ selector: { instrument_type: InstrumentType.Gauge } }], }); assert.deepStrictEqual(config, { meter_provider: { - readers: [], + exemplar_filter: 'trace_based', + readers: [readerExample], views: [{ selector: { instrument_type: 'gauge' } }], }, }); config = {}; setFileMeterProvider(config, { - readers: [], + readers: [readerExample], views: [ { selector: { instrument_type: InstrumentType.ObservableCounter } }, ], }); assert.deepStrictEqual(config, { meter_provider: { - readers: [], + exemplar_filter: 'trace_based', + readers: [readerExample], views: [{ selector: { instrument_type: 'observable_counter' } }], }, }); config = {}; setFileMeterProvider(config, { - readers: [], + readers: [readerExample], views: [ { selector: { instrument_type: InstrumentType.ObservableGauge } }, ], }); assert.deepStrictEqual(config, { meter_provider: { - readers: [], + exemplar_filter: 'trace_based', + readers: [readerExample], views: [{ selector: { instrument_type: 'observable_gauge' } }], }, }); config = {}; setFileMeterProvider(config, { - readers: [], + readers: [readerExample], views: [ { selector: { @@ -2302,7 +2179,8 @@ describe('ConfigFactory', function () { }); assert.deepStrictEqual(config, { meter_provider: { - readers: [], + exemplar_filter: 'trace_based', + readers: [readerExample], views: [ { selector: { instrument_type: 'observable_up_down_counter' } }, ], @@ -2311,17 +2189,140 @@ describe('ConfigFactory', function () { config = {}; setFileMeterProvider(config, { - readers: [], + readers: [readerExample], views: [ { selector: { instrument_type: InstrumentType.UpDownCounter } }, ], + exemplar_filter: 'default' as ExemplarFilter, }); assert.deepStrictEqual(config, { meter_provider: { - readers: [], + exemplar_filter: 'trace_based', + readers: [readerExample], views: [{ selector: { instrument_type: 'up_down_counter' } }], }, }); + + config = {}; + setFileMeterProvider(config, { + views: [{ stream: { aggregation: { default: {} } } }], + readers: [readerExample], + }); + assert.deepStrictEqual(config, { + meter_provider: { + exemplar_filter: 'trace_based', + readers: [readerExample], + views: [ + { + stream: { + aggregation: { + default: {}, + }, + }, + }, + ], + }, + }); + + config = {}; + setFileMeterProvider(config, { + views: [{ stream: { aggregation: { drop: {} } } }], + readers: [readerExample], + }); + assert.deepStrictEqual(config, { + meter_provider: { + exemplar_filter: 'trace_based', + readers: [readerExample], + views: [ + { + stream: { + aggregation: { + drop: {}, + }, + }, + }, + ], + }, + }); + + config = {}; + setFileMeterProvider(config, { + views: [{ stream: { aggregation: { last_value: {} } } }], + readers: [readerExample], + }); + assert.deepStrictEqual(config, { + meter_provider: { + exemplar_filter: 'trace_based', + readers: [readerExample], + views: [ + { + stream: { + aggregation: { + last_value: {}, + }, + }, + }, + ], + }, + }); + + config = {}; + setFileMeterProvider(config, { + views: [{ stream: { aggregation: { sum: {} } } }], + readers: [readerExample], + }); + assert.deepStrictEqual(config, { + meter_provider: { + exemplar_filter: 'trace_based', + readers: [readerExample], + views: [ + { + stream: { + aggregation: { + sum: {}, + }, + }, + }, + ], + }, + }); + + config = {}; + setFileMeterProvider(config, { + views: [ + { + stream: { + aggregation: { + base2_exponential_bucket_histogram: { + record_min_max: false, + max_scale: 20, + max_size: 160, + }, + }, + }, + }, + ], + readers: [readerExample], + }); + assert.deepStrictEqual(config, { + meter_provider: { + exemplar_filter: 'trace_based', + readers: [readerExample], + views: [ + { + stream: { + aggregation: { + base2_exponential_bucket_histogram: { + record_min_max: false, + max_scale: 20, + max_size: 160, + }, + }, + }, + }, + ], + }, + }); }); }); }); diff --git a/experimental/packages/configuration/test/fixtures/invalid-providers.yaml b/experimental/packages/configuration/test/fixtures/invalid-providers.yaml new file mode 100644 index 00000000000..cbd48b27ac7 --- /dev/null +++ b/experimental/packages/configuration/test/fixtures/invalid-providers.yaml @@ -0,0 +1,7 @@ +file_format: "1.0-rc.1" +tracer_provider: + processors: [] +meter_provider: + readers: +logger_provider: + processors: \ No newline at end of file