diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index d5fdf287625..554f147afdb 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -15,8 +15,11 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2 * feat(configuration): set logger provider exporter type from env variable [#6104](https://github.com/open-telemetry/opentelemetry-js/pull/6104) @maryliag * feat(configuration): set meter provider exporter type from env variable [#6105](https://github.com/open-telemetry/opentelemetry-js/pull/6105) @maryliag * 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 +* feat(opentelemetry-sdk-node): use declarative config for resource attributes [#6044](https://github.com/open-telemetry/opentelemetry-js/pull/6044) @maryliag +* feat(opentelemetry-sdk-node): use declarative config for logger provider [#6111](https://github.com/open-telemetry/opentelemetry-js/pull/6111) @maryliag +* feat(configuration): doesnt set meter,tracer,logger provider by default [#6130](https://github.com/open-telemetry/opentelemetry-js/pull/6130) @maryliag +* refactor(configuration): dont have a default value for node resource detectors [#x](https://github.com/open-telemetry/opentelemetry-js/pull/x) @maryliag ### :bug: Bug Fixes diff --git a/experimental/packages/configuration/package.json b/experimental/packages/configuration/package.json index 73ad90b24c3..5a4f10c0a44 100644 --- a/experimental/packages/configuration/package.json +++ b/experimental/packages/configuration/package.json @@ -1,6 +1,5 @@ { "name": "@opentelemetry/configuration", - "private": true, "version": "0.208.0", "description": "OpenTelemetry Configuration", "main": "build/src/index.js", 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..a5fb47e5616 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?.processors?.length > 0) { + config.tracer_provider = initializeDefaultTracerProviderConfiguration(); // Limits if (tracerProvider['limits']) { if (config.tracer_provider.limits == null) { @@ -778,9 +777,7 @@ export function setMeterProvider( meterProvider: MeterProvider ): void { if (meterProvider) { - if (config.meter_provider == null) { - config.meter_provider = { readers: [] }; - } + config.meter_provider = initializeDefaultMeterProviderConfiguration(); const exemplarFilter = getStringFromConfigFile( meterProvider['exemplar_filter'] ); @@ -1063,9 +1060,7 @@ export function setLoggerProvider( loggerProvider: LoggerProvider ): void { if (loggerProvider) { - if (config.logger_provider == null) { - config.logger_provider = { processors: [] }; - } + config.logger_provider = initializeDefaultLoggerProviderConfiguration(); // Limits if (loggerProvider['limits']) { const attributeValueLengthLimit = getNumberFromConfigFile( @@ -1092,9 +1087,6 @@ export function setLoggerProvider( // Processors if (loggerProvider['processors']) { if (loggerProvider['processors'].length > 0) { - if (config.logger_provider == null) { - config.logger_provider = { processors: [] }; - } config.logger_provider.processors = []; for (let i = 0; i < loggerProvider['processors'].length; i++) { const processorType = Object.keys(loggerProvider['processors'][i])[0]; @@ -1150,9 +1142,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 +1176,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'] = {}; } diff --git a/experimental/packages/configuration/src/models/configModel.ts b/experimental/packages/configuration/src/models/configModel.ts index 63450cf8d1b..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 { /** @@ -86,7 +77,6 @@ export function initializeDefaultConfiguration(): ConfigurationModel { const config: ConfigurationModel = { disabled: false, log_level: DiagLogLevel.INFO, - node_resource_detectors: ['all'], resource: {}, attribute_limits: { attribute_count_limit: 128, @@ -95,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 1ddba57affc..bc8c431cc25 100644 --- a/experimental/packages/configuration/test/ConfigFactory.test.ts +++ b/experimental/packages/configuration/test/ConfigFactory.test.ts @@ -25,30 +25,27 @@ import { ExporterDefaultHistogramAggregation, ExporterTemporalityPreference, InstrumentType, + MeterProvider, } 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, log_level: DiagLogLevel.INFO, - node_resource_detectors: ['all'], resource: {}, attribute_limits: { attribute_count_limit: 128, @@ -57,82 +54,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 }, }, }, }; @@ -140,7 +79,6 @@ const defaultConfig: ConfigurationModel = { const configFromFile: ConfigurationModel = { disabled: false, log_level: DiagLogLevel.INFO, - node_resource_detectors: ['all'], resource: { schema_url: 'https://opentelemetry.io/schemas/1.16.0', attributes_list: 'service.namespace=my-namespace,service.version=1.0.0', @@ -300,7 +238,6 @@ const configFromFile: ConfigurationModel = { }, }, ], - limits: { attribute_count_limit: 128, attribute_value_length_limit: 4096, @@ -631,7 +568,6 @@ const configFromFile: ConfigurationModel = { const defaultConfigFromFileWithEnvVariables: ConfigurationModel = { disabled: false, log_level: DiagLogLevel.INFO, - node_resource_detectors: ['all'], resource: { attributes: [ { @@ -863,6 +799,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'; @@ -932,12 +869,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: { @@ -958,7 +926,7 @@ describe('ConfigFactory', function () { const expectedConfig: ConfigurationModel = { ...defaultConfig, tracer_provider: { - ...defaultConfig.tracer_provider, + ...defaultTracerProvider, processors: [ { batch: { @@ -981,7 +949,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'; @@ -989,7 +957,7 @@ describe('ConfigFactory', function () { const expectedConfig: ConfigurationModel = { ...defaultConfig, tracer_provider: { - ...defaultConfig.tracer_provider, + ...defaultTracerProvider, processors: [ { batch: { @@ -1020,7 +988,7 @@ describe('ConfigFactory', function () { const expectedConfig: ConfigurationModel = { ...defaultConfig, tracer_provider: { - ...defaultConfig.tracer_provider, + ...defaultTracerProvider, processors: [ { batch: { @@ -1067,15 +1035,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 () { @@ -1090,7 +1051,7 @@ describe('ConfigFactory', function () { const expectedConfig: ConfigurationModel = { ...defaultConfig, tracer_provider: { - ...defaultConfig.tracer_provider, + ...defaultTracerProvider, processors: [ { batch: { @@ -1121,6 +1082,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 = @@ -1195,16 +1157,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 () { @@ -1428,6 +1382,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'; @@ -1497,17 +1452,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 () { @@ -1634,13 +1580,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', @@ -1656,11 +1609,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: { @@ -1687,7 +1638,9 @@ describe('ConfigFactory', function () { ], }, logger_provider: { - ...defaultConfig.logger_provider, + limits: { + attribute_count_limit: 128, + }, processors: [ { batch: { @@ -1746,185 +1699,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); }); }); @@ -2208,45 +2041,20 @@ 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: [], 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: { + exemplar_filter: 'always_on', readers: [], views: [{ selector: { instrument_type: 'counter' } }], }, @@ -2259,6 +2067,7 @@ describe('ConfigFactory', function () { }); assert.deepStrictEqual(config, { meter_provider: { + exemplar_filter: 'trace_based', readers: [], views: [{ selector: { instrument_type: 'gauge' } }], }, @@ -2273,6 +2082,7 @@ describe('ConfigFactory', function () { }); assert.deepStrictEqual(config, { meter_provider: { + exemplar_filter: 'trace_based', readers: [], views: [{ selector: { instrument_type: 'observable_counter' } }], }, @@ -2287,6 +2097,7 @@ describe('ConfigFactory', function () { }); assert.deepStrictEqual(config, { meter_provider: { + exemplar_filter: 'trace_based', readers: [], views: [{ selector: { instrument_type: 'observable_gauge' } }], }, @@ -2305,6 +2116,7 @@ describe('ConfigFactory', function () { }); assert.deepStrictEqual(config, { meter_provider: { + exemplar_filter: 'trace_based', readers: [], views: [ { selector: { instrument_type: 'observable_up_down_counter' } }, @@ -2318,13 +2130,136 @@ describe('ConfigFactory', function () { views: [ { selector: { instrument_type: InstrumentType.UpDownCounter } }, ], + exemplar_filter: 'default' as ExemplarFilter, }); assert.deepStrictEqual(config, { meter_provider: { + exemplar_filter: 'trace_based', readers: [], views: [{ selector: { instrument_type: 'up_down_counter' } }], }, }); + + config = {}; + setFileMeterProvider(config, { + views: [{ stream: { aggregation: { default: {} } } }], + readers: [], + }); + assert.deepStrictEqual(config, { + meter_provider: { + exemplar_filter: 'trace_based', + readers: [], + views: [ + { + stream: { + aggregation: { + default: {}, + }, + }, + }, + ], + }, + }); + + config = {}; + setFileMeterProvider(config, { + views: [{ stream: { aggregation: { drop: {} } } }], + readers: [], + }); + assert.deepStrictEqual(config, { + meter_provider: { + exemplar_filter: 'trace_based', + readers: [], + views: [ + { + stream: { + aggregation: { + drop: {}, + }, + }, + }, + ], + }, + }); + + config = {}; + setFileMeterProvider(config, { + views: [{ stream: { aggregation: { last_value: {} } } }], + readers: [], + }); + assert.deepStrictEqual(config, { + meter_provider: { + exemplar_filter: 'trace_based', + readers: [], + views: [ + { + stream: { + aggregation: { + last_value: {}, + }, + }, + }, + ], + }, + }); + + config = {}; + setFileMeterProvider(config, { + views: [{ stream: { aggregation: { sum: {} } } }], + readers: [], + }); + assert.deepStrictEqual(config, { + meter_provider: { + exemplar_filter: 'trace_based', + readers: [], + 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: [], + }); + assert.deepStrictEqual(config, { + meter_provider: { + exemplar_filter: 'trace_based', + readers: [], + views: [ + { + stream: { + aggregation: { + base2_exponential_bucket_histogram: { + record_min_max: false, + max_scale: 20, + max_size: 160, + }, + }, + }, + }, + ], + }, + }); }); }); }); diff --git a/experimental/packages/opentelemetry-sdk-node/README.md b/experimental/packages/opentelemetry-sdk-node/README.md index c9b97b33274..873f7f3bdee 100644 --- a/experimental/packages/opentelemetry-sdk-node/README.md +++ b/experimental/packages/opentelemetry-sdk-node/README.md @@ -79,6 +79,79 @@ process.on("SIGTERM", () => { }); ``` +## Configuration file + +The SDK configuration can be done through a configuration yaml file. + +To setup create the file and set the environment variable `OTEL_EXPERIMENTAL_CONFIG_FILE` to its path e.g. `test/fixtures/kitchen-sink.yaml`. + +If the environment variable is set, the configuration will only be used from the file and the correspondent environment +variables will not be used, unless they're in the config file itself (e.g. `disabled: ${OTEL_SDK_DISABLED:-false}`) + +Example of all available configurations: + +```yml +# The file format version. +# The yaml format is documented at +# https://github.com/open-telemetry/opentelemetry-configuration/tree/main/schema +file_format: "1.0-rc.2" +# Configure if the SDK is disabled or not. +disabled: false +# Configure the log level of the internal logger used by the SDK. +# If omitted, info is used. +log_level: info +# Configure logger provider. +# If omitted, a noop logger provider is used. +logger_provider: + # Configure log record processors. + processors: + - # Configure a batch log record processor. + batch: + # Configure delay interval (in milliseconds) between two consecutive exports. + # Value must be non-negative. + # If omitted or null, 1000 is used. + schedule_delay: 5000 + # Configure maximum allowed time (in milliseconds) to export data. + # Value must be non-negative. A value of 0 indicates no limit (infinity). + # If omitted or null, 30000 is used. + export_timeout: 30000 + # Configure maximum queue size. Value must be positive. + # If omitted or null, 2048 is used. + max_queue_size: 2048 + # Configure maximum batch size. Value must be positive. + # If omitted or null, 512 is used. + max_export_batch_size: 512 + # Configure exporter. + exporter: + # Configure exporter to be OTLP with HTTP transport. + otlp_http: + # Configure compression. + # Values include: gzip, none. Implementations may support other compression algorithms. + # If omitted or null, none is used. + compression: gzip + # Configure the encoding used for messages. + # Values include: protobuf, json. Implementations may not support json. + # If omitted or null, protobuf is used. + encoding: protobuf + - # Configure a batch log record processor. + batch: + # Configure exporter. + exporter: + # Configure exporter to be OTLP with gRPC transport. + otlp_grpc: + # Configure compression. + # Values include: gzip, none. Implementations may support other compression algorithms. + # If omitted or null, none is used. + compression: gzip + - # Configure a simple log record processor. + simple: + # Configure exporter. + exporter: + # Configure exporter to be console. + console: + +``` + ## Configuration Below is a full list of configuration options which may be passed into the `NodeSDK` constructor; diff --git a/experimental/packages/opentelemetry-sdk-node/package.json b/experimental/packages/opentelemetry-sdk-node/package.json index 7f1e3c21044..f1097791e52 100644 --- a/experimental/packages/opentelemetry-sdk-node/package.json +++ b/experimental/packages/opentelemetry-sdk-node/package.json @@ -44,6 +44,7 @@ }, "dependencies": { "@opentelemetry/api-logs": "0.208.0", + "@opentelemetry/configuration": "0.208.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/exporter-logs-otlp-grpc": "0.208.0", "@opentelemetry/exporter-logs-otlp-http": "0.208.0", diff --git a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts index 527b1cdedba..e87006f3f84 100644 --- a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts +++ b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts @@ -63,12 +63,7 @@ import { } from '@opentelemetry/sdk-trace-node'; import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions'; import { NodeSDKConfiguration } from './types'; -import { - getBooleanFromEnv, - getStringFromEnv, - getStringListFromEnv, - diagLogLevelFromString, -} from '@opentelemetry/core'; +import { getStringFromEnv, getStringListFromEnv } from '@opentelemetry/core'; import { getResourceDetectorsFromEnv, getSpanProcessorsFromEnv, @@ -76,6 +71,13 @@ import { setupPropagator, setupContextManager, } from './utils'; +import { + ConfigFactory, + ConfigurationModel, + createConfigFactory, + LogRecordExporterModel, +} from '@opentelemetry/configuration'; +import { CompressionAlgorithm } from '@opentelemetry/otlp-exporter-base'; type TracerProviderConfig = { tracerConfig: NodeTracerConfig; @@ -124,7 +126,7 @@ function configureMetricProviderFromEnv(): IMetricReader[] { if (enabledExporters.includes('none')) { diag.info( - `OTEL_METRICS_EXPORTER contains "none". Metric provider will not be initialized.` + `OTEL_METRICS_EXPORTER contains "none". Meter provider will not be initialized.` ); return metricReaders; } @@ -223,6 +225,7 @@ function configureMetricProviderFromEnv(): IMetricReader[] { * nodeSdk.start(); // registers all configured SDK components */ export class NodeSDK { + private _config: ConfigurationModel; private _tracerProviderConfig?: TracerProviderConfig; private _loggerProviderConfig?: LoggerProviderConfig; private _meterProviderConfig?: MeterProviderConfig; @@ -245,16 +248,17 @@ export class NodeSDK { * Create a new NodeJS SDK instance */ public constructor(configuration: Partial = {}) { - if (getBooleanFromEnv('OTEL_SDK_DISABLED')) { + const configFactory: ConfigFactory = createConfigFactory(); + this._config = configFactory.getConfigModel(); + if (this._config.disabled) { this._disabled = true; // Functions with possible side-effects are set // to no-op via the _disabled flag } - const logLevel = getStringFromEnv('OTEL_LOG_LEVEL'); - if (logLevel != null) { + if (this._config.log_level != null) { diag.setLogger(new DiagConsoleLogger(), { - logLevel: diagLogLevelFromString(logLevel), + logLevel: this._config.log_level, }); } @@ -266,8 +270,8 @@ export class NodeSDK { this._resourceDetectors = []; } else if (configuration.resourceDetectors != null) { this._resourceDetectors = configuration.resourceDetectors; - } else if (getStringFromEnv('OTEL_NODE_RESOURCE_DETECTORS')) { - this._resourceDetectors = getResourceDetectorsFromEnv(); + } else if (this._config.node_resource_detectors) { + this._resourceDetectors = getResourceDetectorsFromEnv(this._config); } else { this._resourceDetectors = [envDetector, processDetector, hostDetector]; } @@ -323,7 +327,7 @@ export class NodeSDK { "The 'logRecordProcessor' option is deprecated. Please use 'logRecordProcessors' instead." ); } else { - this.configureLoggerProviderFromEnv(); + this.configureLoggerProviderFromConfigFactory(); } if ( @@ -462,67 +466,57 @@ export class NodeSDK { ); } - private configureLoggerProviderFromEnv(): void { - const enabledExporters = Array.from( - new Set(getStringListFromEnv('OTEL_LOGS_EXPORTER') ?? []) - ); - - if (enabledExporters.length === 0) { - diag.debug('OTEL_LOGS_EXPORTER is empty. Using default otlp exporter.'); - enabledExporters.push('otlp'); - } - - if (enabledExporters.includes('none')) { - diag.info( - `OTEL_LOGS_EXPORTER contains "none". Logger provider will not be initialized.` - ); - return; + private getExporterType(exporter: LogRecordExporterModel): LogRecordExporter { + if (exporter.otlp_http) { + if (exporter.otlp_http.encoding === 'json') { + return new OTLPHttpLogExporter({ + compression: + exporter.otlp_http.compression === 'gzip' + ? CompressionAlgorithm.GZIP + : CompressionAlgorithm.NONE, + }); + } + if (exporter.otlp_http.encoding === 'protobuf') { + return new OTLPProtoLogExporter(); + } + diag.warn(`Unsupported OTLP logs protocol. Using http/protobuf.`); + return new OTLPProtoLogExporter(); + } else if (exporter.otlp_grpc) { + return new OTLPGrpcLogExporter(); + } else if (exporter.console) { + return new ConsoleLogRecordExporter(); } + diag.warn(`Unsupported Exporter value. Using OTLP http/protobuf.`); + return new OTLPProtoLogExporter(); + } - const exporters: LogRecordExporter[] = []; - - enabledExporters.forEach(exporter => { - if (exporter === 'otlp') { - const protocol = - ( - getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_PROTOCOL') ?? - getStringFromEnv('OTEL_EXPORTER_OTLP_PROTOCOL') - )?.trim() || 'http/protobuf'; // Using || to also fall back on empty string - - switch (protocol) { - case 'grpc': - exporters.push(new OTLPGrpcLogExporter()); - break; - case 'http/json': - exporters.push(new OTLPHttpLogExporter()); - break; - case 'http/protobuf': - exporters.push(new OTLPProtoLogExporter()); - break; - default: - diag.warn( - `Unsupported OTLP logs protocol: "${protocol}". Using http/protobuf.` - ); - exporters.push(new OTLPProtoLogExporter()); - } - } else if (exporter === 'console') { - exporters.push(new ConsoleLogRecordExporter()); - } else { - diag.warn( - `Unsupported OTEL_LOGS_EXPORTER value: "${exporter}". Supported values are: otlp, console, none.` + private configureLoggerProviderFromConfigFactory(): void { + const logRecordProcessors: LogRecordProcessor[] = []; + this._config.logger_provider?.processors?.forEach(processor => { + if (processor.batch) { + logRecordProcessors.push( + new BatchLogRecordProcessor( + this.getExporterType(processor.batch.exporter), + { + maxQueueSize: processor.batch.max_queue_size, + maxExportBatchSize: processor.batch.max_export_batch_size, + scheduledDelayMillis: processor.batch.schedule_delay, + exportTimeoutMillis: processor.batch.export_timeout, + } + ) + ); + } + if (processor.simple) { + logRecordProcessors.push( + new SimpleLogRecordProcessor( + this.getExporterType(processor.simple.exporter) + ) ); } }); - - if (exporters.length > 0) { + if (logRecordProcessors.length > 0) { this._loggerProviderConfig = { - logRecordProcessors: exporters.map(exporter => { - if (exporter instanceof ConsoleLogRecordExporter) { - return new SimpleLogRecordProcessor(exporter); - } else { - return new BatchLogRecordProcessor(exporter); - } - }), + logRecordProcessors: logRecordProcessors, }; } } diff --git a/experimental/packages/opentelemetry-sdk-node/test/semconv.ts b/experimental/packages/opentelemetry-sdk-node/src/semconv.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-node/test/semconv.ts rename to experimental/packages/opentelemetry-sdk-node/src/semconv.ts diff --git a/experimental/packages/opentelemetry-sdk-node/src/utils.ts b/experimental/packages/opentelemetry-sdk-node/src/utils.ts index 691ac4c4753..8ea97fe2b73 100644 --- a/experimental/packages/opentelemetry-sdk-node/src/utils.ts +++ b/experimental/packages/opentelemetry-sdk-node/src/utils.ts @@ -50,6 +50,7 @@ import { import { B3InjectEncoding, B3Propagator } from '@opentelemetry/propagator-b3'; import { JaegerPropagator } from '@opentelemetry/propagator-jaeger'; import { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks'; +import { ConfigurationModel } from '@opentelemetry/configuration'; const RESOURCE_DETECTOR_ENVIRONMENT = 'env'; const RESOURCE_DETECTOR_HOST = 'host'; @@ -57,7 +58,9 @@ const RESOURCE_DETECTOR_OS = 'os'; const RESOURCE_DETECTOR_PROCESS = 'process'; const RESOURCE_DETECTOR_SERVICE_INSTANCE_ID = 'serviceinstance'; -export function getResourceDetectorsFromEnv(): Array { +export function getResourceDetectorsFromEnv( + config: ConfigurationModel +): Array { // When updating this list, make sure to also update the section `resourceDetectors` on README. const resourceDetectors = new Map([ [RESOURCE_DETECTOR_ENVIRONMENT, envDetector], @@ -67,9 +70,7 @@ export function getResourceDetectorsFromEnv(): Array { [RESOURCE_DETECTOR_PROCESS, processDetector], ]); - const resourceDetectorsFromEnv = getStringListFromEnv( - 'OTEL_NODE_RESOURCE_DETECTORS' - ) ?? ['all']; + const resourceDetectorsFromEnv = config.node_resource_detectors ?? ['all']; if (resourceDetectorsFromEnv.includes('all')) { return [...resourceDetectors.values()].flat(); @@ -82,9 +83,7 @@ export function getResourceDetectorsFromEnv(): Array { return resourceDetectorsFromEnv.flatMap(detector => { const resourceDetector = resourceDetectors.get(detector); if (!resourceDetector) { - diag.warn( - `Invalid resource detector "${detector}" specified in the environment variable OTEL_NODE_RESOURCE_DETECTORS` - ); + diag.warn(`Invalid resource detector "${detector}" specified`); } return resourceDetector || []; }); diff --git a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts index 3314f613a20..f68911db64f 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -82,7 +82,7 @@ import { OTLPTraceExporter as OTLPProtoTraceExporter } from '@opentelemetry/expo import { OTLPTraceExporter as OTLPGrpcTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc'; import { ZipkinExporter } from '@opentelemetry/exporter-zipkin'; -import { ATTR_HOST_NAME, ATTR_PROCESS_PID } from './semconv'; +import { ATTR_HOST_NAME, ATTR_PROCESS_PID } from '../src/semconv'; function assertDefaultContextManagerRegistered() { assert.ok( @@ -179,20 +179,6 @@ describe('Node SDK', () => { sdk.shutdown(); }); - it('should not register a diag logger with OTEL_LOG_LEVEL unset', () => { - delete process.env.OTEL_LOG_LEVEL; - - const spy = Sinon.spy(diag, 'setLogger'); - const sdk = new NodeSDK({ - autoDetectResources: false, - }); - - sdk.start(); - - assert.strictEqual(spy.callCount, 0); - sdk.shutdown(); - }); - it('should register a tracer provider if an exporter is provided', async () => { const sdk = new NodeSDK({ traceExporter: new ConsoleSpanExporter(), @@ -1114,7 +1100,17 @@ describe('Node SDK', () => { await sdk.shutdown(); }); - it('should use otlp with http/protobuf by default', async () => { + it('should not set logger provider by default', async () => { + const sdk = new NodeSDK(); + sdk.start(); + const loggerProvider = logs.getLoggerProvider(); + const sharedState = (loggerProvider as any)['_sharedState']; + assert.equal(sharedState, undefined); + await sdk.shutdown(); + }); + + it('should use otlp with http/protobuf by default for otlp', async () => { + process.env.OTEL_LOGS_EXPORTER = 'otlp'; const sdk = new NodeSDK(); sdk.start(); const loggerProvider = logs.getLoggerProvider(); @@ -1189,7 +1185,7 @@ describe('Node SDK', () => { await sdk.shutdown(); }); - it('should fall back to OTEL_EXPORTER_OTLP_PROTOCOL', async () => { + it('should fall back to OTEL_EXPORTER_OTLP_PROTOCOL for logger', async () => { process.env.OTEL_LOGS_EXPORTER = 'otlp'; process.env.OTEL_EXPORTER_OTLP_PROTOCOL = 'grpc'; const sdk = new NodeSDK(); @@ -1224,7 +1220,7 @@ describe('Node SDK', () => { }); }); - describe('configuring metric provider from env', () => { + describe('configuring meter provider from env', () => { let stubLogger: Sinon.SinonStub; beforeEach(() => { @@ -1247,7 +1243,7 @@ describe('Node SDK', () => { assert.ok(!(metrics.getMeterProvider() instanceof MeterProvider)); assert.strictEqual( stubLogger.args[0][0], - 'OTEL_METRICS_EXPORTER contains "none". Metric provider will not be initialized.' + 'OTEL_METRICS_EXPORTER contains "none". Meter provider will not be initialized.' ); await sdk.shutdown(); }); @@ -1339,7 +1335,7 @@ describe('Node SDK', () => { await sdk.shutdown(); }); - it('should fall back to OTEL_EXPORTER_OTLP_PROTOCOL', async () => { + it('should fall back to OTEL_EXPORTER_OTLP_PROTOCOL for metrics', async () => { process.env.OTEL_METRICS_EXPORTER = 'otlp'; process.env.OTEL_EXPORTER_OTLP_METRICS_PROTOCOL = 'grpc'; const sdk = new NodeSDK(); diff --git a/experimental/packages/opentelemetry-sdk-node/test/util/resource-assertions.ts b/experimental/packages/opentelemetry-sdk-node/test/util/resource-assertions.ts index 0938b6090fb..b02e0d7d36a 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/util/resource-assertions.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/util/resource-assertions.ts @@ -21,7 +21,10 @@ import { ATTR_SERVICE_VERSION, } from '@opentelemetry/semantic-conventions'; -import { ATTR_SERVICE_INSTANCE_ID, ATTR_SERVICE_NAMESPACE } from '../semconv'; +import { + ATTR_SERVICE_INSTANCE_ID, + ATTR_SERVICE_NAMESPACE, +} from '../../src/semconv'; /** * Test utility method to validate a service resource @@ -43,6 +46,7 @@ export const assertServiceResource = ( resource.attributes[ATTR_SERVICE_INSTANCE_ID], validations.instanceId ); + if (validations.namespace) assert.strictEqual( resource.attributes[ATTR_SERVICE_NAMESPACE], diff --git a/experimental/packages/opentelemetry-sdk-node/tsconfig.json b/experimental/packages/opentelemetry-sdk-node/tsconfig.json index 5f842b7af04..8cb33508620 100644 --- a/experimental/packages/opentelemetry-sdk-node/tsconfig.json +++ b/experimental/packages/opentelemetry-sdk-node/tsconfig.json @@ -45,6 +45,9 @@ { "path": "../api-logs" }, + { + "path": "../configuration" + }, { "path": "../exporter-logs-otlp-grpc" }, diff --git a/package-lock.json b/package-lock.json index c9ff5f13d6e..cb22b0d7f10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1116,6 +1116,7 @@ "license": "Apache-2.0", "dependencies": { "@opentelemetry/api-logs": "0.208.0", + "@opentelemetry/configuration": "0.208.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/exporter-logs-otlp-grpc": "0.208.0", "@opentelemetry/exporter-logs-otlp-http": "0.208.0",