Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
a6d0fca
parse config file
maryliag Aug 22, 2025
f544c93
Merge branch 'main' of github.com:open-telemetry/opentelemetry-js int…
maryliag Aug 22, 2025
fcef569
update changelog
maryliag Aug 22, 2025
0f6a05a
add more tests
maryliag Aug 22, 2025
eeb69f5
Update experimental/packages/opentelemetry-configuration/src/FileConf…
maryliag Sep 16, 2025
cb2cd96
Merge branch 'main' of github.com:open-telemetry/opentelemetry-js int…
maryliag Sep 16, 2025
73fe9af
changes from feedback
maryliag Sep 16, 2025
7a1aec4
create function by paramtre type
maryliag Sep 16, 2025
2297ee9
update package lock
maryliag Sep 16, 2025
97d9013
fix disabled
maryliag Sep 16, 2025
1c3ce03
fix changelog
maryliag Sep 19, 2025
a6833d8
Merge branch 'main' of github.com:open-telemetry/opentelemetry-js int…
maryliag Sep 19, 2025
287c395
Merge branch 'main' into config-yml
maryliag Sep 19, 2025
de08a18
remove import
maryliag Sep 20, 2025
a662970
feat(sampler-composite): add experimental implementation of composite…
maryliag Sep 20, 2025
537e20c
Revert "feat(sampler-composite): add experimental implementation of c…
maryliag Sep 20, 2025
b158b36
Merge branch 'main' of github.com:open-telemetry/opentelemetry-js int…
maryliag Sep 20, 2025
ba49203
use correct type
maryliag Sep 22, 2025
0192f44
Merge branch 'main' of github.com:open-telemetry/opentelemetry-js int…
maryliag Sep 22, 2025
36051e8
Merge branch 'main' of github.com:open-telemetry/opentelemetry-js int…
maryliag Sep 22, 2025
7524d75
update test
maryliag Sep 22, 2025
d695c91
fix lint
maryliag Sep 22, 2025
dd72027
Merge branch 'main' into config-yml
maryliag Sep 23, 2025
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 experimental/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2

