diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 8f420f32d12..15ee9866d78 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -12,6 +12,7 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2 * feat(otlp-transformer): add span flags support for isRemote property [#5910](https://github.com/open-telemetry/opentelemetry-js/pull/5910) @nikhilmantri0902 * feat(sampler-composite): Added experimental implementations of draft composite sampling spec [#5839](https://github.com/open-telemetry/opentelemetry-js/pull/5839) @anuraaga +* feat(opentelemetry-configuration): add more attributes to config model [#5826](https://github.com/open-telemetry/opentelemetry-js/pull/5826) @maryliag ### :bug: Bug Fixes diff --git a/experimental/packages/opentelemetry-configuration/src/EnvironmentConfigProvider.ts b/experimental/packages/opentelemetry-configuration/src/EnvironmentConfigProvider.ts index 718979c7119..4f1c960fe0d 100644 --- a/experimental/packages/opentelemetry-configuration/src/EnvironmentConfigProvider.ts +++ b/experimental/packages/opentelemetry-configuration/src/EnvironmentConfigProvider.ts @@ -24,6 +24,7 @@ import { getStringFromEnv, getStringListFromEnv, diagLogLevelFromString, + getNumberFromEnv, } from '@opentelemetry/core'; import { ConfigProvider } from './IConfigProvider'; @@ -50,13 +51,352 @@ export class EnvironmentConfigProvider implements ConfigProvider { this._config.node_resource_detectors = nodeResourceDetectors; } - const resourceAttrList = getStringFromEnv('OTEL_RESOURCE_ATTRIBUTES'); - if (resourceAttrList) { - this._config.resource.attributes_list = resourceAttrList; - } + setResources(this._config); + setAttributeLimits(this._config); + setPropagators(this._config); + setTracerProvider(this._config); + setMeterProvider(this._config); + setLoggerProvider(this._config); } getInstrumentationConfig(): ConfigurationModel { return this._config; } } + +function setResources(config: ConfigurationModel): void { + const resourceAttrList = getStringFromEnv('OTEL_RESOURCE_ATTRIBUTES'); + if (resourceAttrList) { + config.resource.attributes_list = resourceAttrList; + } + + const serviceName = getStringFromEnv('OTEL_SERVICE_NAME'); + if (serviceName) { + config.resource.attributes = [ + { + name: 'service.name', + value: serviceName, + type: 'string', + }, + ]; + } +} + +function setAttributeLimits(config: ConfigurationModel): void { + const attributeValueLengthLimit = getNumberFromEnv( + 'OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT' + ); + if (attributeValueLengthLimit) { + config.attribute_limits.attribute_value_length_limit = + attributeValueLengthLimit; + } + + const attributeCountLimit = getNumberFromEnv('OTEL_ATTRIBUTE_COUNT_LIMIT'); + if (attributeCountLimit) { + config.attribute_limits.attribute_count_limit = attributeCountLimit; + } +} + +function setPropagators(config: ConfigurationModel): void { + const propagators = getStringListFromEnv('OTEL_PROPAGATORS'); + if (propagators) { + config.propagator = { + composite: propagators, + composite_list: + getStringFromEnv('OTEL_PROPAGATORS') || 'tracecontext,baggage', + }; + } +} + +function setTracerProvider(config: ConfigurationModel): void { + const attributeValueLengthLimit = getNumberFromEnv( + 'OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT' + ); + if (attributeValueLengthLimit) { + config.tracer_provider.limits.attribute_value_length_limit = + attributeValueLengthLimit; + } + + const attributeCountLimit = getNumberFromEnv( + 'OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT' + ); + if (attributeCountLimit) { + config.tracer_provider.limits.attribute_count_limit = attributeCountLimit; + } + + const eventCountLimit = getNumberFromEnv('OTEL_SPAN_EVENT_COUNT_LIMIT'); + if (eventCountLimit) { + config.tracer_provider.limits.event_count_limit = eventCountLimit; + } + + const linkCountLimit = getNumberFromEnv('OTEL_SPAN_LINK_COUNT_LIMIT'); + if (linkCountLimit) { + config.tracer_provider.limits.link_count_limit = linkCountLimit; + } + + const eventAttributeCountLimit = getNumberFromEnv( + 'OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT' + ); + if (eventAttributeCountLimit) { + config.tracer_provider.limits.event_attribute_count_limit = + eventAttributeCountLimit; + } + + const linkAttributeCountLimit = getNumberFromEnv( + 'OTEL_LINK_ATTRIBUTE_COUNT_LIMIT' + ); + if (linkAttributeCountLimit) { + config.tracer_provider.limits.link_attribute_count_limit = + 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 maxQueueSize = getNumberFromEnv('OTEL_BSP_MAX_QUEUE_SIZE'); + if (maxQueueSize) { + batch.max_queue_size = maxQueueSize; + } + + const maxExportBatchSize = getNumberFromEnv( + 'OTEL_BSP_MAX_EXPORT_BATCH_SIZE' + ); + if (maxExportBatchSize) { + batch.max_export_batch_size = maxExportBatchSize; + } + + const endpoint = getStringFromEnv('OTEL_EXPORTER_OTLP_TRACES_ENDPOINT'); + if (endpoint) { + batch.exporter.otlp_http.endpoint = endpoint; + } + + const certificateFile = getStringFromEnv( + 'OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE' + ); + if (certificateFile) { + batch.exporter.otlp_http.certificate_file = certificateFile; + } + + const clientKeyFile = getStringFromEnv( + 'OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY' + ); + if (clientKeyFile) { + batch.exporter.otlp_http.client_key_file = clientKeyFile; + } + + const clientCertificateFile = getStringFromEnv( + 'OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE' + ); + if (clientCertificateFile) { + batch.exporter.otlp_http.client_certificate_file = clientCertificateFile; + } + + const compression = getStringFromEnv( + 'OTEL_EXPORTER_OTLP_TRACES_COMPRESSION' + ); + if (compression) { + batch.exporter.otlp_http.compression = compression; + } + + const timeout = getNumberFromEnv('OTEL_EXPORTER_OTLP_TRACES_TIMEOUT'); + if (timeout) { + batch.exporter.otlp_http.timeout = timeout; + } + + const headersList = getStringFromEnv('OTEL_EXPORTER_OTLP_TRACES_HEADERS'); + if (headersList) { + batch.exporter.otlp_http.headers_list = headersList; + } + + config.tracer_provider.processors[0].batch = batch; + } +} + +function setMeterProvider(config: ConfigurationModel): void { + const readerPeriodic = config.meter_provider.readers[0]?.periodic; + if (readerPeriodic) { + const interval = getNumberFromEnv('OTEL_METRIC_EXPORT_INTERVAL'); + if (interval) { + readerPeriodic.interval = interval; + } + + const timeout = getNumberFromEnv('OTEL_METRIC_EXPORT_TIMEOUT'); + if (timeout) { + readerPeriodic.timeout = timeout; + } + + const endpoint = getStringFromEnv('OTEL_EXPORTER_OTLP_METRICS_ENDPOINT'); + if (endpoint) { + readerPeriodic.exporter.otlp_http.endpoint = endpoint; + } + + const certificateFile = getStringFromEnv( + 'OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE' + ); + if (certificateFile) { + readerPeriodic.exporter.otlp_http.certificate_file = certificateFile; + } + + const clientKeyFile = getStringFromEnv( + 'OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY' + ); + if (clientKeyFile) { + readerPeriodic.exporter.otlp_http.client_key_file = clientKeyFile; + } + + const clientCertificateFile = getStringFromEnv( + 'OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE' + ); + if (clientCertificateFile) { + readerPeriodic.exporter.otlp_http.client_certificate_file = + clientCertificateFile; + } + + const compression = getStringFromEnv( + 'OTEL_EXPORTER_OTLP_METRICS_COMPRESSION' + ); + if (compression) { + readerPeriodic.exporter.otlp_http.compression = compression; + } + + const timeoutEx = getNumberFromEnv('OTEL_EXPORTER_OTLP_METRICS_TIMEOUT'); + if (timeoutEx) { + readerPeriodic.exporter.otlp_http.timeout = timeoutEx; + } + + const headersList = getStringFromEnv('OTEL_EXPORTER_OTLP_METRICS_HEADERS'); + if (headersList) { + readerPeriodic.exporter.otlp_http.headers_list = headersList; + } + + const temporalityPreference = getStringFromEnv( + 'OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE' + ); + if ( + temporalityPreference && + (temporalityPreference === 'cumulative' || + temporalityPreference === 'delta' || + temporalityPreference === 'low_memory') + ) { + readerPeriodic.exporter.otlp_http.temporality_preference = + temporalityPreference; + } + + const defaultHistogramAggregation = getStringFromEnv( + 'OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION' + ); + if ( + defaultHistogramAggregation && + (defaultHistogramAggregation === 'explicit_bucket_histogram' || + defaultHistogramAggregation === 'base2_exponential_bucket_histogram') + ) { + readerPeriodic.exporter.otlp_http.default_histogram_aggregation = + defaultHistogramAggregation; + } + + config.meter_provider.readers[0].periodic = readerPeriodic; + } + const exemplarFilter = getStringFromEnv('OTEL_METRICS_EXEMPLAR_FILTER'); + if ( + exemplarFilter && + (exemplarFilter === 'trace_based' || + exemplarFilter === 'always_on' || + exemplarFilter === 'always_off') + ) { + config.meter_provider.exemplar_filter = exemplarFilter; + } +} + +function setLoggerProvider(config: ConfigurationModel): void { + const attributeValueLengthLimit = getNumberFromEnv( + 'OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT' + ); + if (attributeValueLengthLimit) { + config.logger_provider.limits.attribute_value_length_limit = + attributeValueLengthLimit; + } + + const attributeCountLimit = getNumberFromEnv( + 'OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT' + ); + if (attributeCountLimit) { + config.logger_provider.limits.attribute_count_limit = attributeCountLimit; + } + + const batch = config.logger_provider.processors[0]?.batch; + 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 maxExportBatchSize = getNumberFromEnv( + 'OTEL_BLRP_MAX_EXPORT_BATCH_SIZE' + ); + if (maxExportBatchSize) { + batch.max_export_batch_size = maxExportBatchSize; + } + + const endpoint = getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_ENDPOINT'); + if (endpoint) { + batch.exporter.otlp_http.endpoint = endpoint; + } + + const certificateFile = getStringFromEnv( + 'OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE' + ); + if (certificateFile) { + batch.exporter.otlp_http.certificate_file = certificateFile; + } + + const clientKeyFile = getStringFromEnv( + 'OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY' + ); + if (clientKeyFile) { + batch.exporter.otlp_http.client_key_file = clientKeyFile; + } + + const clientCertificateFile = getStringFromEnv( + 'OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE' + ); + if (clientCertificateFile) { + batch.exporter.otlp_http.client_certificate_file = clientCertificateFile; + } + + const compression = getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_COMPRESSION'); + if (compression) { + batch.exporter.otlp_http.compression = compression; + } + + const timeout = getNumberFromEnv('OTEL_EXPORTER_OTLP_LOGS_TIMEOUT'); + if (timeout) { + batch.exporter.otlp_http.timeout = timeout; + } + + const headersList = getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_HEADERS'); + if (headersList) { + batch.exporter.otlp_http.headers_list = headersList; + } + + config.logger_provider.processors[0].batch = batch; + } +} diff --git a/experimental/packages/opentelemetry-configuration/src/configModel.ts b/experimental/packages/opentelemetry-configuration/src/configModel.ts index 3791b554ce4..d697675bf61 100644 --- a/experimental/packages/opentelemetry-configuration/src/configModel.ts +++ b/experimental/packages/opentelemetry-configuration/src/configModel.ts @@ -40,6 +40,32 @@ export interface ConfigurationModel { * If omitted, the default resource is used. */ resource: ConfigResources; + + /** + * Configure general attribute limits. + * See also tracer_provider.limits, logger_provider.limits. + */ + attribute_limits: AttributeLimits; + + /** + * Configure text map context propagators. + */ + propagator: ConfigPropagator; + + /** + * Configure tracer provider. + */ + tracer_provider: ConfigTracerProvider; + + /** + * Configure meter provider. + */ + meter_provider: ConfigMeterProvider; + + /** + * Configure logger provider. + */ + logger_provider: ConfigLoggerProvider; } export function initializeDefaultConfiguration(): ConfigurationModel { @@ -48,6 +74,87 @@ export function initializeDefaultConfiguration(): ConfigurationModel { log_level: DiagLogLevel.INFO, node_resource_detectors: ['all'], resource: {}, + attribute_limits: { + attribute_count_limit: 128, + }, + propagator: { + composite: ['tracecontext', 'baggage'], + 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, + }, + }, + }, + }, + ], + 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', + remote_parent_sampled: 'always_on', + remote_parent_not_sampled: 'always_off', + local_parent_sampled: 'always_on', + local_parent_not_sampled: 'always_off', + }, + }, + }, + meter_provider: { + readers: [ + { + periodic: { + interval: 60000, + timeout: 30000, + exporter: { + otlp_http: { + endpoint: 'http://localhost:4318/v1/metrics', + timeout: 10000, + temporality_preference: 'cumulative', + default_histogram_aggregation: 'explicit_bucket_histogram', + }, + }, + }, + }, + ], + exemplar_filter: 'trace_based', + }, + 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, + }, + }, + }, + }, + ], + limits: { + attribute_count_limit: 128, + }, + }, }; return config; @@ -88,3 +195,377 @@ export interface ConfigResources { */ schema_url?: string; } + +export interface AttributeLimits { + /** + * Configure max attribute value size. + * Value must be non-negative. + * If omitted or null, there is no limit. + */ + attribute_value_length_limit?: number; + + /** + * Configure max attribute count. + * Value must be non-negative. + * If omitted or null, 128 is used. + */ + attribute_count_limit: number; +} + +export interface ConfigPropagator { + /** + * Configure the propagators in the composite text map propagator. + * Entries from .composite_list are appended to the list here with duplicates filtered out. + * Built-in propagator keys include: tracecontext, baggage, b3, b3multi, jaeger, ottrace. + * Known third party keys include: xray. + * If the resolved list of propagators (from .composite and .composite_list) is empty, a noop propagator is used. + */ + composite: string[]; + + /** + * Configure the propagators in the composite text map propagator. + * Entries are appended to .composite with duplicates filtered out. + * The value is a comma separated list of propagator identifiers matching the format of OTEL_PROPAGATORS. + * Built-in propagator identifiers include: tracecontext, baggage, b3, b3multi, jaeger, ottrace. + * Known third party identifiers include: xray. + * If the resolved list of propagators (from .composite and .composite_list) is empty, a noop propagator is used. + */ + composite_list: string; +} + +export interface ConfigBatchProcessor { + /** + * Configure delay interval (in milliseconds) between two consecutive exports. + * Value must be non-negative. + * If omitted or null, 5000 is used for traces and 1000 for logs. + */ + schedule_delay: number; + + /** + * 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: number; + + /** + * Configure maximum queue size. Value must be positive. + * If omitted or null, 2048 is used. + */ + max_queue_size: number; + + /** + * Configure maximum batch size. Value must be positive. + * If omitted or null, 512 is used. + */ + max_export_batch_size: number; + + /** + * Configure exporter. + */ + exporter: ConfigExporter; +} + +export interface ConfigExporter { + /** + * Configure exporter to be OTLP with HTTP transport. + */ + otlp_http: ConfigOTLPHttp; +} + +export interface ConfigMeterExporter { + /** + * Configure exporter to be OTLP with HTTP transport. + */ + otlp_http: ConfigMeterOTLPHttp; +} + +export interface ConfigOTLPHttp { + /** + * Configure endpoint, including the trace or log specific path. + * If omitted or null, http://localhost:4318/v1/traces is used for trace + * and http://localhost:4318/v1/logs is used for logs. + */ + endpoint: string; + + /** + * Configure certificate used to verify a server's TLS credentials. + * Absolute path to certificate file in PEM format. + * If omitted or null, system default certificate verification is used for secure connections. + */ + certificate_file?: string; + + /** + * Configure mTLS private client key. + * Absolute path to client key file in PEM format. If set, .client_certificate must also be set. + * If omitted or null, mTLS is not used. + */ + client_key_file?: string; + + /** + * Configure mTLS client certificate. + * Absolute path to client certificate file in PEM format. If set, .client_key must also be set. + * If omitted or null, mTLS is not used. + */ + client_certificate_file?: string; + + /** + * Configure compression. + * Values include: gzip, none. Implementations may support other compression algorithms. + * If omitted or null, none is used. + */ + compression?: string; + + /** + * Configure max time (in milliseconds) to wait for each export. + * Value must be non-negative. A value of 0 indicates no limit (infinity). + * If omitted or null, 10000 is used. + */ + timeout: number; + + /** + * Configure headers. Entries have higher priority than entries from .headers_list. + * If an entry's .value is null, the entry is ignored. + */ + headers?: ConfigHeader[]; + + /** + * Configure headers. Entries have lower priority than entries from .headers. + * The value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. + * If omitted or null, no headers are added. + */ + headers_list?: string; +} +export interface ConfigProcessor { + /** + * Configure a batch span processor. + */ + batch: ConfigBatchProcessor; +} + +export interface ConfigHeader { + name: string; + value: string; +} + +export interface ConfigTracerLimits { + /** + * Configure max attribute value size. Overrides .attribute_limits.attribute_value_length_limit. + * Value must be non-negative. + * If omitted or null, there is no limit. + */ + attribute_value_length_limit?: number; + + /** + * Configure max attribute count. Overrides .attribute_limits.attribute_count_limit. + * Value must be non-negative. + * If omitted or null, 128 is used. + */ + attribute_count_limit: number; + + /** + * Configure max span event count. + * Value must be non-negative. + * If omitted or null, 128 is used. + */ + event_count_limit: number; + + /** + * Configure max span link count. + * Value must be non-negative. + * If omitted or null, 128 is used. + */ + link_count_limit: number; + + /** + * Configure max attributes per span event. + * Value must be non-negative. + * If omitted or null, 128 is used. + */ + event_attribute_count_limit: number; + + /** + * Configure max attributes per span link. + * Value must be non-negative. + * If omitted or null, 128 is used. + */ + link_attribute_count_limit: number; +} + +export interface ConfigParentBase { + /** + * Configure root sampler. + * If omitted or null, always_on is used. + */ + root: 'always_on' | 'always_off'; + + /** + * Configure remote_parent_sampled sampler. + * If omitted or null, always_on is used. + */ + remote_parent_sampled: 'always_on' | 'always_off'; + + /** + * Configure remote_parent_not_sampled sampler. + * If omitted or null, always_off is used. + */ + remote_parent_not_sampled: 'always_on' | 'always_off'; + + /** + * Configure local_parent_sampled sampler. + * If omitted or null, always_on is used. + */ + local_parent_sampled: 'always_on' | 'always_off'; + + /** + * Configure local_parent_not_sampled sampler. + * If omitted or null, always_off is used. + */ + local_parent_not_sampled: 'always_on' | 'always_off'; +} +export interface ConfigSampler { + /** + * Configure sampler to be parent_based. + */ + parent_based: ConfigParentBase; +} +export interface ConfigTracerProvider { + /** + * Configure span processors. + */ + processors: ConfigProcessor[]; + + /** + * Configure span limits. See also attribute_limits. + */ + limits: ConfigTracerLimits; + + /** + * Configure the sampler. + * If omitted, parent based sampler with a root of always_on is used. + */ + sampler: ConfigSampler; +} + +export interface ConfigMeterOTLPHttp { + /** + * Configure endpoint, including the metric specific path. + * If omitted or null, http://localhost:4318/v1/metrics is used. + */ + endpoint: string; + + /** + * Configure certificate used to verify a server's TLS credentials. + * Absolute path to certificate file in PEM format. + * If omitted or null, system default certificate verification is used for secure connections. + */ + certificate_file?: string; + + /** + * Configure mTLS private client key. + * Absolute path to client key file in PEM format. If set, .client_certificate must also be set. + * If omitted or null, mTLS is not used. + */ + client_key_file?: string; + + /** + * Configure mTLS client certificate. + * Absolute path to client certificate file in PEM format. If set, .client_key must also be set. + * If omitted or null, mTLS is not used. + */ + client_certificate_file?: string; + + /** + * Configure compression. + * Values include: gzip, none. Implementations may support other compression algorithms. + * If omitted or null, none is used. + */ + compression?: string; + + /** + * Configure max time (in milliseconds) to wait for each export. + * Value must be non-negative. A value of 0 indicates no limit (infinity). + * If omitted or null, 10000 is used. + */ + timeout: number; + + /** + * Configure headers. Entries have higher priority than entries from .headers_list. + * If an entry's .value is null, the entry is ignored. + */ + headers?: ConfigHeader[]; + + /** + * Configure headers. Entries have lower priority than entries from .headers. + * The value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. + * If omitted or null, no headers are added. + */ + headers_list?: string; + + /** + * Configure temporality preference. + * Values include: cumulative, delta, low_memory. + * If omitted or null, cumulative is used. + */ + temporality_preference: 'cumulative' | 'delta' | 'low_memory'; + + /** + * Configure default histogram aggregation. + * Values include: explicit_bucket_histogram, base2_exponential_bucket_histogram. + * If omitted or null, explicit_bucket_histogram is used. + */ + default_histogram_aggregation: + | 'explicit_bucket_histogram' + | 'base2_exponential_bucket_histogram'; +} +export interface ConfigPeriodicReader { + /** + * Configure delay interval (in milliseconds) between start of two consecutive exports. + * Value must be non-negative. + * If omitted or null, 60000 is used. + */ + interval: number; + + /** + * 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. + */ + timeout: number; + + /** + * Configure exporter. + */ + exporter: ConfigMeterExporter; +} +export interface ConfigReader { + /** + * Configure a periodic metric reader. + */ + periodic: ConfigPeriodicReader; +} +export interface ConfigMeterProvider { + /** + * Configure metric readers. + */ + readers: ConfigReader[]; + + /** + * Configure the exemplar filter. + * Values include: trace_based, always_on, always_off. + * If omitted or null, trace_based is used. + */ + exemplar_filter: 'trace_based' | 'always_on' | 'always_off'; +} + +export interface ConfigLoggerProvider { + /** + * Configure log record processors. + */ + processors: ConfigProcessor[]; + + /** + * Configure log record limits. See also attribute_limits. + */ + limits: AttributeLimits; +} diff --git a/experimental/packages/opentelemetry-configuration/test/ConfigProvider.test.ts b/experimental/packages/opentelemetry-configuration/test/ConfigProvider.test.ts index 8594f2f6198..670a09e47e3 100644 --- a/experimental/packages/opentelemetry-configuration/test/ConfigProvider.test.ts +++ b/experimental/packages/opentelemetry-configuration/test/ConfigProvider.test.ts @@ -24,6 +24,87 @@ const defaultConfig: Configuration = { log_level: DiagLogLevel.INFO, node_resource_detectors: ['all'], resource: {}, + attribute_limits: { + attribute_count_limit: 128, + }, + propagator: { + composite: ['tracecontext', 'baggage'], + 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, + }, + }, + }, + }, + ], + 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', + remote_parent_sampled: 'always_on', + remote_parent_not_sampled: 'always_off', + local_parent_sampled: 'always_on', + local_parent_not_sampled: 'always_off', + }, + }, + }, + meter_provider: { + readers: [ + { + periodic: { + interval: 60000, + timeout: 30000, + exporter: { + otlp_http: { + endpoint: 'http://localhost:4318/v1/metrics', + timeout: 10000, + temporality_preference: 'cumulative', + default_histogram_aggregation: 'explicit_bucket_histogram', + }, + }, + }, + }, + ], + exemplar_filter: 'trace_based', + }, + 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, + }, + }, + }, + }, + ], + limits: { + attribute_count_limit: 128, + }, + }, }; describe('ConfigProvider', function () { @@ -33,6 +114,53 @@ describe('ConfigProvider', function () { delete process.env.OTEL_LOG_LEVEL; delete process.env.OTEL_NODE_RESOURCE_DETECTORS; delete process.env.OTEL_RESOURCE_ATTRIBUTES; + delete process.env.OTEL_SERVICE_NAME; + delete process.env.OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT; + delete process.env.OTEL_ATTRIBUTE_COUNT_LIMIT; + delete process.env.OTEL_PROPAGATORS; + delete process.env.OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT; + delete process.env.OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT; + delete process.env.OTEL_SPAN_EVENT_COUNT_LIMIT; + delete process.env.OTEL_SPAN_LINK_COUNT_LIMIT; + delete process.env.OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT; + delete process.env.OTEL_LINK_ATTRIBUTE_COUNT_LIMIT; + delete process.env.OTEL_BSP_SCHEDULE_DELAY; + delete process.env.OTEL_BSP_EXPORT_TIMEOUT; + delete process.env.OTEL_BSP_MAX_QUEUE_SIZE; + delete process.env.OTEL_BSP_MAX_EXPORT_BATCH_SIZE; + delete process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT; + delete process.env.OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE; + delete process.env.OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY; + delete process.env.OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE; + delete process.env.OTEL_EXPORTER_OTLP_TRACES_COMPRESSION; + delete process.env.OTEL_EXPORTER_OTLP_TRACES_TIMEOUT; + delete process.env.OTEL_EXPORTER_OTLP_TRACES_HEADERS; + delete process.env.OTEL_METRIC_EXPORT_INTERVAL; + delete process.env.OTEL_METRIC_EXPORT_TIMEOUT; + delete process.env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT; + delete process.env.OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE; + delete process.env.OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY; + delete process.env.OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE; + delete process.env.OTEL_EXPORTER_OTLP_METRICS_COMPRESSION; + delete process.env.OTEL_EXPORTER_OTLP_METRICS_TIMEOUT; + delete process.env.OTEL_EXPORTER_OTLP_METRICS_HEADERS; + delete process.env.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE; + delete process.env + .OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION; + delete process.env.OTEL_METRICS_EXEMPLAR_FILTER; + delete process.env.OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT; + delete process.env.OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT; + delete process.env.OTEL_BLRP_SCHEDULE_DELAY; + delete process.env.OTEL_BLRP_EXPORT_TIMEOUT; + delete process.env.OTEL_BLRP_MAX_QUEUE_SIZE; + delete process.env.OTEL_BLRP_MAX_EXPORT_BATCH_SIZE; + delete process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT; + delete process.env.OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE; + delete process.env.OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY; + delete process.env.OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE; + delete process.env.OTEL_EXPORTER_OTLP_LOGS_COMPRESSION; + delete process.env.OTEL_EXPORTER_OTLP_LOGS_TIMEOUT; + delete process.env.OTEL_EXPORTER_OTLP_LOGS_HEADERS; }); it('should initialize config with default values', function () { @@ -98,6 +226,238 @@ describe('ConfigProvider', function () { expectedConfig ); }); + + it('should return config with custom service name', function () { + process.env.OTEL_SERVICE_NAME = 'my service name'; + const expectedConfig: Configuration = { + ...defaultConfig, + resource: { + attributes: [ + { + name: 'service.name', + value: 'my service name', + type: 'string', + }, + ], + }, + }; + const configProvider = createConfigProvider(); + assert.deepStrictEqual( + configProvider.getInstrumentationConfig(), + expectedConfig + ); + }); + + it('should return config with custom attribute_limits', function () { + process.env.OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT = '100'; + process.env.OTEL_ATTRIBUTE_COUNT_LIMIT = '200'; + const expectedConfig: Configuration = { + ...defaultConfig, + attribute_limits: { + attribute_value_length_limit: 100, + attribute_count_limit: 200, + }, + }; + const configProvider = createConfigProvider(); + assert.deepStrictEqual( + configProvider.getInstrumentationConfig(), + expectedConfig + ); + }); + + it('should return config with custom propagator', function () { + process.env.OTEL_PROPAGATORS = 'tracecontext,jaeger'; + const expectedConfig: Configuration = { + ...defaultConfig, + propagator: { + composite: ['tracecontext', 'jaeger'], + composite_list: 'tracecontext,jaeger', + }, + }; + const configProvider = createConfigProvider(); + assert.deepStrictEqual( + configProvider.getInstrumentationConfig(), + expectedConfig + ); + }); + + it('should return config with custom tracer_provider', function () { + 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'; + process.env.OTEL_SPAN_LINK_COUNT_LIMIT = '400'; + process.env.OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT = '500'; + process.env.OTEL_LINK_ATTRIBUTE_COUNT_LIMIT = '600'; + process.env.OTEL_BSP_SCHEDULE_DELAY = '700'; + process.env.OTEL_BSP_EXPORT_TIMEOUT = '800'; + process.env.OTEL_BSP_MAX_QUEUE_SIZE = '900'; + process.env.OTEL_BSP_MAX_EXPORT_BATCH_SIZE = '1000'; + process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = + 'http://test.com:4318/v1/traces'; + process.env.OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE = + 'certificate_file.txt'; + process.env.OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY = + 'certificate_key_value'; + process.env.OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE = + 'client_certificate_file.txt'; + process.env.OTEL_EXPORTER_OTLP_TRACES_COMPRESSION = 'gzip'; + process.env.OTEL_EXPORTER_OTLP_TRACES_TIMEOUT = '2000'; + process.env.OTEL_EXPORTER_OTLP_TRACES_HEADERS = 'host=localhost'; + const expectedConfig: Configuration = { + ...defaultConfig, + tracer_provider: { + limits: { + attribute_value_length_limit: 100, + attribute_count_limit: 200, + event_count_limit: 300, + link_count_limit: 400, + event_attribute_count_limit: 500, + link_attribute_count_limit: 600, + }, + processors: [ + { + batch: { + schedule_delay: 700, + export_timeout: 800, + max_queue_size: 900, + max_export_batch_size: 1000, + exporter: { + otlp_http: { + endpoint: 'http://test.com:4318/v1/traces', + certificate_file: 'certificate_file.txt', + client_key_file: 'certificate_key_value', + client_certificate_file: 'client_certificate_file.txt', + compression: 'gzip', + timeout: 2000, + headers_list: 'host=localhost', + }, + }, + }, + }, + ], + sampler: { + parent_based: { + root: 'always_on', + remote_parent_sampled: 'always_on', + remote_parent_not_sampled: 'always_off', + local_parent_sampled: 'always_on', + local_parent_not_sampled: 'always_off', + }, + }, + }, + }; + const configProvider = createConfigProvider(); + assert.deepStrictEqual( + configProvider.getInstrumentationConfig(), + expectedConfig + ); + }); + + 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_EXPORTER_OTLP_METRICS_ENDPOINT = + 'http://test.com:4318/v1/metrics'; + process.env.OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE = + 'certificate_file.txt'; + process.env.OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY = + 'certificate_key_value'; + process.env.OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE = + 'client_certificate_file.txt'; + process.env.OTEL_EXPORTER_OTLP_METRICS_COMPRESSION = 'gzip'; + process.env.OTEL_EXPORTER_OTLP_METRICS_TIMEOUT = '300'; + process.env.OTEL_EXPORTER_OTLP_METRICS_HEADERS = 'host=localhost'; + process.env.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE = 'delta'; + process.env.OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION = + 'base2_exponential_bucket_histogram'; + process.env.OTEL_METRICS_EXEMPLAR_FILTER = 'always_on'; + const expectedConfig: Configuration = { + ...defaultConfig, + meter_provider: { + readers: [ + { + periodic: { + interval: 100, + timeout: 200, + exporter: { + otlp_http: { + endpoint: 'http://test.com:4318/v1/metrics', + certificate_file: 'certificate_file.txt', + client_key_file: 'certificate_key_value', + client_certificate_file: 'client_certificate_file.txt', + compression: 'gzip', + timeout: 300, + headers_list: 'host=localhost', + temporality_preference: 'delta', + default_histogram_aggregation: + 'base2_exponential_bucket_histogram', + }, + }, + }, + }, + ], + exemplar_filter: 'always_on', + }, + }; + const configProvider = createConfigProvider(); + assert.deepStrictEqual( + configProvider.getInstrumentationConfig(), + expectedConfig + ); + }); + + it('should return config with custom logger_provider', function () { + process.env.OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT = '100'; + process.env.OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT = '200'; + process.env.OTEL_BLRP_SCHEDULE_DELAY = '300'; + 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_EXPORTER_OTLP_LOGS_ENDPOINT = + 'http://test.com:4318/v1/logs'; + process.env.OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE = 'certificate_file.txt'; + process.env.OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY = 'certificate_key_value'; + process.env.OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE = + 'client_certificate_file.txt'; + process.env.OTEL_EXPORTER_OTLP_LOGS_COMPRESSION = 'gzip'; + process.env.OTEL_EXPORTER_OTLP_LOGS_TIMEOUT = '700'; + process.env.OTEL_EXPORTER_OTLP_LOGS_HEADERS = 'host=localhost'; + const expectedConfig: Configuration = { + ...defaultConfig, + logger_provider: { + limits: { + attribute_value_length_limit: 100, + attribute_count_limit: 200, + }, + processors: [ + { + batch: { + schedule_delay: 300, + export_timeout: 400, + max_queue_size: 500, + max_export_batch_size: 600, + exporter: { + otlp_http: { + endpoint: 'http://test.com:4318/v1/logs', + certificate_file: 'certificate_file.txt', + client_key_file: 'certificate_key_value', + client_certificate_file: 'client_certificate_file.txt', + compression: 'gzip', + timeout: 700, + headers_list: 'host=localhost', + }, + }, + }, + }, + ], + }, + }; + const configProvider = createConfigProvider(); + assert.deepStrictEqual( + configProvider.getInstrumentationConfig(), + expectedConfig + ); + }); }); describe('get values from config file', function () {