Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
11f647d
fix(sdk-node)!: fail-fast on MeterProvider creation from config file
trentm Jul 28, 2026
548834f
fix build
trentm Jul 28, 2026
ca63320
changelog entry; refactor (and a fix) for createMetricReaderFromConfig
trentm Jul 28, 2026
caddd1b
existing tests pass with this small change in expectations
trentm Jul 28, 2026
0e1e934
actually use the MeterProvider from create-from-config.ts
trentm Jul 28, 2026
c9b9814
get loading of TLS files to fail-fast
trentm Jul 28, 2026
bc3985b
lint:fix
trentm Jul 28, 2026
5040b5a
refactor validateExporterTimeout to _validateExportTimeoutConfig whic…
trentm Jul 28, 2026
0afaa5e
lint:fix
trentm Jul 28, 2026
bc6040a
tests for the create-from-config.ts added functionality, clear out ol…
trentm Jul 29, 2026
0dbca81
lint:fix
trentm Jul 29, 2026
de42156
clear one TODO, add an issue ref for another
trentm Jul 30, 2026
44ef9de
fix(sdk-node)!: fail-fast on TracerProvider creation from config file
trentm Jul 30, 2026
9ae81c6
changelog PR ref
trentm Jul 30, 2026
5a02c90
tweak todo note for jaeger-remote sampler
trentm Jul 30, 2026
addf7cc
Merge branch 'main' into trentm-sdk-create-from-config-4
trentm Jul 30, 2026
3634ffc
Merge branch 'trentm-sdk-create-from-config-4' into trentm-sdk-create…
trentm Jul 30, 2026
621f22c
fix(sdk-node)!: fixes for and fail-fast on Resource creation from con…
trentm Aug 7, 2026
6741ded
changelog entry
trentm Aug 7, 2026
0fd6863
lint:fix
trentm Aug 7, 2026
e4fa828
remove this now unused internal helper
trentm Aug 7, 2026
0e2665b
drop SDKOptions.testMapPropagator for now, it is out of place until a…
trentm Aug 7, 2026
f207a2a
refactor configuration package to no longer to env-based config; just…
trentm Aug 7, 2026
7e90f01
sdk-node: big refactor and update to the startNodeSdk *from-env* code…
trentm Aug 13, 2026
2c79534
lint:fix
trentm Aug 13, 2026
9f1c70e
Merge branch 'main' into trentm-startNodeSDK-refactor
trentm Aug 13, 2026
67f7f3b
fix lint and compile
trentm Aug 13, 2026
1419f64
fix tests
trentm Aug 13, 2026
14fb2fc
more tests for create-from-env.ts exports
trentm Aug 13, 2026
2099e0a
change the default resource detectors; some test improvements
trentm Aug 14, 2026
8b5b494
feat(resources): add `resourceAttributesEnvDetector` and `serviceName…
trentm Aug 14, 2026
7935656
ensure OTEL_SERVICE_NAME wins over service.name in OTEL_RESOURCE_ATTR…
trentm Aug 14, 2026
6350ea0
'new NodeSDK()': add serviceInstanceIdDetector and osDetector to the …
trentm Aug 14, 2026
9a21e77
test updates for change in default resource detectors for 'new NodeSD…
trentm Aug 14, 2026
a09d356
drop some debug/dev comments no longer needed
trentm Aug 14, 2026
914692e
use opts.propagators=[], rather than null, to be 'no propagators, ple…
trentm Aug 14, 2026
3ee6e0d
change to using empty array to signal no {signal}Provider, already wo…
trentm Aug 14, 2026
cd049fd
don't need these todos right now
trentm Aug 15, 2026
86b3ada
lint:fix
trentm Aug 15, 2026
99ffae0
fix parse-config.mjs dev script for the 'configuration' package API c…
trentm Aug 17, 2026
f372865
update changelog with better details of changes to sdk-node and confi…
trentm Aug 17, 2026
d67a514
merge from main
trentm Aug 21, 2026
38b66c6
drop dead code
trentm Aug 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2

### :rocket: Features

* feat(resources): Deprecate `envDetector` in favor of separate `resourceAttributesEnvDetector` and `serviceNameEnvDetector`. Also mark `serviceInstanceIdDetector` as stable (the `service.instance.id` semconv attribute is now stable). [#6999](https://github.com/open-telemetry/opentelemetry-js/pull/6999) @trentm
* feat(context-async-hooks): implement `attach()` on `AsyncLocalStorageContextManager` [#6845](https://github.com/open-telemetry/opentelemetry-js/pull/6845) @pichlermarc
* On Node.js 25.9+, delegates to `AsyncLocalStorage.withScope()` returning a native `RunScope`. On older Node.js, falls back to `enterWith()` with a manual disposable wrapper.
* feat(sdk-trace): allow configuring the force flush timeout per call #6929 @LarryHu0217
Expand Down
8 changes: 8 additions & 0 deletions experimental/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2
Could not create OpenTelemetry SDK from configuration, SDK will not be setup: unknown ExperimentalResourceDetector name in configuration: "container"
```