*feat(opentelemetry-configuration): creation of basic ConfigProvider [#5809](https://github.com/open-telemetry/opentelemetry-js/pull/5809) @maryliag
*feat(opentelemetry-configuration): creation of basic FileConfigProvider [#5863](https://github.com/open-telemetry/opentelemetry-js/pull/5863) @maryliag
*feat(opentelemetry-configuration): Parse of Configuration File [#5875](https://github.com/open-telemetry/opentelemetry-js/pull/5875) @maryliag

### :bug: Bug Fixes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
},
"dependencies": {
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/core": "^2.0.1"
"@opentelemetry/core": "^2.0.1",
"yaml": "^1.10.2"
},
"devDependencies": {
"@opentelemetry/api": "^1.9.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
* limitations under the License.
*/

import { DiagLogLevel } from '@opentelemetry/api';
import {
ConfigurationModel,
initializeDefaultConfiguration,
Expand All @@ -35,12 +34,11 @@ export class EnvironmentConfigProvider implements ConfigProvider {

constructor() {
this._config = initializeDefaultConfiguration();
this._config.disable = getBooleanFromEnv('OTEL_SDK_DISABLED');
this._config.disabled = getBooleanFromEnv('OTEL_SDK_DISABLED');

const logLevel = getStringFromEnv('OTEL_LOG_LEVEL');
const logLevel = diagLogLevelFromString(getStringFromEnv('OTEL_LOG_LEVEL'));
if (logLevel) {
this._config.log_level =
diagLogLevelFromString(logLevel) ?? DiagLogLevel.INFO;
this._config.log_level = logLevel;
}

const nodeResourceDetectors = getStringListFromEnv(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,25 @@
* limitations under the License.
*/

import { getStringFromEnv } from '@opentelemetry/core';
import {
diagLogLevelFromString,
getStringFromEnv,
getStringListFromEnv,
} from '@opentelemetry/core';
import {
ConfigurationModel,
initializeDefaultConfiguration,
} from './configModel';
import { ConfigProvider } from './IConfigProvider';
import * as fs from 'fs';
import * as yaml from 'yaml';

export class FileConfigProvider implements ConfigProvider {
private _config: ConfigurationModel;

constructor() {
this._config = initializeDefaultConfiguration();
ParseConfigFile(this._config);
}

getInstrumentationConfig(): ConfigurationModel {
Expand All @@ -37,7 +43,10 @@ export class FileConfigProvider implements ConfigProvider {
export function hasValidConfigFile(): boolean {
const configFile = getStringFromEnv('OTEL_EXPERIMENTAL_CONFIG_FILE');
if (configFile) {
if (!configFile.endsWith('.yaml') || !fs.existsSync(configFile)) {
if (
!(configFile.endsWith('.yaml') || configFile.endsWith('.yml')) ||
!fs.existsSync(configFile)
) {
throw new Error(
`Config file ${configFile} set on OTEL_EXPERIMENTAL_CONFIG_FILE is not valid`
);
Expand All @@ -46,3 +55,92 @@ export function hasValidConfigFile(): boolean {
}
return false;
}

function ParseConfigFile(config: ConfigurationModel) {
const supportedFileVersions = ['1.0-rc.1'];
const configFile = getStringFromEnv('OTEL_EXPERIMENTAL_CONFIG_FILE') || '';
const file = fs.readFileSync(configFile, 'utf8');
const parsedContent = yaml.parse(file);

if (
parsedContent['file_format'] &&
supportedFileVersions.includes(parsedContent['file_format'])
) {
const disabled = getValue(config.disabled, parsedContent['disabled']);
if (disabled || disabled === false) {
config.disabled = disabled;
}

const logLevel = getValue(
config.log_level,
diagLogLevelFromString(parsedContent['log_level'])
);
if (logLevel) {
config.log_level = logLevel;
}

const attrList = getValue(
config.resource.attributes_list,
parsedContent['resource']?.['attributes_list']
);
if (attrList) {
config.resource.attributes_list = attrList;
}

const schemaUrl = getValue(
config.resource.schema_url,
parsedContent['resource']?.['schema_url']
);
if (schemaUrl) {
config.resource.schema_url = schemaUrl;
}

setResourceAttributes(config, parsedContent['resource']?.['attributes']);

setValuesFromEnvVariables(config);
} else {
throw new Error(
`Unsupported File Format: ${parsedContent['file_format']}. It must be one of the following: ${supportedFileVersions}`
);
}
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function getValue(obj: unknown, value: unknown): any {
if (typeof obj === 'boolean') {
const raw = String(value)?.trim().toLowerCase();
if (raw === 'false') {
return false;
}
}
return value;
}

/**
* Some values can only be set by Environment Variables and
* not declarative configuration. This function set those values.
* @param config
*/
function setValuesFromEnvVariables(config: ConfigurationModel) {
const nodeResourceDetectors = getStringListFromEnv(
'OTEL_NODE_RESOURCE_DETECTORS'
);
if (nodeResourceDetectors) {
config.node_resource_detectors = nodeResourceDetectors;
}
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function setResourceAttributes(config: ConfigurationModel, attributes: any[]) {
if (attributes) {
config.resource.attributes = [];
for (let i = 0; i < attributes.length; i++) {
const att = attributes[i];
config.resource.attributes.push({
name: att['name'],
value: att['value'],
type: att['type'] ?? 'string',
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export interface ConfigurationModel {
* Configure if the SDK is disabled or not.
* If omitted or null, false is used.
*/
disable: boolean;
disabled: boolean;

/**
* Configure the log level of the internal logger used by the SDK.
Expand All @@ -44,7 +44,7 @@ export interface ConfigurationModel {

export function initializeDefaultConfiguration(): ConfigurationModel {
const config: ConfigurationModel = {
disable: false,
disabled: true,
log_level: DiagLogLevel.INFO,
node_resource_detectors: ['all'],
resource: {},
Expand All @@ -56,7 +56,7 @@ export function initializeDefaultConfiguration(): ConfigurationModel {
export interface ConfigAttributes {
name: string;
value: string | boolean | number | string[] | boolean[] | number[];
type?:
type:
| 'string'
| 'bool'
| 'int'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,69 @@ import { DiagLogLevel } from '@opentelemetry/api';
import { createConfigProvider } from '../src/ConfigProvider';

const defaultConfig: Configuration = {
disable: false,
disabled: false,
log_level: DiagLogLevel.INFO,
node_resource_detectors: ['all'],
resource: {},
};

const configFromFile: Configuration = {
disabled: false,
log_level: DiagLogLevel.DEBUG,
node_resource_detectors: ['all'],
resource: {
schema_url: 'https://opentelemetry.io/schemas/1.16.0',
attributes_list: 'service.namespace=my-namespace,service.version=1.0.0',
attributes: [
{
name: 'service.name',
value: 'unknown_service',
type: 'string',
},
{
name: 'string_key',
value: 'value',
type: 'string',
},
{
name: 'bool_key',
value: true,
type: 'bool',
},
{
name: 'int_key',
value: 1,
type: 'int',
},
{
name: 'double_key',
value: 1.1,
type: 'double',
},
{
name: 'string_array_key',
value: ['value1', 'value2'],
type: 'string_array',
},
{
name: 'bool_array_key',
value: [true, false],
type: 'bool_array',
},
{
name: 'int_array_key',
value: [1, 2],
type: 'int_array',
},
{
name: 'double_array_key',
value: [1.1, 2.2],
type: 'double_array',
},
],
},
};

describe('ConfigProvider', function () {
describe('get values from environment variables', function () {
afterEach(function () {
Expand All @@ -47,7 +104,7 @@ describe('ConfigProvider', function () {
process.env.OTEL_SDK_DISABLED = 'true';
const expectedConfig: Configuration = {
...defaultConfig,
disable: true,
disabled: true,
};
const configProvider = createConfigProvider();
assert.deepStrictEqual(
Expand Down Expand Up @@ -103,6 +160,7 @@ describe('ConfigProvider', function () {
describe('get values from config file', function () {
afterEach(function () {
delete process.env.OTEL_EXPERIMENTAL_CONFIG_FILE;
delete process.env.OTEL_NODE_RESOURCE_DETECTORS;
});

it('should initialize config with default values from valid config file', function () {
Expand All @@ -111,7 +169,7 @@ describe('ConfigProvider', function () {
const configProvider = createConfigProvider();
assert.deepStrictEqual(
configProvider.getInstrumentationConfig(),
defaultConfig
configFromFile
);
});

Expand All @@ -122,6 +180,13 @@ describe('ConfigProvider', function () {
});
});

it('should return error from invalid config file format', function () {
process.env.OTEL_EXPERIMENTAL_CONFIG_FILE = 'test/fixtures/invalid.yaml';
assert.throws(() => {
createConfigProvider();
});
});

it('should initialize config with default values with empty string for config file', function () {
process.env.OTEL_EXPERIMENTAL_CONFIG_FILE = '';
const configProvider = createConfigProvider();
Expand All @@ -139,5 +204,30 @@ describe('ConfigProvider', function () {
defaultConfig
);
});

it('should initialize config with default values from valid short config file', function () {
process.env.OTEL_EXPERIMENTAL_CONFIG_FILE =
'test/fixtures/short-config.yml';
const configProvider = createConfigProvider();
assert.deepStrictEqual(
configProvider.getInstrumentationConfig(),
defaultConfig
);
});

it('should initialize config with default values from valid config file and node resources', function () {
process.env.OTEL_EXPERIMENTAL_CONFIG_FILE =
'test/fixtures/short-config.yml';
process.env.OTEL_NODE_RESOURCE_DETECTORS = 'env,host, serviceinstance';
const expectedConfig = {
...defaultConfig,
node_resource_detectors: ['env', 'host', 'serviceinstance'],
};
const configProvider = createConfigProvider();
assert.deepStrictEqual(
configProvider.getInstrumentationConfig(),
expectedConfig
);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
file_format: "invalid"
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ file_format: "1.0-rc.1"
disabled: false
# Configure the log level of the internal logger used by the SDK.
# If omitted, info is used.
log_level: info
log_level: debug
# Configure general attribute limits. See also tracer_provider.limits, logger_provider.limits.
attribute_limits:
# Configure max attribute value size.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
file_format: "1.0-rc.1"
disabled: false
10 changes: 5 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading