Skip to content

Commit 1db6285

Browse files
maryliagpichlermarctrentm
authored
feat(opentelemetry-configuration): parse of array objects on configuration file (#5947)
Co-authored-by: Marc Pichler <[email protected]> Co-authored-by: Trent Mick <[email protected]>
1 parent b11baa1 commit 1db6285

File tree

5 files changed

+191
-3
lines changed

5 files changed

+191
-3
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
* feat(sampler-composite): Added experimental implementations of draft composite sampling spec [#5839](https://github.com/open-telemetry/opentelemetry-js/pull/5839) @anuraaga
1515
* feat(opentelemetry-configuration): add more attributes to config model [#5826](https://github.com/open-telemetry/opentelemetry-js/pull/5826) @maryliag
1616
* feat(opentelemetry-configuration): Parse of Configuration File [#5875](https://github.com/open-telemetry/opentelemetry-js/pull/5875) @maryliag
17+
* feat(opentelemetry-configuration): parse of array objects on configuration file [#5947](https://github.com/open-telemetry/opentelemetry-js/pull/5947) @maryliag
1718

1819
### :bug: Bug Fixes
1920

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

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@ import * as fs from 'fs';
2525
import * as yaml from 'yaml';
2626
import {
2727
getBooleanFromConfigFile,
28+
getBooleanListFromConfigFile,
2829
getNumberFromConfigFile,
30+
getNumberListFromConfigFile,
2931
getStringFromConfigFile,
32+
getStringListFromConfigFile,
3033
} from './utils';
3134

3235
export class FileConfigProvider implements ConfigProvider {
@@ -110,9 +113,33 @@ function setResourceAttributes(
110113
config.resource.attributes = [];
111114
for (let i = 0; i < attributes.length; i++) {
112115
const att = attributes[i];
116+
let value = att['value'];
117+
switch (att['type']) {
118+
case 'bool':
119+
value = getBooleanFromConfigFile(value);
120+
break;
121+
case 'bool_array':
122+
value = getBooleanListFromConfigFile(value);
123+
break;
124+
case 'int':
125+
case 'double':
126+
value = getNumberFromConfigFile(value);
127+
break;
128+
case 'int_array':
129+
case 'double_array':
130+
value = getNumberListFromConfigFile(value);
131+
break;
132+
case 'string_array':
133+
value = getStringListFromConfigFile(value);
134+
break;
135+
default:
136+
value = getStringFromConfigFile(value);
137+
break;
138+
}
139+
113140
config.resource.attributes.push({
114141
name: getStringFromConfigFile(att['name']) ?? '',
115-
value: att['value'],
142+
value: value,
116143
type: att['type'] ?? 'string',
117144
});
118145
}

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,14 @@ export function initializeDefaultConfiguration(): ConfigurationModel {
162162

163163
export interface ConfigAttributes {
164164
name: string;
165-
value: string | boolean | number | string[] | boolean[] | number[];
165+
value:
166+
| string
167+
| boolean
168+
| number
169+
| string[]
170+
| boolean[]
171+
| number[]
172+
| undefined;
166173
type:
167174
| 'string'
168175
| 'bool'

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

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,34 @@ export function getBooleanFromConfigFile(value: unknown): boolean | undefined {
3939
}
4040
}
4141

42+
/**
43+
* Retrieves a list of booleans from a configuration file parameter.
44+
* - Uses ',' as the delimiter.
45+
* - Trims leading and trailing whitespace from each entry.
46+
* - Excludes empty entries.
47+
* - Returns `undefined` if the variable is empty or contains only whitespace.
48+
* - Returns an empty array if all entries are empty or whitespace.
49+
*
50+
* @param {unknown} value - The value from the config file.
51+
* @returns {boolean[] | undefined} - The list of strings or `undefined`.
52+
*/
53+
export function getBooleanListFromConfigFile(
54+
value: unknown
55+
): boolean[] | undefined {
56+
const list = getStringFromConfigFile(value)?.split(',');
57+
if (list) {
58+
const filteredList = [];
59+
for (let i = 0; i < list.length; i++) {
60+
const element = getBooleanFromConfigFile(list[i]);
61+
if (element != null) {
62+
filteredList.push(element);
63+
}
64+
}
65+
return filteredList;
66+
}
67+
return list;
68+
}
69+
4270
/**
4371
* Retrieves a number from a configuration file parameter.
4472
* - Returns `undefined` if the environment variable is empty, unset, or contains only whitespace.
@@ -63,9 +91,37 @@ export function getNumberFromConfigFile(value: unknown): number | undefined {
6391
return n;
6492
}
6593

94+
/**
95+
* Retrieves a list of numbers from a configuration file parameter.
96+
* - Uses ',' as the delimiter.
97+
* - Trims leading and trailing whitespace from each entry.
98+
* - Excludes empty entries.
99+
* - Returns `undefined` if the variable is empty or contains only whitespace.
100+
* - Returns an empty array if all entries are empty or whitespace.
101+
*
102+
* @param {unknown} value - The value from the config file.
103+
* @returns {number[] | undefined} - The list of numbers or `undefined`.
104+
*/
105+
export function getNumberListFromConfigFile(
106+
value: unknown
107+
): number[] | undefined {
108+
const list = getStringFromConfigFile(value)?.split(',');
109+
if (list) {
110+
const filteredList = [];
111+
for (let i = 0; i < list.length; i++) {
112+
const element = getNumberFromConfigFile(list[i]);
113+
if (element) {
114+
filteredList.push(element);
115+
}
116+
}
117+
return filteredList;
118+
}
119+
return list;
120+
}
121+
66122
/**
67123
* Retrieves a string from a configuration file parameter.
68-
* - Returns `undefined` if the environment variable is empty, unset, or contains only whitespace.
124+
* - Returns `undefined` if the variable is empty, unset, or contains only whitespace.
69125
*
70126
* @param {unknown} value - The value from the config file.
71127
* @returns {string | undefined} - The string value or `undefined`.
@@ -77,3 +133,23 @@ export function getStringFromConfigFile(value: unknown): string | undefined {
77133
}
78134
return raw;
79135
}
136+
137+
/**
138+
* Retrieves a list of strings from a configuration file parameter.
139+
* - Uses ',' as the delimiter.
140+
* - Trims leading and trailing whitespace from each entry.
141+
* - Excludes empty entries.
142+
* - Returns `undefined` if the variable is empty or contains only whitespace.
143+
* - Returns an empty array if all entries are empty or whitespace.
144+
*
145+
* @param {unknown} value - The value from the config file.
146+
* @returns {string[] | undefined} - The list of strings or `undefined`.
147+
*/
148+
export function getStringListFromConfigFile(
149+
value: unknown
150+
): string[] | undefined {
151+
return getStringFromConfigFile(value)
152+
?.split(',')
153+
.map(v => v.trim())
154+
.filter(s => s !== '');
155+
}

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

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@ import * as sinon from 'sinon';
1919
import { diag } from '@opentelemetry/api';
2020
import {
2121
getBooleanFromConfigFile,
22+
getBooleanListFromConfigFile,
2223
getNumberFromConfigFile,
24+
getNumberListFromConfigFile,
2325
getStringFromConfigFile,
26+
getStringListFromConfigFile,
2427
} from '../src/utils';
2528

2629
describe('config utils', function () {
@@ -44,6 +47,34 @@ describe('config utils', function () {
4447
);
4548
});
4649

50+
it('should return correct values for getBooleanListFromConfigFile', function () {
51+
assert.deepStrictEqual(getBooleanListFromConfigFile(null), undefined);
52+
assert.deepStrictEqual(getBooleanListFromConfigFile(' '), undefined);
53+
assert.deepStrictEqual(getBooleanListFromConfigFile(' , '), []);
54+
assert.deepStrictEqual(getBooleanListFromConfigFile(true), [true]);
55+
assert.deepStrictEqual(getBooleanListFromConfigFile('true'), [true]);
56+
assert.deepStrictEqual(getBooleanListFromConfigFile(false), [false]);
57+
assert.deepStrictEqual(getBooleanListFromConfigFile('false'), [false]);
58+
assert.deepStrictEqual(
59+
getBooleanListFromConfigFile('true,false,false,true'),
60+
[true, false, false, true]
61+
);
62+
assert.deepStrictEqual(
63+
getBooleanListFromConfigFile('true,false,,,true,false'),
64+
[true, false, true, false]
65+
);
66+
67+
const warnStub = sinon.stub(diag, 'warn');
68+
assert.deepStrictEqual(getBooleanListFromConfigFile('non-boolean'), []);
69+
sinon.assert.calledOnceWithMatch(
70+
warnStub,
71+
`Unknown value 'non-boolean', expected 'true' or 'false'`
72+
);
73+
assert.deepStrictEqual(getBooleanListFromConfigFile('non-boolean,false'), [
74+
false,
75+
]);
76+
});
77+
4778
it('should return correct values for getNumberFromConfigFile', function () {
4879
assert.strictEqual(getNumberFromConfigFile(null), undefined);
4980
assert.strictEqual(getNumberFromConfigFile(' '), undefined);
@@ -59,11 +90,57 @@ describe('config utils', function () {
5990
);
6091
});
6192

93+
it('should return correct values for getNumberListFromConfigFile', function () {
94+
assert.deepStrictEqual(getNumberListFromConfigFile(null), undefined);
95+
assert.deepStrictEqual(getNumberListFromConfigFile(' '), undefined);
96+
assert.deepStrictEqual(getNumberListFromConfigFile(' , '), []);
97+
assert.deepStrictEqual(getNumberListFromConfigFile(5), [5]);
98+
assert.deepStrictEqual(getNumberListFromConfigFile('7'), [7]);
99+
assert.deepStrictEqual(
100+
getNumberListFromConfigFile('1,2,3,4'),
101+
[1, 2, 3, 4]
102+
);
103+
assert.deepStrictEqual(
104+
getNumberListFromConfigFile('5,6,,,7,8'),
105+
[5, 6, 7, 8]
106+
);
107+
108+
const warnStub = sinon.stub(diag, 'warn');
109+
assert.deepStrictEqual(getNumberListFromConfigFile('non-number'), []);
110+
sinon.assert.calledOnceWithMatch(
111+
warnStub,
112+
`Unknown value 'non-number', expected a number`
113+
);
114+
assert.deepStrictEqual(getNumberListFromConfigFile('non-number,10'), [10]);
115+
});
116+
62117
it('should return correct values for getStringFromConfigFile', function () {
63118
assert.strictEqual(getStringFromConfigFile(null), undefined);
64119
assert.strictEqual(getStringFromConfigFile(' '), undefined);
65120
assert.strictEqual(getStringFromConfigFile(undefined), undefined);
66121
assert.strictEqual(getStringFromConfigFile(1), '1');
67122
assert.strictEqual(getStringFromConfigFile('string-value'), 'string-value');
68123
});
124+
125+
it('should return correct values for getStringListFromConfigFile', function () {
126+
assert.deepStrictEqual(getStringListFromConfigFile(null), undefined);
127+
assert.deepStrictEqual(getStringListFromConfigFile(' '), undefined);
128+
assert.deepStrictEqual(getStringListFromConfigFile(' , '), []);
129+
assert.deepStrictEqual(getStringListFromConfigFile(1), ['1']);
130+
assert.deepStrictEqual(getStringListFromConfigFile('string-value'), [
131+
'string-value',
132+
]);
133+
assert.deepStrictEqual(getStringListFromConfigFile('v1,v2,v3,v4'), [
134+
'v1',
135+
'v2',
136+
'v3',
137+
'v4',
138+
]);
139+
assert.deepStrictEqual(getStringListFromConfigFile('v5,v6,,,v7,v8'), [
140+
'v5',
141+
'v6',
142+
'v7',
143+
'v8',
144+
]);
145+
});
69146
});

0 commit comments

Comments
 (0)