Skip to content

Commit a6d0fca

Browse files
committed
parse config file
1 parent 23677fd commit a6d0fca

File tree

8 files changed

+162
-16
lines changed

8 files changed

+162
-16
lines changed

experimental/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2
1414

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

1819
### :bug: Bug Fixes
1920

experimental/packages/opentelemetry-configuration/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@
4141
},
4242
"dependencies": {
4343
"@opentelemetry/api": "^1.9.0",
44-
"@opentelemetry/core": "^2.0.1"
44+
"@opentelemetry/core": "^2.0.1",
45+
"yaml": "^1.10.2"
4546
},
4647
"devDependencies": {
4748
"@opentelemetry/api": "^1.9.0",

experimental/packages/opentelemetry-configuration/src/EnvironmentConfigProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export class EnvironmentConfigProvider implements ConfigProvider {
3535

3636
constructor() {
3737
this._config = initializeDefaultConfiguration();
38-
this._config.disable = getBooleanFromEnv('OTEL_SDK_DISABLED');
38+
this._config.disabled = getBooleanFromEnv('OTEL_SDK_DISABLED');
3939

4040
const logLevel = getStringFromEnv('OTEL_LOG_LEVEL');
4141
if (logLevel) {

experimental/packages/opentelemetry-configuration/src/FileConfigProvider.ts

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,26 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { getStringFromEnv } from '@opentelemetry/core';
17+
import {
18+
diagLogLevelFromString,
19+
getStringFromEnv,
20+
getStringListFromEnv,
21+
} from '@opentelemetry/core';
1822
import {
1923
ConfigurationModel,
2024
initializeDefaultConfiguration,
2125
} from './configModel';
2226
import { ConfigProvider } from './IConfigProvider';
2327
import * as fs from 'fs';
28+
import * as yaml from 'yaml';
29+
import { DiagLogLevel } from '@opentelemetry/api';
2430

2531
export class FileConfigProvider implements ConfigProvider {
2632
private _config: ConfigurationModel;
2733

2834
constructor() {
2935
this._config = initializeDefaultConfiguration();
36+
ParseConfigFile(this._config);
3037
}
3138

3239
getInstrumentationConfig(): ConfigurationModel {
@@ -37,7 +44,10 @@ export class FileConfigProvider implements ConfigProvider {
3744
export function hasValidConfigFile(): boolean {
3845
const configFile = getStringFromEnv('OTEL_EXPERIMENTAL_CONFIG_FILE');
3946
if (configFile) {
40-
if (!configFile.endsWith('.yaml') || !fs.existsSync(configFile)) {
47+
if (
48+
!(configFile.endsWith('.yaml') || configFile.endsWith('.yml')) ||
49+
!fs.existsSync(configFile)
50+
) {
4151
throw new Error(
4252
`Config file ${configFile} set on OTEL_EXPERIMENTAL_CONFIG_FILE is not valid`
4353
);
@@ -46,3 +56,80 @@ export function hasValidConfigFile(): boolean {
4656
}
4757
return false;
4858
}
59+
60+
function ParseConfigFile(config: ConfigurationModel) {
61+
const supportedFileVersions = ['1.0-rc.1'];
62+
const configFile = getStringFromEnv('OTEL_EXPERIMENTAL_CONFIG_FILE') || '';
63+
const file = fs.readFileSync(configFile, 'utf8');
64+
const parsedContent = yaml.parse(file);
65+
66+
if (
67+
parsedContent['file_format'] &&
68+
supportedFileVersions.includes(parsedContent['file_format'])
69+
) {
70+
config.disabled = setValue(config.disabled, parsedContent['disabled']);
71+
config.log_level = setValue(
72+
config.log_level,
73+
diagLogLevelFromString(parsedContent['log_level']) ?? DiagLogLevel.INFO
74+
);
75+
config.resource.attributes_list = setValue(
76+
config.resource.attributes_list,
77+
parsedContent['resource']?.['attributes_list']
78+
);
79+
config.resource.schema_url = setValue(
80+
config.resource.schema_url,
81+
parsedContent['resource']?.['schema_url']
82+
);
83+
setResourceAttributes(config, parsedContent['resource']?.['attributes']);
84+
85+
setValuesFromEnvVariables(config);
86+
} else {
87+
console.log(`Unsupported File Format: ${parsedContent['file_format']}. It must be one of the following: ${supportedFileVersions}`);
88+
throw new Error(
89+
`Unsupported File Format: ${parsedContent['file_format']}. It must be one of the following: ${supportedFileVersions}`
90+
);
91+
}
92+
}
93+
94+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
95+
function setValue(obj: unknown, value: unknown): any {
96+
if (value) {
97+
return value;
98+
}
99+
if (typeof obj === 'boolean') {
100+
const raw = String(value)?.trim().toLowerCase();
101+
if (raw === 'false') {
102+
return false;
103+
}
104+
}
105+
return obj;
106+
}
107+
108+
/**
109+
* Some values can only be set by Environment Variables and
110+
* not declarative configuration. This function set those values.
111+
* @param config
112+
*/
113+
function setValuesFromEnvVariables(config: ConfigurationModel) {
114+
const nodeResourceDetectors = getStringListFromEnv(
115+
'OTEL_NODE_RESOURCE_DETECTORS'
116+
);
117+
if (nodeResourceDetectors) {
118+
config.node_resource_detectors = nodeResourceDetectors;
119+
}
120+
}
121+
122+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
123+
function setResourceAttributes(config: ConfigurationModel, attributes: any[]) {
124+
if (attributes) {
125+
config.resource.attributes = [];
126+
for (let i = 0; i < attributes.length; i++) {
127+
const att = attributes[i];
128+
config.resource.attributes.push({
129+
name: att['name'],
130+
value: att['value'],
131+
type: att['type'] ?? 'string',
132+
});
133+
}
134+
}
135+
}

experimental/packages/opentelemetry-configuration/src/configModel.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export interface ConfigurationModel {
2121
* Configure if the SDK is disabled or not.
2222
* If omitted or null, false is used.
2323
*/
24-
disable: boolean;
24+
disabled: boolean;
2525

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

4545
export function initializeDefaultConfiguration(): ConfigurationModel {
4646
const config: ConfigurationModel = {
47-
disable: false,
47+
disabled: true,
4848
log_level: DiagLogLevel.INFO,
4949
node_resource_detectors: ['all'],
5050
resource: {},
@@ -56,7 +56,7 @@ export function initializeDefaultConfiguration(): ConfigurationModel {
5656
export interface ConfigAttributes {
5757
name: string;
5858
value: string | boolean | number | string[] | boolean[] | number[];
59-
type?:
59+
type:
6060
| 'string'
6161
| 'bool'
6262
| 'int'

experimental/packages/opentelemetry-configuration/test/ConfigProvider.test.ts

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,69 @@ import { DiagLogLevel } from '@opentelemetry/api';
2020
import { createConfigProvider } from '../src/ConfigProvider';
2121

2222
const defaultConfig: Configuration = {
23-
disable: false,
23+
disabled: false,
2424
log_level: DiagLogLevel.INFO,
2525
node_resource_detectors: ['all'],
2626
resource: {},
2727
};
2828

29+
const configFromFile: Configuration = {
30+
disabled: false,
31+
log_level: DiagLogLevel.DEBUG,
32+
node_resource_detectors: ['all'],
33+
resource: {
34+
schema_url: 'https://opentelemetry.io/schemas/1.16.0',
35+
attributes_list: 'service.namespace=my-namespace,service.version=1.0.0',
36+
attributes: [
37+
{
38+
name: 'service.name',
39+
value: 'unknown_service',
40+
type: 'string',
41+
},
42+
{
43+
name: 'string_key',
44+
value: 'value',
45+
type: 'string',
46+
},
47+
{
48+
name: 'bool_key',
49+
value: true,
50+
type: 'bool',
51+
},
52+
{
53+
name: 'int_key',
54+
value: 1,
55+
type: 'int',
56+
},
57+
{
58+
name: 'double_key',
59+
value: 1.1,
60+
type: 'double',
61+
},
62+
{
63+
name: 'string_array_key',
64+
value: ['value1', 'value2'],
65+
type: 'string_array',
66+
},
67+
{
68+
name: 'bool_array_key',
69+
value: [true, false],
70+
type: 'bool_array',
71+
},
72+
{
73+
name: 'int_array_key',
74+
value: [1, 2],
75+
type: 'int_array',
76+
},
77+
{
78+
name: 'double_array_key',
79+
value: [1.1, 2.2],
80+
type: 'double_array',
81+
},
82+
],
83+
},
84+
};
85+
2986
describe('ConfigProvider', function () {
3087
describe('get values from environment variables', function () {
3188
afterEach(function () {
@@ -47,7 +104,7 @@ describe('ConfigProvider', function () {
47104
process.env.OTEL_SDK_DISABLED = 'true';
48105
const expectedConfig: Configuration = {
49106
...defaultConfig,
50-
disable: true,
107+
disabled: true,
51108
};
52109
const configProvider = createConfigProvider();
53110
assert.deepStrictEqual(
@@ -111,7 +168,7 @@ describe('ConfigProvider', function () {
111168
const configProvider = createConfigProvider();
112169
assert.deepStrictEqual(
113170
configProvider.getInstrumentationConfig(),
114-
defaultConfig
171+
configFromFile
115172
);
116173
});
117174

experimental/packages/opentelemetry-configuration/test/fixtures/kitchen-sink.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ file_format: "1.0-rc.1"
1414
disabled: false
1515
# Configure the log level of the internal logger used by the SDK.
1616
# If omitted, info is used.
17-
log_level: info
17+
log_level: debug
1818
# Configure general attribute limits. See also tracer_provider.limits, logger_provider.limits.
1919
attribute_limits:
2020
# Configure max attribute value size.

package-lock.json

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)