* feat(sdk-node)!: The experimental `startNodeSdk()` code path for *environment-based* config (i.e. when not using a config file), has full option coverage. [#6999](https://github.com/open-telemetry/opentelemetry-js/pull/6999) @trentm
* `startNodeSdk()` should now be a viable replacement for `new NodeSDK()`, supporting similar (but not exactly the same) options for configuring most SDK components.
* `startNodeSDK()` has been *deprecated*, use `startNodeSdk()` (slight capitalization change).
* Two resource detectors have been added to the default set for `new NodeSDK()` users: `os` and `serviceinstance`. This means that when not specifying `OTEL_NODE_RESOURCE_DETECTORS`, the SDK Resource will include `os.*` and `service.instance.id` attributes.
* refactor(configuration)!: The responsibility of the `configuration` package has been reduced to just the parsing, validation, and TypeScript types for declarative config files. [#6999](https://github.com/open-telemetry/opentelemetry-js/pull/6999) @trentm
* **Breaking:** The `configuration` package no longer supports creating a synthetic `ConfigurationModel` from environment variables.
* **Breaking:** The `configuration` package API has changed: `createConfigFactory()` has been replaced with `parseConfigFile().

### :rocket: Features

* feat(sdk-logs): deprecate `SdkLogRecord` in favor of `ReadWriteLogRecord` [#6939](https://github.com/open-telemetry/opentelemetry-js/pull/6939) @pichlermarc
Expand Down
159 changes: 23 additions & 136 deletions experimental/packages/configuration/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@

**Note: This is an experimental package under active development. New releases may include breaking changes.**

This package implements the [OpenTelemetry declarative configuration](https://github.com/open-telemetry/opentelemetry-configuration) specification for Node.js. It parses configuration from a YAML file or environment variables and produces a `ConfigurationModel` that the OpenTelemetry SDK uses to initialize providers.
This package implements a part of the [OpenTelemetry declarative configuration](https://opentelemetry.io/docs/specs/otel/configuration/#declarative-configuration) specification for Node.js. It exports:

- a suite of TypeScript types representing [the configuration types](https://opentelemetry.io/docs/specs/otel-config/types/) defined by [the declarative config schema](https://github.com/open-telemetry/opentelemetry-configuration#readme);
- [`parseConfigFile()` to parse and validate](https://opentelemetry.io/docs/specs/otel/configuration/sdk/#parse) a YAML configuration, which can then be used (e.g. by `@opentelemetry/sdk-node`) to setup an OpenTelemetry SDK; and
- some utilities for working with parsed configuration data.

## Installation

Expand All @@ -15,129 +19,38 @@ npm install @opentelemetry/configuration

## Usage

`createConfigFactory()` selects the configuration source automatically:

- If `OTEL_CONFIG_FILE` points to a valid `.yaml`/`.yml` file, configuration is read from that file.
- Otherwise, configuration is assembled from standard OpenTelemetry environment variables.

```typescript
import { createConfigFactory } from '@opentelemetry/configuration';

const factory = createConfigFactory();
const config = factory.getConfigModel();
```

### YAML file configuration

Set `OTEL_CONFIG_FILE` to the path of your configuration file:

```sh
OTEL_CONFIG_FILE=./otel-config.yaml node app.js
```js
import { parseConfigFile } from '@opentelemetry/configuration';
const config = parseConfigFile('./otel-sdk-config.yaml');
```

Example:
An extremely limit example configuration file:

```yaml
file_format: "1.0"
resource:
attributes:
- name: service.name
value: my-service
file_format: "1.1"
tracer_provider:
processors:
- batch:
exporter:
otlp_http:
endpoint: http://localhost:4318/v1/traces
endpoint: ${OTEL_EXPORTER_ENDPOINT:-http://localhost:4318}/v1/traces
```

Environment variable substitution is supported using `${VAR_NAME}`, `${VAR_NAME:-default}`, `${env:VAR_NAME}`, and `${env:VAR_NAME:-default}` syntax. Use `$$` for a literal `$`.

```yaml
tracer_provider:
processors:
- batch:
exporter:
otlp_http:
endpoint: ${OTEL_EXPORTER_ENDPOINT:-http://localhost:4318}/v1/traces
```
See <https://opentelemetry.io/docs/specs/otel/configuration/#declarative-configuration> and <https://github.com/open-telemetry/opentelemetry-configuration> for documentation, examples, and a JSON schema for declarative configuration.

## Supported schema versions

- `1.0`
- `1.1`

### Environment variable configuration

When no config file is set, the factory reads from the standard OpenTelemetry SDK environment variables. The full set of variables this package consumes:

| Variable | Description |
| --- | --- |
| `OTEL_SDK_DISABLED` | Disable the SDK entirely |
| `OTEL_LOG_LEVEL` | Internal SDK log level |
| `OTEL_SERVICE_NAME` | Service name resource attribute |
| `OTEL_RESOURCE_ATTRIBUTES` | Comma-separated resource attributes |
| `OTEL_NODE_RESOURCE_DETECTORS` | Resource detectors to enable (`env`, `host`, `os`, `process`, `serviceinstance`, `all`, `none`) |
| `OTEL_PROPAGATORS` | Propagators: `tracecontext`, `baggage`, `b3`, `b3multi` |
| `OTEL_TRACES_EXPORTER` | Traces exporter(s): `otlp`, `console`, `none` |
| `OTEL_METRICS_EXPORTER` | Metrics exporter(s): `otlp`, `prometheus`, `console`, `none` |
| `OTEL_LOGS_EXPORTER` | Logs exporter(s): `otlp`, `console`, `none` |
| `OTEL_TRACES_SAMPLER` | Sampler name (e.g. `parentbased_always_on`, `traceidratio`) |
| `OTEL_TRACES_SAMPLER_ARG` | Sampler argument (e.g. ratio value) |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP endpoint (all signals) |
| `OTEL_EXPORTER_OTLP_HEADERS` | OTLP headers (all signals) |
| `OTEL_EXPORTER_OTLP_PROTOCOL` | OTLP protocol: `grpc`, `http/protobuf`, `http/json` |
| `OTEL_EXPORTER_OTLP_TIMEOUT` | OTLP request timeout (all signals) |
| `OTEL_EXPORTER_OTLP_COMPRESSION` | OTLP compression (all signals): `gzip`, `none` |
| `OTEL_EXPORTER_OTLP_CERTIFICATE` | OTLP server CA certificate file (all signals) |
| `OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE` | OTLP client certificate file for mTLS (all signals) |
| `OTEL_EXPORTER_OTLP_CLIENT_KEY` | OTLP client private key file for mTLS (all signals) |
| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | Per-signal override (traces) |
| `OTEL_EXPORTER_OTLP_TRACES_HEADERS` | Per-signal override (traces) |
| `OTEL_EXPORTER_OTLP_TRACES_PROTOCOL` | Per-signal override (traces) |
| `OTEL_EXPORTER_OTLP_TRACES_TIMEOUT` | Per-signal override (traces) |
| `OTEL_EXPORTER_OTLP_TRACES_COMPRESSION` | Per-signal override (traces) |
| `OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE` | Per-signal override (traces) |
| `OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE` | Per-signal override (traces) |
| `OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY` | Per-signal override (traces) |
| `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` | Per-signal override (metrics) |
| `OTEL_EXPORTER_OTLP_METRICS_HEADERS` | Per-signal override (metrics) |
| `OTEL_EXPORTER_OTLP_METRICS_PROTOCOL` | Per-signal override (metrics) |
| `OTEL_EXPORTER_OTLP_METRICS_TIMEOUT` | Per-signal override (metrics) |
| `OTEL_EXPORTER_OTLP_METRICS_COMPRESSION` | Per-signal override (metrics) |
| `OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE` | Per-signal override (metrics) |
| `OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE` | Per-signal override (metrics) |
| `OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY` | Per-signal override (metrics) |
| `OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE` | Metric temporality preference: `cumulative`, `delta`, `lowmemory` |
| `OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION` | Default histogram aggregation: `explicit_bucket_histogram`, `base2_exponential_bucket_histogram` |
| `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` | Per-signal override (logs) |
| `OTEL_EXPORTER_OTLP_LOGS_HEADERS` | Per-signal override (logs) |
| `OTEL_EXPORTER_OTLP_LOGS_PROTOCOL` | Per-signal override (logs) |
| `OTEL_EXPORTER_OTLP_LOGS_TIMEOUT` | Per-signal override (logs) |
| `OTEL_EXPORTER_OTLP_LOGS_COMPRESSION` | Per-signal override (logs) |
| `OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE` | Per-signal override (logs) |
| `OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE` | Per-signal override (logs) |
| `OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY` | Per-signal override (logs) |
| `OTEL_EXPORTER_PROMETHEUS_HOST` | Prometheus exporter bind host |
| `OTEL_EXPORTER_PROMETHEUS_PORT` | Prometheus exporter bind port |
| `OTEL_METRIC_EXPORT_INTERVAL` | Periodic metric reader export interval (ms) |
| `OTEL_METRIC_EXPORT_TIMEOUT` | Periodic metric reader export timeout (ms) |
| `OTEL_METRICS_EXEMPLAR_FILTER` | Exemplar filter: `always_on`, `always_off`, `trace_based` |
| `OTEL_BSP_SCHEDULE_DELAY` | Batch span processor: schedule delay (ms) |
| `OTEL_BSP_EXPORT_TIMEOUT` | Batch span processor: export timeout (ms) |
| `OTEL_BSP_MAX_QUEUE_SIZE` | Batch span processor: max queue size |
| `OTEL_BSP_MAX_EXPORT_BATCH_SIZE` | Batch span processor: max export batch size |
| `OTEL_BLRP_SCHEDULE_DELAY` | Batch log record processor: schedule delay (ms) |
| `OTEL_BLRP_EXPORT_TIMEOUT` | Batch log record processor: export timeout (ms) |
| `OTEL_BLRP_MAX_QUEUE_SIZE` | Batch log record processor: max queue size |
| `OTEL_BLRP_MAX_EXPORT_BATCH_SIZE` | Batch log record processor: max export batch size |
| `OTEL_ATTRIBUTE_COUNT_LIMIT` | Default max attributes per span/log/event/link |
| `OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT` | Default max attribute value length |
| `OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT` | Max attributes per span |
| `OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT` | Max span attribute value length |
| `OTEL_SPAN_EVENT_COUNT_LIMIT` | Max events per span |
| `OTEL_SPAN_LINK_COUNT_LIMIT` | Max links per span |
| `OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT` | Max attributes per span event |
| `OTEL_LINK_ATTRIBUTE_COUNT_LIMIT` | Max attributes per span link |
| `OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT` | Max attributes per log record |
| `OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT` | Max log record attribute value length |

See [`src/EnvironmentConfigFactory.ts`](src/EnvironmentConfigFactory.ts) for the exact parsing logic.
For a per-field view of which schema fields the SDK currently applies, see
the JS row in the cross-SDK [language support status][lss] doc maintained in
the `opentelemetry-configuration` repo. That doc is the source of truth for
declarative-config conformance across all SDKs.

[lss]: https://github.com/open-telemetry/opentelemetry-configuration/blob/main/language-support-status.md#js-

## Exported types

Expand Down Expand Up @@ -175,32 +88,6 @@ The generation script (`scripts/generate-config.js`) handles several post-proces
- Removes the duplicate type declarations that `json-schema-to-typescript` emits for structurally-identical sub-schemas (e.g. the second `GrpcTls`/`HttpTls`)
- Produces a pre-compiled ajv validator (`validator.js` + `validator.d.ts`) for use at runtime

### Defaults

Both config paths apply the same spec-defined defaults so consumers see consistent behaviour regardless of config source:

| Field | Default |
| --- | --- |
| `disabled` | `false` |
| `log_level` | `info` |
| `attribute_limits.attribute_count_limit` | `128` |

`FileConfigFactory` applies these via `applyConfigDefaults()` after schema validation. `EnvironmentConfigFactory` applies them via `initializeDefaultConfiguration()` in the constructor, then overlays env var values on top.

One intentional exception in both paths: `AttributeNameValue.type` is **not** defaulted even though the spec says "if omitted, string is used". This is a semantic default for SDK code interpreting resource attributes, not a config-parser concern. SDK code reading `resource.attributes` should apply `attr.type ?? 'string'` at the point of use.

## Supported schema versions

- `1.0`
- `1.1`

For a per-field view of which schema fields the SDK currently applies, see
the JS row in the cross-SDK [language support status][lss] doc maintained in
the `opentelemetry-configuration` repo. That doc is the source of truth for
declarative-config conformance across all SDKs.

[lss]: https://github.com/open-telemetry/opentelemetry-configuration/blob/main/language-support-status.md#js-

## Useful links

- [OpenTelemetry Declarative Configuration Specification](https://github.com/open-telemetry/opentelemetry-configuration)
Expand Down
21 changes: 9 additions & 12 deletions experimental/packages/configuration/scripts/parse-config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,25 @@
*/

/**
* Parse a declaractive config file (or create a config from env vars) and
* print its JS object representation. This is a convenience script for
* development of this package.
* Parse a declaractive config file and print its JS object representation.
* This is a convenience script for development of this package.
*
* Usage:
* ./scripts/parse-config.mjs [CONFIG_FILE]
*
* If `CONFIG_FILE` is given, it is used to set the `OTEL_CONFIG_FILE` envvar.
* That means that if no `CONFIG_FILE` is given, the config will be
* generated from envvars.
* The config file to parse can be provided as a command-line argument, or
* via the `OTEL_CONFIG_FILE` environment variable.
*/

import { createConfigFactory } from '@opentelemetry/configuration';
import { parseConfigFile } from '@opentelemetry/configuration';
import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api';

diag.setLogger(new DiagConsoleLogger(), { logLevel: DiagLogLevel.INFO });

const configFile = process.argv[2];
if (configFile) {
process.env.OTEL_CONFIG_FILE = configFile;
const configFile = process.argv[2] || process.env.OTEL_CONFIG_FILE;
if (!configFile) {
throw new Error('missing CONFIG_FILE argument or `OTEL_CONFIG_FILE` envvar');
}

const fac = createConfigFactory();
const config = fac.getConfigModel();
const config = parseConfigFile(configFile);
console.dir(config, { depth: 50 });
17 changes: 0 additions & 17 deletions experimental/packages/configuration/src/ConfigFactory.ts

This file was deleted.

37 changes: 0 additions & 37 deletions experimental/packages/configuration/src/EnvDefinition.ts

This file was deleted.

Loading