diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 01e76816976..a67d748f4f0 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -8,6 +8,8 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2 ### :boom: Breaking Changes +* fix(configuration)!: stop removing `null` values from parsed config object [#6679](https://github.com/open-telemetry/opentelemetry-js/pull/6679) @trentm + * It is now the responsibility of the user of a parsed declarative config object, typically just the `sdk-node` package, to handle `null` values. * fix(api-logs): Removed `NOOP_LOGGER` and `NoopLogger` exports from `@opentelemetry/api-logs`. Use `createNoopLogger(): Logger` instead. [#6713](https://github.com/open-telemetry/opentelemetry-js/pull/6713) @dyladan ### :rocket: Features diff --git a/experimental/packages/configuration/scripts/generate-config.js b/experimental/packages/configuration/scripts/generate-config.js index 10943f02bb2..1ef69467a6a 100644 --- a/experimental/packages/configuration/scripts/generate-config.js +++ b/experimental/packages/configuration/scripts/generate-config.js @@ -218,51 +218,6 @@ function rtrimDescription(node) { } rtrimDescription(schema); -// Avoid unnecessary `| null` in TypeScript types. -// -// opentelemetry-configuration intentionally adds an optional "null" type to -// most fields to express optional/nullable values, e.g.: -// "ConsoleMetricExporter": { -// "type": [ -// "object", -// "null" -// ], -// See explanation at: https://github.com/open-telemetry/opentelemetry-configuration/blob/main/CONTRIBUTING.md#required-and-null-properties -// -// In TypeScript, `?` expresses a property being optional, e.g.: -// endpoint?: string; -// Leaving "null" in the JSON Schema results in TypeScript like this: -// endpoint?: string | null; -// -// That null option has a downstream blast radius. E.g. a downstream API that -// takes that `endpoint` value, now needs to handle `null`. -// -// By preprocessing the schema to remove those we get nicer typescript types. -function stripNullTypeFallback(obj) { - if (Array.isArray(obj.type)) { - if (obj.type.length === 2 && obj.type[1] === 'null') { - obj.type.pop(); - } - } else if (Array.isArray(obj.oneOf)) { - // Handle the more complex case of AttributeNameValue#value, which uses: - // "value": { "oneOf": [{"type":"string"}, {"type":"null"}, ...] } - if (obj.oneOf.length > 1) { - obj.oneOf = obj.oneOf.filter(entry => { - return !(entry?.type === 'null' && Object.keys(entry).length === 1); - }); - } - } - if (typeof obj.properties === 'object' && obj.properties != null) { - for (const prop of Object.values(obj.properties)) { - stripNullTypeFallback(prop); - } - } -} -stripNullTypeFallback(schema); -for (const def of Object.values(schema.$defs)) { - stripNullTypeFallback(def); -} - compile(schema, 'OpenTelemetryConfiguration', { bannerComment, unknownAny: false, @@ -288,7 +243,7 @@ compile(schema, 'OpenTelemetryConfiguration', { // of the codebase and other OTel SDKs. ts = ts.replace(/\bOpenTelemetryConfiguration\b/g, 'ConfigurationModel'); - // Change the TypeScript representation for interfaces where + // Refine the TypeScript representation for interfaces where // "additionalProperties" is allowed. // // The configuration JSON schema uses the following for types that have @@ -301,17 +256,17 @@ compile(schema, 'OpenTelemetryConfiguration', { // [k: string]: {} | null // // However, we want: - // [k: string]: object | undefined + // [k: string]: object | null | undefined // // - `object` instead of `{}`, because JSON schema "object" means a thing // with keys and values (https://json-schema.org/understanding-json-schema/reference/object) // and TypeScript "object" means non-Primitive values (https://stackoverflow.com/a/49465172) // which is closest. `{}` allows too much (e.g. 42 matches `{}`). - // - `undefined` rather than `null` because we want to express that the - // property can be unspecified. + // - `null` to allow an empty value in the YAML + // - `undefined` to allow the property to not be specified in the YAML ts = ts.replace( /\[k: string\]: \{\} \| null;/g, - '[k: string]: object | undefined;' + '[k: string]: object | null | undefined;' ); // Similarly for schema types with the following (e.g. `Distribution`): // "additionalProperties": { diff --git a/experimental/packages/configuration/src/FileConfigFactory.ts b/experimental/packages/configuration/src/FileConfigFactory.ts index 57847148619..1616059e276 100644 --- a/experimental/packages/configuration/src/FileConfigFactory.ts +++ b/experimental/packages/configuration/src/FileConfigFactory.ts @@ -47,9 +47,6 @@ export function parseConfigFile(): ConfigurationModel { ); } - // Normalize YAML null type-tag values to {} before validation - normalizeYamlNulls(processed); - const valid = validateConfig(processed); if (!valid) { let detail: string; @@ -76,14 +73,6 @@ export function parseConfigFile(): ConfigurationModel { // Strip file_format from output — it's a meta-field, not a config value delete (data as Record)['file_format']; - // The generated TypeScript types omit `| null` from unions (see - // generate-config.js) because consumers expect `T | undefined`, not - // `T | null`. To match, we delete any properties still set to `null` - // after YAML parsing so that accessing them returns `undefined`. - // Runs after normalizeYamlNulls, which has already converted type-tag - // nulls (e.g. `console:`) to `{}`. - stripNulls(processed); - applyConfigDefaults(data); mergeAttributesList(data); mergeCompositeList(data); @@ -237,113 +226,6 @@ function applyConfigDefaults(data: ConfigurationModel): void { } } -/** - * Recursively delete object properties whose value is `null`. - * - * YAML `key:` (no value) parses to `{ key: null }`. The generated TypeScript - * types use `?: T` (not `T | null`) because downstream consumers like sdk-node - * assign config values to interfaces that only accept `T | undefined`. The - * codegen script (generate-config.js) strips `| null` from type unions; this - * function makes the runtime data match by deleting null-valued keys so that - * property access returns `undefined` instead of `null`. - * - * Must run AFTER normalizeYamlNulls, which converts type-tag nulls - * (e.g. `console: null` → `console: {}`) — those are already `{}` by the - * time this function runs and won't be affected. - */ -function stripNulls(value: unknown): void { - if (value == null || typeof value !== 'object') return; - if (Array.isArray(value)) { - for (const item of value) { - stripNulls(item); - } - } else { - for (const [key, val] of Object.entries(value as Record)) { - if (val === null) { - delete (value as Record)[key]; - } else { - stripNulls(val); - } - } - } -} - -/** - * Object type-tag keys that may appear as nested (non-array-element) properties. - * YAML `console:` (no value) parses to `{ console: null }`, but the SDK checks - * `if (exporter.console)` — truthy — so null must become {}. - * - * We exclude keys that are also used as nullable primitives in other contexts - * (e.g. `host` is a string field in prometheus config; detectors use it as a - * type-tag but only as array elements, which are already handled below). - */ -const NESTED_OBJECT_TYPE_TAGS = new Set([ - // Exporter type discriminators (nested inside simple/batch processor or reader) - 'console', - 'otlp_http', - 'otlp_grpc', - // Sampler type discriminators (nested inside tracer_provider.sampler) - 'always_on', - 'always_off', - 'trace_id_ratio_based', - 'parent_based', - 'jaeger_remote', - // Propagator type discriminators (array elements, but covered here for completeness) - 'tracecontext', - 'baggage', - 'b3', - 'b3multi', - 'xray', - // Telemetry producer type discriminators - 'opencensus', -]); - -/** - * Normalizes YAML null values to empty objects for discriminated-union type-tag fields. - * - * YAML `key:` (no value) parses to `{ key: null }`, but the SDK checks `if (obj.key)` - * to determine which type to instantiate — null fails that check. Two cases: - * - * 1. Array element properties: convert ALL null-valued keys to {} (handles detectors, - * composite propagators, and most exporter/processor discriminators). - * 2. Nested NESTED_OBJECT_TYPE_TAGS: convert known type-discriminator keys to {} when - * encountered anywhere in the tree (handles sampler types, console exporter nested - * inside simple/batch, etc.). - * - * Top-level nullable primitive fields (disabled, log_level, endpoint, ca_file, etc.) - * are NOT in NESTED_OBJECT_TYPE_TAGS and are left as-is; applyConfigDefaults() - * handles the boolean/string ones that need defaults. - */ -function normalizeYamlNulls(value: unknown): void { - if (value == null || typeof value !== 'object') return; - if (Array.isArray(value)) { - for (const item of value) { - if (item != null && typeof item === 'object' && !Array.isArray(item)) { - // All null-valued properties of array elements are type-tag discriminators. - for (const key of Object.keys(item as object)) { - if ((item as Record)[key] === null) { - (item as Record)[key] = {}; - } - } - } - normalizeYamlNulls(item); - } - } else { - for (const [key, val] of Object.entries(value as Record)) { - if ( - val === null && - // Known type-tag keys, or slash-qualified experimental type-tags - // (e.g. otlp_file/development, prometheus/development) - (NESTED_OBJECT_TYPE_TAGS.has(key) || key.includes('/')) - ) { - (value as Record)[key] = {}; - } else { - normalizeYamlNulls(val); - } - } - } -} - const ENV_VAR_PATTERN = /\$\{[^}]+\}/; function substituteEnvVars(obj: unknown): unknown { diff --git a/experimental/packages/configuration/src/generated/types.ts b/experimental/packages/configuration/src/generated/types.ts index 5e9ca8820bd..f490b038abd 100644 --- a/experimental/packages/configuration/src/generated/types.ts +++ b/experimental/packages/configuration/src/generated/types.ts @@ -39,30 +39,98 @@ * If omitted, INFO is used. */ export type SeverityNumber = - | 'trace' - | 'trace2' - | 'trace3' - | 'trace4' - | 'debug' - | 'debug2' - | 'debug3' - | 'debug4' - | 'info' - | 'info2' - | 'info3' - | 'info4' - | 'warn' - | 'warn2' - | 'warn3' - | 'warn4' - | 'error' - | 'error2' - | 'error3' - | 'error4' - | 'fatal' - | 'fatal2' - | 'fatal3' - | 'fatal4'; + | ( + | 'trace' + | 'trace2' + | 'trace3' + | 'trace4' + | 'debug' + | 'debug2' + | 'debug3' + | 'debug4' + | 'info' + | 'info2' + | 'info3' + | 'info4' + | 'warn' + | 'warn2' + | 'warn3' + | 'warn4' + | 'error' + | 'error2' + | 'error3' + | 'error4' + | 'fatal' + | 'fatal2' + | 'fatal3' + | 'fatal4' + ) + | null; + +/** + * Configure exporter to be OTLP with HTTP transport. + * If omitted, ignore. + */ +export type OtlpHttpExporter = { + /** + * Configure endpoint, including the signal specific path. + * If omitted or null, the http://localhost:4318/v1/{signal} (where signal is 'traces', 'logs', or 'metrics') is used. + */ + endpoint?: string | null; + tls?: HttpTls; + /** + * Configure headers. Entries have higher priority than entries from .headers_list. + * If an entry's .value is null, the entry is ignored. + * If omitted, no headers are added. + * + * @minItems 1 + */ + headers?: NameStringValuePair[]; + /** + * 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. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details. + * If omitted or null, no headers are added. + */ + headers_list?: string | null; + /** + * Configure compression. + * Known values include: gzip, none. Implementations may support other compression algorithms. + * If omitted or null, none is used. + */ + compression?: string | null; + /** + * 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 | null; + encoding?: OtlpHttpEncoding; +} | null; + +/** + * Configure TLS settings for the exporter. + * If omitted, system default TLS settings are used. + */ +export type HttpTls = { + /** + * 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. + */ + ca_file?: string | null; + /** + * 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. + */ + key_file?: string | null; + /** + * 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. + */ + cert_file?: string | null; +} | null; /** * Configure the encoding used for messages. @@ -72,7 +140,138 @@ export type SeverityNumber = * * protobuf: Protobuf binary encoding. * If omitted, protobuf is used. */ -export type OtlpHttpEncoding = 'protobuf' | 'json'; +export type OtlpHttpEncoding = ('protobuf' | 'json') | null; + +/** + * Configure exporter to be OTLP with gRPC transport. + * If omitted, ignore. + */ +export type OtlpGrpcExporter = { + /** + * Configure endpoint. + * If omitted or null, http://localhost:4317 is used. + */ + endpoint?: string | null; + tls?: GrpcTls; + /** + * Configure headers. Entries have higher priority than entries from .headers_list. + * If an entry's .value is null, the entry is ignored. + * If omitted, no headers are added. + * + * @minItems 1 + */ + headers?: NameStringValuePair[]; + /** + * 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. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details. + * If omitted or null, no headers are added. + */ + headers_list?: string | null; + /** + * Configure compression. + * Known values include: gzip, none. Implementations may support other compression algorithms. + * If omitted or null, none is used. + */ + compression?: string | null; + /** + * 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 | null; +} | null; + +/** + * Configure TLS settings for the exporter. + * If omitted, system default TLS settings are used. + */ +export type GrpcTls = { + /** + * 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. + */ + ca_file?: string | null; + /** + * 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. + */ + key_file?: string | null; + /** + * 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. + */ + cert_file?: string | null; + /** + * Configure client transport security for the exporter's connection. + * Only applicable when .endpoint is provided without http or https scheme. Implementations may choose to ignore .insecure. + * If omitted or null, false is used. + */ + insecure?: boolean | null; +} | null; + +/** + * Configure exporter to be OTLP with file transport. + * If omitted, ignore. + */ +export type ExperimentalOtlpFileExporter = { + /** + * Configure output stream. + * Values include stdout, or scheme+destination. For example: file:///path/to/file.jsonl. + * If omitted or null, stdout is used. + */ + output_stream?: string | null; +} | null; + +/** + * Configure exporter to be console. + * If omitted, ignore. + */ +export type ConsoleExporter = {} | null; + +/** + * Configure exporter to be OTLP with HTTP transport. + * If omitted, ignore. + */ +export type OtlpHttpMetricExporter = { + /** + * Configure endpoint. + * If omitted or null, http://localhost:4318/v1/metrics is used. + */ + endpoint?: string | null; + tls?: HttpTls; + /** + * Configure headers. Entries have higher priority than entries from .headers_list. + * If an entry's .value is null, the entry is ignored. + * If omitted, no headers are added. + * + * @minItems 1 + */ + headers?: NameStringValuePair[]; + /** + * 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. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details. + * If omitted or null, no headers are added. + */ + headers_list?: string | null; + /** + * Configure compression. + * Known values include: gzip, none. Implementations may support other compression algorithms. + * If omitted or null, none is used. + */ + compression?: string | null; + /** + * 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 | null; + encoding?: OtlpHttpEncoding; + temporality_preference?: ExporterTemporalityPreference; + default_histogram_aggregation?: ExporterDefaultHistogramAggregation; +} | null; /** * Configure temporality preference. @@ -83,9 +282,8 @@ export type OtlpHttpEncoding = 'protobuf' | 'json'; * If omitted, cumulative is used. */ export type ExporterTemporalityPreference = - | 'cumulative' - | 'delta' - | 'low_memory'; + | ('cumulative' | 'delta' | 'low_memory') + | null; /** * Configure default histogram aggregation. @@ -95,8 +293,108 @@ export type ExporterTemporalityPreference = * If omitted, explicit_bucket_histogram is used. */ export type ExporterDefaultHistogramAggregation = - | 'explicit_bucket_histogram' - | 'base2_exponential_bucket_histogram'; + | ('explicit_bucket_histogram' | 'base2_exponential_bucket_histogram') + | null; + +/** + * Configure exporter to be OTLP with gRPC transport. + * If omitted, ignore. + */ +export type OtlpGrpcMetricExporter = { + /** + * Configure endpoint. + * If omitted or null, http://localhost:4317 is used. + */ + endpoint?: string | null; + tls?: GrpcTls; + /** + * Configure headers. Entries have higher priority than entries from .headers_list. + * If an entry's .value is null, the entry is ignored. + * If omitted, no headers are added. + * + * @minItems 1 + */ + headers?: NameStringValuePair[]; + /** + * 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. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details. + * If omitted or null, no headers are added. + */ + headers_list?: string | null; + /** + * Configure compression. + * Known values include: gzip, none. Implementations may support other compression algorithms. + * If omitted or null, none is used. + */ + compression?: string | null; + /** + * 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 | null; + temporality_preference?: ExporterTemporalityPreference; + default_histogram_aggregation?: ExporterDefaultHistogramAggregation; +} | null; + +/** + * Configure exporter to be OTLP with file transport. + * If omitted, ignore. + */ +export type ExperimentalOtlpFileMetricExporter = { + /** + * Configure output stream. + * Values include stdout, or scheme+destination. For example: file:///path/to/file.jsonl. + * If omitted or null, stdout is used. + */ + output_stream?: string | null; + temporality_preference?: ExporterTemporalityPreference; + default_histogram_aggregation?: ExporterDefaultHistogramAggregation; +} | null; + +/** + * Configure exporter to be console. + * If omitted, ignore. + */ +export type ConsoleMetricExporter = { + temporality_preference?: ExporterTemporalityPreference; + default_histogram_aggregation?: ExporterDefaultHistogramAggregation; +} | null; + +/** + * Configure metric producer to be opencensus. + * If omitted, ignore. + */ +export type OpenCensusMetricProducer = {} | null; + +/** + * Configure exporter to be prometheus. + * If omitted, ignore. + */ +export type ExperimentalPrometheusMetricExporter = { + /** + * Configure host. + * If omitted or null, localhost is used. + */ + host?: string | null; + /** + * Configure port. + * If omitted or null, 9464 is used. + */ + port?: number | null; + /** + * Configure Prometheus Exporter to produce metrics without scope labels. + * If omitted or null, false is used. + */ + without_scope_info?: boolean | null; + /** + * Configure Prometheus Exporter to produce metrics without a target info metric for the resource. + * If omitted or null, false is used. + */ + 'without_target_info/development'?: boolean | null; + with_resource_constant_labels?: IncludeExclude; + translation_strategy?: ExperimentalPrometheusTranslationStrategy; +} | null; /** * Configure how metric names are translated to Prometheus metric names. @@ -108,10 +406,13 @@ export type ExporterDefaultHistogramAggregation = * If omitted, underscore_escaping_with_suffixes is used. */ export type ExperimentalPrometheusTranslationStrategy = - | 'underscore_escaping_with_suffixes' - | 'underscore_escaping_without_suffixes/development' - | 'no_utf8_escaping_with_suffixes/development' - | 'no_translation/development'; + | ( + | 'underscore_escaping_with_suffixes' + | 'underscore_escaping_without_suffixes/development' + | 'no_utf8_escaping_with_suffixes/development' + | 'no_translation/development' + ) + | null; /** * Configure instrument type selection criteria. @@ -126,13 +427,81 @@ export type ExperimentalPrometheusTranslationStrategy = * If omitted, all instrument types match. */ export type InstrumentType = - | 'counter' - | 'gauge' - | 'histogram' - | 'observable_counter' - | 'observable_gauge' - | 'observable_up_down_counter' - | 'up_down_counter'; + | ( + | 'counter' + | 'gauge' + | 'histogram' + | 'observable_counter' + | 'observable_gauge' + | 'observable_up_down_counter' + | 'up_down_counter' + ) + | null; + +/** + * Configures the stream to use the instrument kind to select an aggregation and advisory parameters to influence aggregation configuration parameters. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#default-aggregation for details. + * If omitted, ignore. + */ +export type DefaultAggregation = {} | null; + +/** + * Configures the stream to ignore/drop all instrument measurements. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#drop-aggregation for details. + * If omitted, ignore. + */ +export type DropAggregation = {} | null; + +/** + * Configures the stream to collect data for the histogram metric point using a set of explicit boundary values for histogram bucketing. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#explicit-bucket-histogram-aggregation for details + * If omitted, ignore. + */ +export type ExplicitBucketHistogramAggregation = { + /** + * Configure bucket boundaries. + * If omitted, [0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000] is used. + * + * @minItems 0 + */ + boundaries?: number[]; + /** + * Configure record min and max. + * If omitted or null, true is used. + */ + record_min_max?: boolean | null; +} | null; + +/** + * Configures the stream to collect data for the exponential histogram metric point, which uses a base-2 exponential formula to determine bucket boundaries and an integer scale parameter to control resolution. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#base2-exponential-bucket-histogram-aggregation for details. + * If omitted, ignore. + */ +export type Base2ExponentialBucketHistogramAggregation = { + /** + * Configure the max scale factor. + * If omitted or null, 20 is used. + */ + max_scale?: number | null; + /** + * Configure the maximum number of buckets in each of the positive and negative ranges, not counting the special zero bucket. + * If omitted or null, 160 is used. + */ + max_size?: number | null; + /** + * Configure whether or not to record min and max. + * If omitted or null, true is used. + */ + record_min_max?: boolean | null; +} | null; + +/** + * Configures the stream to collect data using the last measurement. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#last-value-aggregation for details. + * If omitted, ignore. + */ +export type LastValueAggregation = {} | null; + +/** + * Configures the stream to collect the arithmetic sum of measurement values. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#sum-aggregation for details. + * If omitted, ignore. + */ +export type SumAggregation = {} | null; /** * Configure the exemplar filter. @@ -142,16 +511,146 @@ export type InstrumentType = * * trace_based: ExemplarFilter which makes measurements recorded in the context of a sampled parent span eligible for being an Exemplar. * If omitted, trace_based is used. */ -export type ExemplarFilter = 'always_on' | 'always_off' | 'trace_based'; +export type ExemplarFilter = + | ('always_on' | 'always_off' | 'trace_based') + | null; + +/** + * Include the w3c trace context propagator. + * If omitted, ignore. + */ +export type TraceContextPropagator = {} | null; + +/** + * Include the w3c baggage propagator. + * If omitted, ignore. + */ +export type BaggagePropagator = {} | null; + +/** + * Include the zipkin b3 propagator. + * If omitted, ignore. + */ +export type B3Propagator = {} | null; + +/** + * Include the zipkin b3 multi propagator. + * If omitted, ignore. + */ +export type B3MultiPropagator = {} | null; + +/** + * Configure sampler to be always_off. + * If omitted, ignore. + */ +export type AlwaysOffSampler = {} | null; + +/** + * Configure sampler to be always_on. + * If omitted, ignore. + */ +export type AlwaysOnSampler = {} | null; + +/** + * Configure sampler to be always_off. + * If omitted, ignore. + */ +export type ExperimentalComposableAlwaysOffSampler = {} | null; + +/** + * Configure sampler to be always_on. + * If omitted, ignore. + */ +export type ExperimentalComposableAlwaysOnSampler = {} | null; + +/** + * Configure sampler to be probability. + * If omitted, ignore. + */ +export type ExperimentalComposableProbabilitySampler = { + /** + * Configure ratio. + * If omitted or null, 1.0 is used. + */ + ratio?: number | null; +} | null; + +/** + * Configure sampler to be rule_based. + * If omitted, ignore. + */ +export type ExperimentalComposableRuleBasedSampler = { + /** + * The rules for the sampler, matched in order. + * Each rule can have multiple match conditions. All conditions must match for the rule to match. + * If no conditions are specified, the rule matches all spans that reach it. + * If no rules match, the span is not sampled. + * If omitted, no span is sampled. + * + * @minItems 1 + */ + rules?: ExperimentalComposableRuleBasedSamplerRule[]; +} | null; export type SpanKind = - | 'internal' - | 'server' - | 'client' - | 'producer' - | 'consumer'; + | ('internal' | 'server' | 'client' | 'producer' | 'consumer') + | null; + +export type ExperimentalSpanParent = ('none' | 'remote' | 'local') | null; + +/** + * Configure sampler to be jaeger_remote. + * If omitted, ignore. + */ +export type ExperimentalJaegerRemoteSampler = { + /** + * Configure the endpoint of the jaeger remote sampling service. + * Property is required and must be non-null. + */ + endpoint: string; + /** + * Configure the polling interval (in milliseconds) to fetch from the remote sampling service. + * If omitted or null, 60000 is used. + */ + interval?: number | null; + initial_sampler: Sampler; +} | null; + +/** + * Configure sampler to be parent_based. + * If omitted, ignore. + */ +export type ParentBasedSampler = { + root?: Sampler; + remote_parent_sampled?: Sampler; + remote_parent_not_sampled?: Sampler; + local_parent_sampled?: Sampler; + local_parent_not_sampled?: Sampler; +} | null; + +/** + * Configure sampler to be probability. + * If omitted, ignore. + */ +export type ExperimentalProbabilitySampler = { + /** + * Configure ratio. + * If omitted or null, 1.0 is used. + */ + ratio?: number | null; +} | null; -export type ExperimentalSpanParent = 'none' | 'remote' | 'local'; +/** + * Configure sampler to be trace_id_ratio_based. + * If omitted, ignore. + */ +export type TraceIdRatioBasedSampler = { + /** + * Configure trace_id_ratio. + * If omitted or null, 1.0 is used. + */ + ratio?: number | null; +} | null; /** * The attribute type. @@ -166,15 +665,42 @@ export type ExperimentalSpanParent = 'none' | 'remote' | 'local'; * * string_array: String array attribute value. * If omitted, string is used. */ -export type AttributeType = - | 'string' - | 'bool' - | 'int' - | 'double' - | 'string_array' - | 'bool_array' - | 'int_array' - | 'double_array'; +export type AttributeType = + | ( + | 'string' + | 'bool' + | 'int' + | 'double' + | 'string_array' + | 'bool_array' + | 'int_array' + | 'double_array' + ) + | null; + +/** + * Enable the container resource detector, which populates container.* attributes. + * If omitted, ignore. + */ +export type ExperimentalContainerResourceDetector = {} | null; + +/** + * Enable the host resource detector, which populates host.* and os.* attributes. + * If omitted, ignore. + */ +export type ExperimentalHostResourceDetector = {} | null; + +/** + * Enable the process resource detector, which populates process.* attributes. + * If omitted, ignore. + */ +export type ExperimentalProcessResourceDetector = {} | null; + +/** + * Enable the service detector, which populates service.name based on the OTEL_SERVICE_NAME environment variable and service.instance.id. + * If omitted, ignore. + */ +export type ExperimentalServiceResourceDetector = {} | null; export interface ConfigurationModel { /** @@ -189,7 +715,7 @@ export interface ConfigurationModel { * Configure if the SDK is disabled or not. * If omitted or null, false is used. */ - disabled?: boolean; + disabled?: boolean | null; log_level?: SeverityNumber; attribute_limits?: AttributeLimits; logger_provider?: LoggerProvider; @@ -212,13 +738,13 @@ export interface AttributeLimits { * Value must be non-negative. * If omitted or null, there is no limit. */ - attribute_value_length_limit?: number; + attribute_value_length_limit?: number | null; /** * Configure max attribute count. * Value must be non-negative. * If omitted or null, 128 is used. */ - attribute_count_limit?: number; + attribute_count_limit?: number | null; } /** @@ -240,7 +766,7 @@ export interface LoggerProvider { export interface LogRecordProcessor { batch?: BatchLogRecordProcessor; simple?: SimpleLogRecordProcessor; - [k: string]: object | undefined; + [k: string]: object | null | undefined; } /** @@ -253,23 +779,23 @@ export interface BatchLogRecordProcessor { * Value must be non-negative. * If omitted or null, 1000 is used. */ - schedule_delay?: number; + schedule_delay?: number | null; /** * 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; + export_timeout?: number | null; /** * Configure maximum queue size. Value must be positive. * If omitted or null, 2048 is used. */ - max_queue_size?: number; + max_queue_size?: number | null; /** * Configure maximum batch size. Value must be positive. * If omitted or null, 512 is used. */ - max_export_batch_size?: number; + max_export_batch_size?: number | null; exporter: LogRecordExporter; } @@ -282,72 +808,7 @@ export interface LogRecordExporter { otlp_grpc?: OtlpGrpcExporter; 'otlp_file/development'?: ExperimentalOtlpFileExporter; console?: ConsoleExporter; - [k: string]: object | undefined; -} - -/** - * Configure exporter to be OTLP with HTTP transport. - * If omitted, ignore. - */ -export interface OtlpHttpExporter { - /** - * Configure endpoint, including the signal specific path. - * If omitted or null, the http://localhost:4318/v1/{signal} (where signal is 'traces', 'logs', or 'metrics') is used. - */ - endpoint?: string; - tls?: HttpTls; - /** - * Configure headers. Entries have higher priority than entries from .headers_list. - * If an entry's .value is null, the entry is ignored. - * If omitted, no headers are added. - * - * @minItems 1 - */ - headers?: NameStringValuePair[]; - /** - * 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. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details. - * If omitted or null, no headers are added. - */ - headers_list?: string; - /** - * Configure compression. - * Known 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; - encoding?: OtlpHttpEncoding; -} - -/** - * Configure TLS settings for the exporter. - * If omitted, system default TLS settings are used. - */ -export interface HttpTls { - /** - * 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. - */ - ca_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. - */ - 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. - */ - cert_file?: string; + [k: string]: object | null | undefined; } export interface NameStringValuePair { @@ -360,98 +821,9 @@ export interface NameStringValuePair { * The value of the pair. * Property must be present, but if null the behavior is dependent on usage context. */ - value: string; -} - -/** - * Configure exporter to be OTLP with gRPC transport. - * If omitted, ignore. - */ -export interface OtlpGrpcExporter { - /** - * Configure endpoint. - * If omitted or null, http://localhost:4317 is used. - */ - endpoint?: string; - tls?: GrpcTls; - /** - * Configure headers. Entries have higher priority than entries from .headers_list. - * If an entry's .value is null, the entry is ignored. - * If omitted, no headers are added. - * - * @minItems 1 - */ - headers?: NameStringValuePair[]; - /** - * 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. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details. - * If omitted or null, no headers are added. - */ - headers_list?: string; - /** - * Configure compression. - * Known 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 TLS settings for the exporter. - * If omitted, system default TLS settings are used. - */ -export interface GrpcTls { - /** - * 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. - */ - ca_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. - */ - 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. - */ - cert_file?: string; - /** - * Configure client transport security for the exporter's connection. - * Only applicable when .endpoint is provided without http or https scheme. Implementations may choose to ignore .insecure. - * If omitted or null, false is used. - */ - insecure?: boolean; -} - -/** - * Configure exporter to be OTLP with file transport. - * If omitted, ignore. - */ -export interface ExperimentalOtlpFileExporter { - /** - * Configure output stream. - * Values include stdout, or scheme+destination. For example: file:///path/to/file.jsonl. - * If omitted or null, stdout is used. - */ - output_stream?: string; + value: string | null; } -/** - * Configure exporter to be console. - * If omitted, ignore. - */ -export interface ConsoleExporter {} - /** * Configure a simple log record processor. * If omitted, ignore. @@ -470,13 +842,13 @@ export interface LogRecordLimits { * Value must be non-negative. * If omitted or null, there is no limit. */ - attribute_value_length_limit?: number; + attribute_value_length_limit?: number | null; /** * 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; + attribute_count_limit?: number | null; } /** @@ -503,14 +875,14 @@ export interface ExperimentalLoggerConfig { * Configure if the logger is enabled or not. * If omitted or null, true is used. */ - enabled?: boolean; + enabled?: boolean | null; minimum_severity?: SeverityNumber; /** * Configure trace based filtering. * If true, log records associated with unsampled trace contexts traces are not processed. If false, or if a log record is not associated with a trace context, trace based filtering is not applied. * If omitted or null, trace based filtering is not applied. */ - trace_based?: boolean; + trace_based?: boolean | null; } export interface ExperimentalLoggerMatcherAndConfig { @@ -549,169 +921,56 @@ export interface MeterProvider { 'meter_configurator/development'?: ExperimentalMeterConfigurator; } -export interface MetricReader { - periodic?: PeriodicMetricReader; - pull?: PullMetricReader; -} - -/** - * Configure a periodic metric reader. - * If omitted, ignore. - */ -export interface PeriodicMetricReader { - /** - * 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; - exporter: PushMetricExporter; - /** - * Configure metric producers. - * If omitted, no metric producers are added. - * - * @minItems 1 - */ - producers?: MetricProducer[]; - cardinality_limits?: CardinalityLimits; -} - -/** - * Configure exporter. - * Property is required and must be non-null. - */ -export interface PushMetricExporter { - otlp_http?: OtlpHttpMetricExporter; - otlp_grpc?: OtlpGrpcMetricExporter; - 'otlp_file/development'?: ExperimentalOtlpFileMetricExporter; - console?: ConsoleMetricExporter; - [k: string]: object | undefined; -} - -/** - * Configure exporter to be OTLP with HTTP transport. - * If omitted, ignore. - */ -export interface OtlpHttpMetricExporter { - /** - * Configure endpoint. - * If omitted or null, http://localhost:4318/v1/metrics is used. - */ - endpoint?: string; - tls?: HttpTls; - /** - * Configure headers. Entries have higher priority than entries from .headers_list. - * If an entry's .value is null, the entry is ignored. - * If omitted, no headers are added. - * - * @minItems 1 - */ - headers?: NameStringValuePair[]; - /** - * 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. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details. - * If omitted or null, no headers are added. - */ - headers_list?: string; - /** - * Configure compression. - * Known 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; - encoding?: OtlpHttpEncoding; - temporality_preference?: ExporterTemporalityPreference; - default_histogram_aggregation?: ExporterDefaultHistogramAggregation; -} - -/** - * Configure exporter to be OTLP with gRPC transport. - * If omitted, ignore. - */ -export interface OtlpGrpcMetricExporter { - /** - * Configure endpoint. - * If omitted or null, http://localhost:4317 is used. - */ - endpoint?: string; - tls?: GrpcTls; - /** - * Configure headers. Entries have higher priority than entries from .headers_list. - * If an entry's .value is null, the entry is ignored. - * If omitted, no headers are added. - * - * @minItems 1 - */ - headers?: NameStringValuePair[]; - /** - * 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. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details. - * If omitted or null, no headers are added. - */ - headers_list?: string; - /** - * Configure compression. - * Known 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; - temporality_preference?: ExporterTemporalityPreference; - default_histogram_aggregation?: ExporterDefaultHistogramAggregation; +export interface MetricReader { + periodic?: PeriodicMetricReader; + pull?: PullMetricReader; } /** - * Configure exporter to be OTLP with file transport. + * Configure a periodic metric reader. * If omitted, ignore. */ -export interface ExperimentalOtlpFileMetricExporter { +export interface PeriodicMetricReader { /** - * Configure output stream. - * Values include stdout, or scheme+destination. For example: file:///path/to/file.jsonl. - * If omitted or null, stdout is used. + * Configure delay interval (in milliseconds) between start of two consecutive exports. + * Value must be non-negative. + * If omitted or null, 60000 is used. */ - output_stream?: string; - temporality_preference?: ExporterTemporalityPreference; - default_histogram_aggregation?: ExporterDefaultHistogramAggregation; + interval?: number | null; + /** + * 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 | null; + exporter: PushMetricExporter; + /** + * Configure metric producers. + * If omitted, no metric producers are added. + * + * @minItems 1 + */ + producers?: MetricProducer[]; + cardinality_limits?: CardinalityLimits; } /** - * Configure exporter to be console. - * If omitted, ignore. + * Configure exporter. + * Property is required and must be non-null. */ -export interface ConsoleMetricExporter { - temporality_preference?: ExporterTemporalityPreference; - default_histogram_aggregation?: ExporterDefaultHistogramAggregation; +export interface PushMetricExporter { + otlp_http?: OtlpHttpMetricExporter; + otlp_grpc?: OtlpGrpcMetricExporter; + 'otlp_file/development'?: ExperimentalOtlpFileMetricExporter; + console?: ConsoleMetricExporter; + [k: string]: object | null | undefined; } export interface MetricProducer { opencensus?: OpenCensusMetricProducer; - [k: string]: object | undefined; + [k: string]: object | null | undefined; } -/** - * Configure metric producer to be opencensus. - * If omitted, ignore. - */ -export interface OpenCensusMetricProducer {} - /** * Configure cardinality limits. * If omitted, default values as described in CardinalityLimits are used. @@ -722,42 +981,42 @@ export interface CardinalityLimits { * Instrument-specific cardinality limits take priority. * If omitted or null, 2000 is used. */ - default?: number; + default?: number | null; /** * Configure default cardinality limit for counter instruments. * If omitted or null, the value from .default is used. */ - counter?: number; + counter?: number | null; /** * Configure default cardinality limit for gauge instruments. * If omitted or null, the value from .default is used. */ - gauge?: number; + gauge?: number | null; /** * Configure default cardinality limit for histogram instruments. * If omitted or null, the value from .default is used. */ - histogram?: number; + histogram?: number | null; /** * Configure default cardinality limit for observable_counter instruments. * If omitted or null, the value from .default is used. */ - observable_counter?: number; + observable_counter?: number | null; /** * Configure default cardinality limit for observable_gauge instruments. * If omitted or null, the value from .default is used. */ - observable_gauge?: number; + observable_gauge?: number | null; /** * Configure default cardinality limit for observable_up_down_counter instruments. * If omitted or null, the value from .default is used. */ - observable_up_down_counter?: number; + observable_up_down_counter?: number | null; /** * Configure default cardinality limit for up_down_counter instruments. * If omitted or null, the value from .default is used. */ - up_down_counter?: number; + up_down_counter?: number | null; } /** @@ -782,36 +1041,7 @@ export interface PullMetricReader { */ export interface PullMetricExporter { 'prometheus/development'?: ExperimentalPrometheusMetricExporter; - [k: string]: object | undefined; -} - -/** - * Configure exporter to be prometheus. - * If omitted, ignore. - */ -export interface ExperimentalPrometheusMetricExporter { - /** - * Configure host. - * If omitted or null, localhost is used. - */ - host?: string; - /** - * Configure port. - * If omitted or null, 9464 is used. - */ - port?: number; - /** - * Configure Prometheus Exporter to produce metrics without scope labels. - * If omitted or null, false is used. - */ - without_scope_info?: boolean; - /** - * Configure Prometheus Exporter to produce metrics without a target info metric for the resource. - * If omitted or null, false is used. - */ - 'without_target_info/development'?: boolean; - with_resource_constant_labels?: IncludeExclude; - translation_strategy?: ExperimentalPrometheusTranslationStrategy; + [k: string]: object | null | undefined; } /** @@ -856,28 +1086,28 @@ export interface ViewSelector { * Configure instrument name selection criteria. * If omitted or null, all instrument names match. */ - instrument_name?: string; + instrument_name?: string | null; instrument_type?: InstrumentType; /** * Configure the instrument unit selection criteria. * If omitted or null, all instrument units match. */ - unit?: string; + unit?: string | null; /** * Configure meter name selection criteria. * If omitted or null, all meter names match. */ - meter_name?: string; + meter_name?: string | null; /** * Configure meter version selection criteria. * If omitted or null, all meter versions match. */ - meter_version?: string; + meter_version?: string | null; /** * Configure meter schema url selection criteria. * If omitted or null, all meter schema URLs match. */ - meter_schema_url?: string; + meter_schema_url?: string | null; } /** @@ -889,18 +1119,18 @@ export interface ViewStream { * Configure metric name of the resulting stream(s). * If omitted or null, the instrument's original name is used. */ - name?: string; + name?: string | null; /** * Configure metric description of the resulting stream(s). * If omitted or null, the instrument's origin description is used. */ - description?: string; + description?: string | null; aggregation?: Aggregation; /** * Configure the aggregation cardinality limit. * If omitted or null, the metric reader's default cardinality limit is used. */ - aggregation_cardinality_limit?: number; + aggregation_cardinality_limit?: number | null; attribute_keys?: IncludeExclude; } @@ -917,71 +1147,6 @@ export interface Aggregation { sum?: SumAggregation; } -/** - * Configures the stream to use the instrument kind to select an aggregation and advisory parameters to influence aggregation configuration parameters. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#default-aggregation for details. - * If omitted, ignore. - */ -export interface DefaultAggregation {} - -/** - * Configures the stream to ignore/drop all instrument measurements. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#drop-aggregation for details. - * If omitted, ignore. - */ -export interface DropAggregation {} - -/** - * Configures the stream to collect data for the histogram metric point using a set of explicit boundary values for histogram bucketing. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#explicit-bucket-histogram-aggregation for details - * If omitted, ignore. - */ -export interface ExplicitBucketHistogramAggregation { - /** - * Configure bucket boundaries. - * If omitted, [0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000] is used. - * - * @minItems 0 - */ - boundaries?: number[]; - /** - * Configure record min and max. - * If omitted or null, true is used. - */ - record_min_max?: boolean; -} - -/** - * Configures the stream to collect data for the exponential histogram metric point, which uses a base-2 exponential formula to determine bucket boundaries and an integer scale parameter to control resolution. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#base2-exponential-bucket-histogram-aggregation for details. - * If omitted, ignore. - */ -export interface Base2ExponentialBucketHistogramAggregation { - /** - * Configure the max scale factor. - * If omitted or null, 20 is used. - */ - max_scale?: number; - /** - * Configure the maximum number of buckets in each of the positive and negative ranges, not counting the special zero bucket. - * If omitted or null, 160 is used. - */ - max_size?: number; - /** - * Configure whether or not to record min and max. - * If omitted or null, true is used. - */ - record_min_max?: boolean; -} - -/** - * Configures the stream to collect data using the last measurement. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#last-value-aggregation for details. - * If omitted, ignore. - */ -export interface LastValueAggregation {} - -/** - * Configures the stream to collect the arithmetic sum of measurement values. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#sum-aggregation for details. - * If omitted, ignore. - */ -export interface SumAggregation {} - /** * Configure meters. * If omitted, all meters use default values as described in ExperimentalMeterConfig. @@ -1040,7 +1205,7 @@ export interface Propagator { * Built-in propagator identifiers include: tracecontext, baggage, b3, b3multi. Known third party identifiers include: xray. * If omitted or null, and .composite is omitted or null, a noop propagator is used. */ - composite_list?: string; + composite_list?: string | null; } export interface TextMapPropagator { @@ -1048,33 +1213,9 @@ export interface TextMapPropagator { baggage?: BaggagePropagator; b3?: B3Propagator; b3multi?: B3MultiPropagator; - [k: string]: object | undefined; + [k: string]: object | null | undefined; } -/** - * Include the w3c trace context propagator. - * If omitted, ignore. - */ -export interface TraceContextPropagator {} - -/** - * Include the w3c baggage propagator. - * If omitted, ignore. - */ -export interface BaggagePropagator {} - -/** - * Include the zipkin b3 propagator. - * If omitted, ignore. - */ -export interface B3Propagator {} - -/** - * Include the zipkin b3 multi propagator. - * If omitted, ignore. - */ -export interface B3MultiPropagator {} - /** * Configure tracer provider. * If omitted, a noop tracer provider is used. @@ -1095,7 +1236,7 @@ export interface TracerProvider { export interface SpanProcessor { batch?: BatchSpanProcessor; simple?: SimpleSpanProcessor; - [k: string]: object | undefined; + [k: string]: object | null | undefined; } /** @@ -1108,23 +1249,23 @@ export interface BatchSpanProcessor { * Value must be non-negative. * If omitted or null, 5000 is used. */ - schedule_delay?: number; + schedule_delay?: number | null; /** * 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; + export_timeout?: number | null; /** * Configure maximum queue size. Value must be positive. * If omitted or null, 2048 is used. */ - max_queue_size?: number; + max_queue_size?: number | null; /** * Configure maximum batch size. Value must be positive. * If omitted or null, 512 is used. */ - max_export_batch_size?: number; + max_export_batch_size?: number | null; exporter: SpanExporter; } @@ -1137,7 +1278,7 @@ export interface SpanExporter { otlp_grpc?: OtlpGrpcExporter; 'otlp_file/development'?: ExperimentalOtlpFileExporter; console?: ConsoleExporter; - [k: string]: object | undefined; + [k: string]: object | null | undefined; } /** @@ -1158,37 +1299,37 @@ export interface SpanLimits { * Value must be non-negative. * If omitted or null, there is no limit. */ - attribute_value_length_limit?: number; + attribute_value_length_limit?: number | null; /** * 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; + attribute_count_limit?: number | null; /** * Configure max span event count. * Value must be non-negative. * If omitted or null, 128 is used. */ - event_count_limit?: number; + event_count_limit?: number | null; /** * Configure max span link count. * Value must be non-negative. * If omitted or null, 128 is used. */ - link_count_limit?: number; + link_count_limit?: number | null; /** * Configure max attributes per span event. * Value must be non-negative. * If omitted or null, 128 is used. */ - event_attribute_count_limit?: number; + event_attribute_count_limit?: number | null; /** * Configure max attributes per span link. * Value must be non-negative. * If omitted or null, 128 is used. */ - link_attribute_count_limit?: number; + link_attribute_count_limit?: number | null; } /** @@ -1203,21 +1344,9 @@ export interface Sampler { parent_based?: ParentBasedSampler; 'probability/development'?: ExperimentalProbabilitySampler; trace_id_ratio_based?: TraceIdRatioBasedSampler; - [k: string]: object | undefined; + [k: string]: object | null | undefined; } -/** - * Configure sampler to be always_off. - * If omitted, ignore. - */ -export interface AlwaysOffSampler {} - -/** - * Configure sampler to be always_on. - * If omitted, ignore. - */ -export interface AlwaysOnSampler {} - /** * Configure sampler to be composite. * If omitted, ignore. @@ -1228,21 +1357,9 @@ export interface ExperimentalComposableSampler { parent_threshold?: ExperimentalComposableParentThresholdSampler; probability?: ExperimentalComposableProbabilitySampler; rule_based?: ExperimentalComposableRuleBasedSampler; - [k: string]: object | undefined; + [k: string]: object | null | undefined; } -/** - * Configure sampler to be always_off. - * If omitted, ignore. - */ -export interface ExperimentalComposableAlwaysOffSampler {} - -/** - * Configure sampler to be always_on. - * If omitted, ignore. - */ -export interface ExperimentalComposableAlwaysOnSampler {} - /** * Configure sampler to be parent_threshold. * If omitted, ignore. @@ -1251,35 +1368,6 @@ export interface ExperimentalComposableParentThresholdSampler { root: ExperimentalComposableSampler; } -/** - * Configure sampler to be probability. - * If omitted, ignore. - */ -export interface ExperimentalComposableProbabilitySampler { - /** - * Configure ratio. - * If omitted or null, 1.0 is used. - */ - ratio?: number; -} - -/** - * Configure sampler to be rule_based. - * If omitted, ignore. - */ -export interface ExperimentalComposableRuleBasedSampler { - /** - * The rules for the sampler, matched in order. - * Each rule can have multiple match conditions. All conditions must match for the rule to match. - * If no conditions are specified, the rule matches all spans that reach it. - * If no rules match, the span is not sampled. - * If omitted, no span is sampled. - * - * @minItems 1 - */ - rules?: ExperimentalComposableRuleBasedSamplerRule[]; -} - /** * A rule for ExperimentalComposableRuleBasedSampler. A rule can have multiple match conditions - the sampler will be applied if all match. * If no conditions are specified, the rule matches all spans that reach it. @@ -1369,60 +1457,6 @@ export interface ExperimentalComposableRuleBasedSamplerRuleAttributePatterns { excluded?: string[]; } -/** - * Configure sampler to be jaeger_remote. - * If omitted, ignore. - */ -export interface ExperimentalJaegerRemoteSampler { - /** - * Configure the endpoint of the jaeger remote sampling service. - * Property is required and must be non-null. - */ - endpoint: string; - /** - * Configure the polling interval (in milliseconds) to fetch from the remote sampling service. - * If omitted or null, 60000 is used. - */ - interval?: number; - initial_sampler: Sampler; -} - -/** - * Configure sampler to be parent_based. - * If omitted, ignore. - */ -export interface ParentBasedSampler { - root?: Sampler; - remote_parent_sampled?: Sampler; - remote_parent_not_sampled?: Sampler; - local_parent_sampled?: Sampler; - local_parent_not_sampled?: Sampler; -} - -/** - * Configure sampler to be probability. - * If omitted, ignore. - */ -export interface ExperimentalProbabilitySampler { - /** - * Configure ratio. - * If omitted or null, 1.0 is used. - */ - ratio?: number; -} - -/** - * Configure sampler to be trace_id_ratio_based. - * If omitted, ignore. - */ -export interface TraceIdRatioBasedSampler { - /** - * Configure trace_id_ratio. - * If omitted or null, 1.0 is used. - */ - ratio?: number; -} - /** * Configure tracers. * If omitted, all tracers use default values as described in ExperimentalTracerConfig. @@ -1479,13 +1513,13 @@ export interface Resource { * Configure resource schema URL. * If omitted or null, no schema URL is used. */ - schema_url?: string; + schema_url?: string | null; /** * Configure resource attributes. Entries have lower priority than entries from .resource.attributes. * The value is a list of comma separated key-value pairs matching the format of OTEL_RESOURCE_ATTRIBUTES. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#general-sdk-configuration for details. * If omitted or null, no resource attributes are added. */ - attributes_list?: string; + attributes_list?: string | null; } export interface AttributeNameValue { @@ -1499,7 +1533,7 @@ export interface AttributeNameValue { * The type of value must match .type. * Property is required and must be non-null. */ - value: string | number | boolean | string[] | boolean[] | number[]; + value: string | number | boolean | null | string[] | boolean[] | number[]; type?: AttributeType; } @@ -1524,33 +1558,9 @@ export interface ExperimentalResourceDetector { host?: ExperimentalHostResourceDetector; process?: ExperimentalProcessResourceDetector; service?: ExperimentalServiceResourceDetector; - [k: string]: object | undefined; + [k: string]: object | null | undefined; } -/** - * Enable the container resource detector, which populates container.* attributes. - * If omitted, ignore. - */ -export interface ExperimentalContainerResourceDetector {} - -/** - * Enable the host resource detector, which populates host.* and os.* attributes. - * If omitted, ignore. - */ -export interface ExperimentalHostResourceDetector {} - -/** - * Enable the process resource detector, which populates process.* attributes. - * If omitted, ignore. - */ -export interface ExperimentalProcessResourceDetector {} - -/** - * Enable the service detector, which populates service.name based on the OTEL_SERVICE_NAME environment variable and service.instance.id. - * If omitted, ignore. - */ -export interface ExperimentalServiceResourceDetector {} - /** * Configure instrumentation. * If omitted, instrumentation defaults are used. @@ -1613,7 +1623,7 @@ export interface ExperimentalGeneralInstrumentation { * - Messaging: https://opentelemetry.io/docs/specs/semconv/messaging/messaging-spans/ * If omitted or null, no opt-in is configured and instrumentations continue emitting their default semantic convention version. */ - stability_opt_in_list?: string; + stability_opt_in_list?: string | null; } /** @@ -1640,12 +1650,12 @@ export interface ExperimentalSemconvConfig { * The target semantic convention version for this domain (e.g., 1). * If omitted or null, the latest stable version is used, or if no stable version is available and .experimental is true then the latest experimental version is used. */ - version?: number; + version?: number | null; /** * Use latest experimental semantic conventions (before stable is available or to enable experimental features on top of stable conventions). * If omitted or null, false is used. */ - experimental?: boolean; + experimental?: boolean | null; /** * When true, also emit the previous major version alongside the target version. * For version=1, the previous version refers to the pre-stable conventions that the instrumentation emitted before the first stable semantic convention version was defined. @@ -1653,7 +1663,7 @@ export interface ExperimentalSemconvConfig { * Enables dual-emit for phased migration between versions. * If omitted or null, false is used. */ - dual_emit?: boolean; + dual_emit?: boolean | null; } /** diff --git a/experimental/packages/configuration/src/index.ts b/experimental/packages/configuration/src/index.ts index 0ddde3c3bf1..203f21192b1 100644 --- a/experimental/packages/configuration/src/index.ts +++ b/experimental/packages/configuration/src/index.ts @@ -16,6 +16,7 @@ export type { SpanProcessor as SpanProcessorConfigModel, NameStringValuePair as NameStringValuePairConfigModel, HttpTls as HttpTlsConfigModel, + GrpcTls as GrpcTlsConfigModel, SeverityNumber as SeverityNumberConfigModel, } from './generated/types'; export { createConfigFactory } from './ConfigFactory'; diff --git a/experimental/packages/configuration/test/ConfigFactory.test.ts b/experimental/packages/configuration/test/ConfigFactory.test.ts index cbb0faa7f54..9a0c71112c5 100644 --- a/experimental/packages/configuration/test/ConfigFactory.test.ts +++ b/experimental/packages/configuration/test/ConfigFactory.test.ts @@ -47,8 +47,6 @@ const defaultTracerProvider: NonNullable< }, }; -const tls = {}; - const configFromFile = { disabled: false, log_level: 'info', @@ -62,10 +60,11 @@ const configFromFile = { ], }, attribute_limits: { + attribute_value_length_limit: null, attribute_count_limit: 128, }, propagator: { - composite: [{ tracecontext: {} }, { baggage: {} }], + composite: [{ tracecontext: null }, { baggage: null }], }, tracer_provider: { processors: [ @@ -78,7 +77,11 @@ const configFromFile = { exporter: { otlp_http: { endpoint: 'http://localhost:4318/v1/traces', - tls, + tls: { + ca_file: null, + cert_file: null, + key_file: null, + }, timeout: 10000, compression: 'gzip', encoding: 'protobuf', @@ -88,6 +91,7 @@ const configFromFile = { }, ], limits: { + attribute_value_length_limit: null, attribute_count_limit: 128, event_count_limit: 128, link_count_limit: 128, @@ -96,11 +100,11 @@ const configFromFile = { }, 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: {} }, + root: { always_on: null }, + remote_parent_sampled: { always_on: null }, + remote_parent_not_sampled: { always_off: null }, + local_parent_sampled: { always_on: null }, + local_parent_not_sampled: { always_off: null }, }, }, }, @@ -113,7 +117,11 @@ const configFromFile = { exporter: { otlp_http: { endpoint: 'http://localhost:4318/v1/metrics', - tls, + tls: { + ca_file: null, + cert_file: null, + key_file: null, + }, compression: 'gzip', timeout: 10000, temporality_preference: 'cumulative', @@ -138,7 +146,11 @@ const configFromFile = { exporter: { otlp_http: { endpoint: 'http://localhost:4318/v1/logs', - tls, + tls: { + ca_file: null, + cert_file: null, + key_file: null, + }, timeout: 10000, compression: 'gzip', encoding: 'protobuf', @@ -148,6 +160,7 @@ const configFromFile = { }, ], limits: { + attribute_value_length_limit: null, attribute_count_limit: 128, }, }, @@ -203,12 +216,12 @@ const configFromKitchenSinkFile = { excluded: ['process.command_args'], }, detectors: [ - { container: {} }, - { env: {} }, - { host: {} }, - { os: {} }, - { process: {} }, - { service: {} }, + { container: null }, + { env: null }, + { host: null }, + { os: null }, + { process: null }, + { service: null }, ], }, schema_url: 'https://opentelemetry.io/schemas/1.16.0', @@ -220,12 +233,12 @@ const configFromKitchenSinkFile = { }, propagator: { composite: [ - { tracecontext: {} }, - { baggage: {} }, - { b3: {} }, - { b3multi: {} }, - { jaeger: {} }, - { ottrace: {} }, + { tracecontext: null }, + { baggage: null }, + { b3: null }, + { b3multi: null }, + { jaeger: null }, + { ottrace: null }, { xray: {} }, ], composite_list: 'tracecontext,baggage,b3,b3multi,jaeger,ottrace,xray', @@ -301,7 +314,7 @@ const configFromKitchenSinkFile = { }, }, { - simple: { exporter: { console: {} } }, + simple: { exporter: { console: null } }, }, ], limits: { @@ -314,8 +327,8 @@ const configFromKitchenSinkFile = { }, sampler: { parent_based: { - root: { always_on: {} }, - remote_parent_sampled: { always_on: {} }, + root: { always_on: null }, + remote_parent_sampled: { always_on: null }, remote_parent_not_sampled: { 'probability/development': { ratio: 0.01 }, }, @@ -328,7 +341,7 @@ const configFromKitchenSinkFile = { key: 'http.route', values: ['/healthz', '/livez'], }, - sampler: { always_off: {} }, + sampler: { always_off: null }, }, { attribute_patterns: { @@ -336,7 +349,7 @@ const configFromKitchenSinkFile = { included: ['/internal/*'], excluded: ['/internal/special/*'], }, - sampler: { always_on: {} }, + sampler: { always_on: null }, }, { parent: ['none'], @@ -350,7 +363,7 @@ const configFromKitchenSinkFile = { }, }, }, - local_parent_not_sampled: { always_off: {} }, + local_parent_not_sampled: { always_off: null }, }, }, }, @@ -363,7 +376,7 @@ const configFromKitchenSinkFile = { 'underscore_escaping_with_suffixes' ), }, - producers: [{ opencensus: {} }], + producers: [{ opencensus: null }], cardinality_limits: ksCardinality, }, }, @@ -374,7 +387,7 @@ const configFromKitchenSinkFile = { 'underscore_escaping_without_suffixes/development' ), }, - producers: [{ opencensus: {} }], + producers: [{ opencensus: null }], cardinality_limits: ksCardinality, }, }, @@ -385,7 +398,7 @@ const configFromKitchenSinkFile = { 'no_utf8_escaping_with_suffixes/development' ), }, - producers: [{ opencensus: {} }], + producers: [{ opencensus: null }], cardinality_limits: ksCardinality, }, }, @@ -396,7 +409,7 @@ const configFromKitchenSinkFile = { 'no_translation/development' ), }, - producers: [{ opencensus: {} }], + producers: [{ opencensus: null }], cardinality_limits: ksCardinality, }, }, @@ -422,7 +435,7 @@ const configFromKitchenSinkFile = { 'base2_exponential_bucket_histogram', }, }, - producers: [{ opencensus: {} }], + producers: [{ opencensus: null }], cardinality_limits: ksCardinality, }, }, @@ -596,7 +609,7 @@ const configFromKitchenSinkFile = { }, }, { - simple: { exporter: { console: {} } }, + simple: { exporter: { console: null } }, }, ], limits: { @@ -619,12 +632,11 @@ const configFromKitchenSinkFile = { }, }; -const nullTls = {}; - const defaultConfigFromFileWithEnvVariables: ConfigurationModel = { disabled: false, log_level: 'info', resource: { + attributes_list: null, attributes: [ { name: 'service.name', @@ -634,6 +646,7 @@ const defaultConfigFromFileWithEnvVariables: ConfigurationModel = { ], }, attribute_limits: { + attribute_value_length_limit: null, attribute_count_limit: 128, }, propagator: { @@ -653,14 +666,20 @@ const defaultConfigFromFileWithEnvVariables: ConfigurationModel = { endpoint: 'http://localhost:4318/v1/traces', timeout: 10000, compression: 'gzip', - tls: nullTls, encoding: 'protobuf', + headers_list: null, + tls: { + ca_file: null, + cert_file: null, + key_file: null, + }, }, }, }, }, ], limits: { + attribute_value_length_limit: null, attribute_count_limit: 128, event_count_limit: 128, link_count_limit: 128, @@ -669,11 +688,11 @@ const defaultConfigFromFileWithEnvVariables: ConfigurationModel = { }, 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: {} }, + root: { always_on: null }, + remote_parent_sampled: { always_on: null }, + remote_parent_not_sampled: { always_off: null }, + local_parent_sampled: { always_on: null }, + local_parent_not_sampled: { always_off: null }, }, }, }, @@ -690,7 +709,12 @@ const defaultConfigFromFileWithEnvVariables: ConfigurationModel = { timeout: 10000, temporality_preference: 'cumulative', default_histogram_aggregation: 'explicit_bucket_histogram', - tls: nullTls, + tls: { + ca_file: null, + cert_file: null, + key_file: null, + }, + headers_list: null, encoding: 'protobuf', }, }, @@ -713,7 +737,12 @@ const defaultConfigFromFileWithEnvVariables: ConfigurationModel = { endpoint: 'http://localhost:4318/v1/logs', timeout: 10000, compression: 'gzip', - tls: nullTls, + tls: { + ca_file: null, + cert_file: null, + key_file: null, + }, + headers_list: null, encoding: 'protobuf', }, }, @@ -721,6 +750,7 @@ const defaultConfigFromFileWithEnvVariables: ConfigurationModel = { }, ], limits: { + attribute_value_length_limit: null, attribute_count_limit: 128, }, }, @@ -2229,7 +2259,7 @@ describe('ConfigFactory', function () { 'composite/development': { rule_based: { rules: [ - { sampler: { always_on: {} } }, + { sampler: { always_on: null } }, { sampler: { probability: { ratio: 0.5 } } }, ], }, @@ -2251,7 +2281,7 @@ describe('ConfigFactory', function () { key: 'http.method', values: ['GET'], }, - sampler: { always_on: {} }, + sampler: { always_on: null }, }, ], }, @@ -2621,7 +2651,9 @@ describe('ConfigFactory', function () { attribute_limits: { attribute_count_limit: 128, }, - resource: {}, + resource: { + attributes_list: null, + }, propagator: { composite: [{ tracecontext: {} }], composite_list: 'tracecontext', @@ -2631,7 +2663,7 @@ describe('ConfigFactory', function () { { simple: { exporter: { - console: {}, + console: null, }, }, }, diff --git a/experimental/packages/configuration/test/fixtures/test-for-coverage.yaml b/experimental/packages/configuration/test/fixtures/test-for-coverage.yaml index a3f8ea2a6b2..314489549fe 100644 --- a/experimental/packages/configuration/test/fixtures/test-for-coverage.yaml +++ b/experimental/packages/configuration/test/fixtures/test-for-coverage.yaml @@ -14,4 +14,4 @@ logger_provider: config: enabled: false minimum_severity: info - trace_based: true \ No newline at end of file + trace_based: true diff --git a/experimental/packages/opentelemetry-sdk-node/src/start.ts b/experimental/packages/opentelemetry-sdk-node/src/start.ts index 9d6985a1fc7..deedd6f845e 100644 --- a/experimental/packages/opentelemetry-sdk-node/src/start.ts +++ b/experimental/packages/opentelemetry-sdk-node/src/start.ts @@ -167,8 +167,9 @@ function create( spanLimits, generalLimits: { attributeValueLengthLimit: - config.attribute_limits?.attribute_value_length_limit, - attributeCountLimit: config.attribute_limits?.attribute_count_limit, + config.attribute_limits?.attribute_value_length_limit ?? undefined, + attributeCountLimit: + config.attribute_limits?.attribute_count_limit ?? undefined, }, // TODO (6616): support idGenerator configuration from config // TODO (6624): support for `meterProvider: components.meterProvider` diff --git a/experimental/packages/opentelemetry-sdk-node/src/utils.ts b/experimental/packages/opentelemetry-sdk-node/src/utils.ts index 9bbe3ee3421..978f381f452 100644 --- a/experimental/packages/opentelemetry-sdk-node/src/utils.ts +++ b/experimental/packages/opentelemetry-sdk-node/src/utils.ts @@ -67,6 +67,7 @@ import type { SamplerConfigModel, NameStringValuePairConfigModel, HttpTlsConfigModel, + GrpcTlsConfigModel, } from '@opentelemetry/configuration'; import type { AggregationOption, @@ -109,13 +110,17 @@ export function getResourceFromConfiguration( config: ConfigurationModel ): Resource | undefined { if (config.resource && config.resource.attributes) { - const attr: DetectedResourceAttributes = {}; + const attrs: DetectedResourceAttributes = {}; for (let i = 0; i < config.resource.attributes.length; i++) { const a = config.resource.attributes[i]; - attr[a.name] = a.value; + // https://github.com/open-telemetry/opentelemetry-configuration/issues/613 + // will likely clarify that entries with a `null` value should be ignored. + if (a.value !== null) { + attrs[a.name] = a.value; + } } - return resourceFromAttributes(attr, { - schemaUrl: config.resource.schema_url, + return resourceFromAttributes(attrs, { + schemaUrl: config.resource.schema_url ?? undefined, }); } return undefined; @@ -161,11 +166,11 @@ export function getResourceDetectorsFromConfiguration( return detectors.flatMap(detector => { const result: ResourceDetector[] = []; - if (detector.host != null) result.push(hostDetector); - if (detector.os != null) result.push(osDetector); - if (detector.process != null) result.push(processDetector); - if (detector.service != null) result.push(serviceInstanceIdDetector); - if (detector.env != null) result.push(envDetector); + if (detector.host !== undefined) result.push(hostDetector); + if (detector.os !== undefined) result.push(osDetector); + if (detector.process !== undefined) result.push(processDetector); + if (detector.service !== undefined) result.push(serviceInstanceIdDetector); + if (detector.env !== undefined) result.push(envDetector); return result; }); } @@ -519,19 +524,19 @@ export function getPeriodicMetricReaderFromConfiguration( ): IMetricReader | undefined { if (periodic.exporter) { let exporter; - if (periodic.exporter.otlp_http) { - const encoding = periodic.exporter.otlp_http.encoding; + if (periodic.exporter.otlp_http !== undefined) { + const encoding = periodic.exporter.otlp_http?.encoding ?? 'protobuf'; if (encoding === 'json') { exporter = new OTLPHttpMetricExporter({ compression: - periodic.exporter.otlp_http.compression === 'gzip' + periodic.exporter.otlp_http?.compression === 'gzip' ? CompressionAlgorithm.GZIP : CompressionAlgorithm.NONE, }); } else if (encoding === 'protobuf') { exporter = new OTLPProtoMetricExporter({ compression: - periodic.exporter.otlp_http.compression === 'gzip' + periodic.exporter.otlp_http?.compression === 'gzip' ? CompressionAlgorithm.GZIP : CompressionAlgorithm.NONE, }); @@ -539,10 +544,10 @@ export function getPeriodicMetricReaderFromConfiguration( diag.warn(`Unsupported OTLP metrics encoding: ${encoding}.`); } } - if (periodic.exporter.otlp_grpc) { + if (periodic.exporter.otlp_grpc !== undefined) { exporter = new OTLPGrpcMetricExporter({ compression: - periodic.exporter.otlp_grpc.compression === 'gzip' + periodic.exporter.otlp_grpc?.compression === 'gzip' ? CompressionAlgorithm.GZIP : CompressionAlgorithm.NONE, }); @@ -556,7 +561,7 @@ export function getPeriodicMetricReaderFromConfiguration( exporter, }); } - if (periodic.exporter.console) { + if (periodic.exporter.console !== undefined) { return new PeriodicExportingMetricReader({ exporter: new ConsoleMetricExporter(), }); @@ -613,42 +618,42 @@ export function getBatchLogRecordProcessorFromEnv( export function getLogRecordExporter( exporter: LogRecordExporterConfigModel ): LogRecordExporter | undefined { - if (exporter.otlp_http) { + if (exporter.otlp_http !== undefined) { const cfg = exporter.otlp_http; const commonOpts = { compression: - cfg.compression === 'gzip' + cfg?.compression === 'gzip' ? CompressionAlgorithm.GZIP : CompressionAlgorithm.NONE, - url: cfg.endpoint, - headers: getHeadersFromConfiguration(cfg.headers), - timeoutMillis: cfg.timeout, - httpAgentOptions: getHttpAgentOptionsFromTls(cfg.tls), + url: cfg?.endpoint ?? undefined, + headers: getHeadersFromConfiguration(cfg?.headers), + timeoutMillis: validateExporterTimeout(cfg?.timeout), + httpAgentOptions: getHttpAgentOptionsFromTls(cfg?.tls), }; - const encoding = cfg.encoding; + const encoding = cfg?.encoding ?? 'protobuf'; if (encoding === 'json') { return new OTLPHttpLogExporter(commonOpts); } - if (encoding === 'protobuf' || encoding == null) { + if (encoding === 'protobuf') { return new OTLPProtoLogExporter(commonOpts); } diag.warn( `Unsupported OTLP logs encoding: ${encoding}. Using http/protobuf.` ); return new OTLPProtoLogExporter(commonOpts); - } else if (exporter.otlp_grpc) { + } else if (exporter.otlp_grpc !== undefined) { const cfg = exporter.otlp_grpc; return new OTLPGrpcLogExporter({ compression: - cfg.compression === 'gzip' + cfg?.compression === 'gzip' ? CompressionAlgorithm.GZIP : CompressionAlgorithm.NONE, - url: cfg.endpoint, - timeoutMillis: cfg.timeout, - credentials: getGrpcCredentialsFromTls(cfg.tls), - metadata: getGrpcMetadataFromHeaders(cfg.headers), + url: cfg?.endpoint ?? undefined, + timeoutMillis: validateExporterTimeout(cfg?.timeout), + credentials: getGrpcCredentialsFromTls(cfg?.tls), + metadata: getGrpcMetadataFromHeaders(cfg?.headers), }); - } else if (exporter.console) { + } else if (exporter.console !== undefined) { return new ConsoleLogRecordExporter(); } diag.warn(`Unsupported Exporter value. No Log Record Exporter registered`); @@ -665,10 +670,11 @@ export function getLogRecordProcessorsFromConfiguration( if (exporter) { logRecordProcessors.push( new BatchLogRecordProcessor(exporter, { - maxQueueSize: processor.batch.max_queue_size, - maxExportBatchSize: processor.batch.max_export_batch_size, - scheduledDelayMillis: processor.batch.schedule_delay, - exportTimeoutMillis: processor.batch.export_timeout, + maxQueueSize: processor.batch.max_queue_size ?? undefined, + maxExportBatchSize: + processor.batch.max_export_batch_size ?? undefined, + scheduledDelayMillis: processor.batch.schedule_delay ?? undefined, + exportTimeoutMillis: processor.batch.export_timeout ?? undefined, }) ); } @@ -694,7 +700,9 @@ export function getHeadersFromConfiguration( } const result: Record = {}; headers.forEach(header => { - result[header.name] = header.value; + if (header.value !== null) { + result[header.name] = header.value; + } }); return result; } @@ -705,9 +713,11 @@ export function getHeadersFromConfiguration( * Warn and return undefined so the exporter falls back to its default. */ function validateExporterTimeout( - timeout: number | undefined + timeout: number | null | undefined ): number | undefined { - if (timeout === 0) { + if (timeout === null) { + return undefined; + } else if (timeout === 0) { diag.warn( 'Exporter timeout of 0 (infinite) is not supported. Using default timeout.' ); @@ -729,16 +739,7 @@ export function getHttpAgentOptionsFromTls( return undefined; } -function getGrpcCredentialsFromTls( - tls: - | { - ca_file?: string; - key_file?: string; - cert_file?: string; - insecure?: boolean; - } - | undefined -) { +function getGrpcCredentialsFromTls(tls?: GrpcTlsConfigModel) { if (tls?.insecure) { return createInsecureCredentials(); } @@ -764,13 +765,15 @@ function getGrpcMetadataFromHeaders( } const metadata = createEmptyMetadata(); for (const header of headers) { - metadata.set(header.name, header.value); + if (header.value !== null) { + metadata.set(header.name, header.value); + } } return metadata; } function readFileOrWarn( - filePath: string | undefined, + filePath: string | null | undefined, label: string ): Buffer | undefined { if (!filePath) return undefined; @@ -785,43 +788,43 @@ function readFileOrWarn( export function getSpanExporter( exporter: SpanExporterConfigModel ): SpanExporter | undefined { - if (exporter.otlp_http) { - const encoding = exporter.otlp_http.encoding; + if (exporter.otlp_http !== undefined) { + const encoding = exporter.otlp_http?.encoding ?? 'protobuf'; if (encoding === 'json') { return new OTLPHttpTraceExporter({ compression: - exporter.otlp_http.compression === 'gzip' + exporter.otlp_http?.compression === 'gzip' ? CompressionAlgorithm.GZIP : CompressionAlgorithm.NONE, - url: exporter.otlp_http.endpoint, - headers: getHeadersFromConfiguration(exporter.otlp_http.headers), - timeoutMillis: validateExporterTimeout(exporter.otlp_http.timeout), - httpAgentOptions: getHttpAgentOptionsFromTls(exporter.otlp_http.tls), + url: exporter.otlp_http?.endpoint ?? undefined, + headers: getHeadersFromConfiguration(exporter.otlp_http?.headers), + timeoutMillis: validateExporterTimeout(exporter.otlp_http?.timeout), + httpAgentOptions: getHttpAgentOptionsFromTls(exporter.otlp_http?.tls), }); } else { return new OTLPProtoTraceExporter({ compression: - exporter.otlp_http.compression === 'gzip' + exporter.otlp_http?.compression === 'gzip' ? CompressionAlgorithm.GZIP : CompressionAlgorithm.NONE, - url: exporter.otlp_http.endpoint, - headers: getHeadersFromConfiguration(exporter.otlp_http.headers), - timeoutMillis: validateExporterTimeout(exporter.otlp_http.timeout), - httpAgentOptions: getHttpAgentOptionsFromTls(exporter.otlp_http.tls), + url: exporter.otlp_http?.endpoint ?? undefined, + headers: getHeadersFromConfiguration(exporter.otlp_http?.headers), + timeoutMillis: validateExporterTimeout(exporter.otlp_http?.timeout), + httpAgentOptions: getHttpAgentOptionsFromTls(exporter.otlp_http?.tls), }); } - } else if (exporter.otlp_grpc) { + } else if (exporter.otlp_grpc !== undefined) { return new OTLPGrpcTraceExporter({ compression: - exporter.otlp_grpc.compression === 'gzip' + exporter.otlp_grpc?.compression === 'gzip' ? CompressionAlgorithm.GZIP : CompressionAlgorithm.NONE, - url: exporter.otlp_grpc.endpoint, - timeoutMillis: validateExporterTimeout(exporter.otlp_grpc.timeout), - credentials: getGrpcCredentialsFromTls(exporter.otlp_grpc.tls), - metadata: getGrpcMetadataFromHeaders(exporter.otlp_grpc.headers), + url: exporter.otlp_grpc?.endpoint ?? undefined, + timeoutMillis: validateExporterTimeout(exporter.otlp_grpc?.timeout), + credentials: getGrpcCredentialsFromTls(exporter.otlp_grpc?.tls), + metadata: getGrpcMetadataFromHeaders(exporter.otlp_grpc?.headers), }); - } else if (exporter.console) { + } else if (exporter.console !== undefined) { return new ConsoleSpanExporter(); } diag.warn(`Unsupported Exporter value. No Span Exporter registered`); @@ -838,10 +841,11 @@ export function getSpanProcessorsFromConfiguration( if (exporter) { spanProcessors.push( new BatchSpanProcessor(exporter, { - maxQueueSize: processor.batch.max_queue_size, - maxExportBatchSize: processor.batch.max_export_batch_size, - scheduledDelayMillis: processor.batch.schedule_delay, - exportTimeoutMillis: processor.batch.export_timeout, + maxQueueSize: processor.batch.max_queue_size ?? undefined, + maxExportBatchSize: + processor.batch.max_export_batch_size ?? undefined, + scheduledDelayMillis: processor.batch.schedule_delay ?? undefined, + exportTimeoutMillis: processor.batch.export_timeout ?? undefined, }) ); } @@ -959,8 +963,10 @@ export function getAggregationType( type: AggregationType.EXPONENTIAL_HISTOGRAM, options: { recordMinMax: - aggregation.base2_exponential_bucket_histogram.record_min_max ?? true, - maxSize: aggregation.base2_exponential_bucket_histogram.max_size, + aggregation.base2_exponential_bucket_histogram.record_min_max ?? + undefined, + maxSize: + aggregation.base2_exponential_bucket_histogram.max_size ?? undefined, }, }; } @@ -1079,20 +1085,22 @@ const DEFAULT_RATIO = 1; * Builds a {@link Sampler} from a {@link SamplerConfigModel} data model. * This allows sampler construction from declarative configuration. */ -export function buildSamplerFromConfig(config: SamplerConfigModel): Sampler { - if (config.always_on !== undefined) { +export function buildSamplerFromConfig( + samplerConfig: SamplerConfigModel +): Sampler { + if (samplerConfig.always_on !== undefined) { return new AlwaysOnSampler(); } - if (config.always_off !== undefined) { + if (samplerConfig.always_off !== undefined) { return new AlwaysOffSampler(); } - if (config.trace_id_ratio_based !== undefined) { + if (samplerConfig.trace_id_ratio_based !== undefined) { return new TraceIdRatioBasedSampler( - config.trace_id_ratio_based.ratio ?? DEFAULT_RATIO + samplerConfig.trace_id_ratio_based?.ratio ?? DEFAULT_RATIO ); } - if (config.parent_based !== undefined) { - const pb = config.parent_based; + if (samplerConfig.parent_based !== undefined) { + const pb = samplerConfig.parent_based ?? {}; return new ParentBasedSampler({ root: pb.root ? buildSamplerFromConfig(pb.root) : new AlwaysOnSampler(), remoteParentSampled: pb.remote_parent_sampled diff --git a/experimental/packages/opentelemetry-sdk-node/test/utils.test.ts b/experimental/packages/opentelemetry-sdk-node/test/utils.test.ts index 3bc3b7d86b1..c446334a4cd 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/utils.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/utils.test.ts @@ -504,7 +504,7 @@ describe('getBatchLogRecordProcessorConfigFromEnv', function () { { type: AggregationType.EXPONENTIAL_HISTOGRAM, options: { - recordMinMax: true, + recordMinMax: undefined, maxSize: 10, }, }