Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5df60a4
parse attribute limits
maryliag Sep 23, 2025
2381346
Merge branch 'main' of github.com:open-telemetry/opentelemetry-js int…
maryliag Sep 23, 2025
b2bfada
set propagators
maryliag Sep 23, 2025
8f60964
parse limit of tracer provider
maryliag Sep 23, 2025
6933b03
add meter and logger
maryliag Sep 23, 2025
9dec6ab
fix lint
maryliag Sep 23, 2025
01497ab
add changelog
maryliag Sep 23, 2025
aaaed79
create check for propagator
maryliag Oct 2, 2025
2d0369c
Merge branch 'main' of github.com:open-telemetry/opentelemetry-js int…
maryliag Oct 2, 2025
bb00dc8
Merge branch 'main' of github.com:open-telemetry/opentelemetry-js int…
maryliag Oct 7, 2025
0ce3289
parse trace provider
maryliag Oct 7, 2025
860aae1
add changelog
maryliag Oct 7, 2025
2e06c42
update changelog
maryliag Oct 7, 2025
4f18dd4
Merge branch 'main' of github.com:open-telemetry/opentelemetry-js int…
maryliag Oct 8, 2025
da7762d
fix post merge
maryliag Oct 8, 2025
2cd03d7
fix pos merge
maryliag Oct 8, 2025
6265f0f
parse logger provider
maryliag Oct 8, 2025
8e0420d
add changelog
maryliag Oct 8, 2025
f26c8d0
Merge branch 'main' of github.com:open-telemetry/opentelemetry-js int…
maryliag Oct 8, 2025
7d09a23
fix lint
maryliag Oct 8, 2025
d5546b7
Merge branch 'main' of github.com:open-telemetry/opentelemetry-js int…
maryliag Oct 8, 2025
dd229ae
separate models
maryliag Oct 9, 2025
30fffce
Merge branch 'tracer-parse' into logger-parse
maryliag Oct 9, 2025
79d6a61
updates to model
maryliag Oct 9, 2025
60fafee
Merge branch 'main' of github.com:open-telemetry/opentelemetry-js int…
maryliag Oct 9, 2025
2ec2b47
Merge branch 'main' of github.com:open-telemetry/opentelemetry-js int…
maryliag Oct 9, 2025
1061b07
Merge branch 'main' of github.com:open-telemetry/opentelemetry-js int…
maryliag Oct 10, 2025
6c7f7a9
feedback from PR
maryliag Oct 10, 2025
2b48da4
fix endpoint
maryliag Oct 10, 2025
f40c414
Merge branch 'tracer-parse' into logger-parse
maryliag Oct 10, 2025
b324fd4
Merge branch 'main' of github.com:open-telemetry/opentelemetry-js int…
maryliag Oct 14, 2025
2b8a2d2
fixes with messed merge
maryliag Oct 14, 2025
e1913b4
Merge branch 'main' into logger-parse
maryliag Oct 15, 2025
eff2f69
Merge branch 'main' into logger-parse
maryliag Oct 16, 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 @@ -44,6 +44,7 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2
* feat(opentelemetry-configuration): parse more parameters from config file [#5955](https://github.com/open-telemetry/opentelemetry-js/pull/5955) @maryliag
* feat(exporter-prometheus): support withoutTargetInfo option [#5962](https://github.com/open-telemetry/opentelemetry-js/pull/5962) @cjihrig
* feat(opentelemetry-configuration): parse trace provider from config file [#5992](https://github.com/open-telemetry/opentelemetry-js/pull/5992) @maryliag
* feat(opentelemetry-configuration): parse logger provider from config file [#5995](https://github.com/open-telemetry/opentelemetry-js/pull/5995) @maryliag

### :bug: Bug Fixes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ function setLoggerProvider(config: ConfigurationModel): void {
);
if (attributeValueLengthLimit || attributeCountLimit) {
if (config.logger_provider == null) {
config.logger_provider = {};
config.logger_provider = { processors: [] };
}
if (config.logger_provider.limits == null) {
config.logger_provider.limits = { attribute_count_limit: 128 };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
import { diagLogLevelFromString, getStringFromEnv } from '@opentelemetry/core';
import {
AttributeLimits,
ConfigAttributes,
LoggerProvider,
MeterProvider,
Propagator,
ConfigurationModel,
Expand All @@ -41,6 +39,8 @@ import {
SpanProcessor,
TracerProvider,
} from './models/tracerProviderModel';
import { LoggerProvider } from './models/loggerProviderModel';
import { AttributeNameValue } from './models/resourceModel';

export class FileConfigProvider implements ConfigProvider {
private _config: ConfigurationModel;
Expand Down Expand Up @@ -98,14 +98,14 @@ function parseConfigFile(config: ConfigurationModel) {
config.resource = {};
}
const attrList = getStringFromConfigFile(
parsedContent['resource']?.['attributes_list']
parsedContent['resource']['attributes_list']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewing utils, I think resource could still be undefined here right? Is there a reason to drop the optional chaining?

);
if (attrList) {
config.resource.attributes_list = attrList;
}

const schemaUrl = getStringFromConfigFile(
parsedContent['resource']?.['schema_url']
parsedContent['resource']['schema_url']
);
if (schemaUrl) {
config.resource.schema_url = schemaUrl;
Expand All @@ -127,7 +127,7 @@ function parseConfigFile(config: ConfigurationModel) {

function setResourceAttributes(
config: ConfigurationModel,
attributes: ConfigAttributes[]
attributes: AttributeNameValue[]
) {
if (attributes) {
if (config.resource == null) {
Expand Down Expand Up @@ -254,7 +254,16 @@ function getConfigHeaders(
return null;
}

function parseConfigExporter(exporter: SpanExporter): SpanExporter {
enum ProviderType {
TRACER = 0,
METER = 1,
LOGGER = 2,
}

function parseConfigExporter(
exporter: SpanExporter,
providerType: ProviderType
): SpanExporter {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are now using this for multiple signals, do we need to return different exporters for each signal (e.g. LogExporter vs SpanExporter)?

const exporterType = Object.keys(exporter)[0];
let parsedExporter: SpanExporter = {};
let e;
Expand All @@ -265,15 +274,24 @@ function parseConfigExporter(exporter: SpanExporter): SpanExporter {
let headers;
let headersList;
let insecure;
let endpoint;

switch (providerType) {
case ProviderType.TRACER:
endpoint = 'http://localhost:4318/v1/traces';
break;
case ProviderType.LOGGER:
endpoint = 'http://localhost:4318/v1/logs';
break;
}

switch (exporterType) {
case 'otlp_http':
e = exporter['otlp_http'];
if (e) {
parsedExporter = {
otlp_http: {
endpoint:
getStringFromConfigFile(e['endpoint']) ??
'http://localhost:4318/v1/traces',
endpoint: getStringFromConfigFile(e['endpoint']) ?? endpoint,
timeout: getNumberFromConfigFile(e['timeout']) ?? 10000,
encoding:
getStringFromConfigFile(e['encoding']) === 'json'
Expand Down Expand Up @@ -460,7 +478,10 @@ function setTracerProvider(
if (processorType === 'batch') {
const element = tracerProvider['processors'][i]['batch'];
if (element) {
const parsedExporter = parseConfigExporter(element['exporter']);
const parsedExporter = parseConfigExporter(
element['exporter'],
ProviderType.TRACER
);
const batchConfig: SpanProcessor = {
batch: {
schedule_delay:
Expand All @@ -481,7 +502,10 @@ function setTracerProvider(
} else if (processorType === 'simple') {
const element = tracerProvider['processors'][i]['simple'];
if (element) {
const parsedExporter = parseConfigExporter(element['exporter']);
const parsedExporter = parseConfigExporter(
element['exporter'],
ProviderType.TRACER
);
const simpleConfig: SpanProcessor = {
simple: {
exporter: parsedExporter,
Expand Down Expand Up @@ -524,8 +548,9 @@ function setLoggerProvider(
): void {
if (loggerProvider) {
if (config.logger_provider == null) {
config.logger_provider = {};
config.logger_provider = { processors: [] };
}
// Limits
if (loggerProvider['limits']) {
const attributeValueLengthLimit = getNumberFromConfigFile(
loggerProvider['limits']['attribute_value_length_limit']
Expand All @@ -537,17 +562,124 @@ function setLoggerProvider(
if (config.logger_provider.limits == null) {
config.logger_provider.limits = { attribute_count_limit: 128 };
}

if (attributeValueLengthLimit) {
config.logger_provider.limits.attribute_value_length_limit =
attributeValueLengthLimit;
}

if (attributeCountLimit) {
config.logger_provider.limits.attribute_count_limit =
attributeCountLimit;
}
}
}

// Processors
if (loggerProvider['processors']) {
if (loggerProvider['processors'].length > 0) {
if (config.logger_provider == null) {
config.logger_provider = { processors: [] };
}
config.logger_provider.processors = [];
for (let i = 0; i < loggerProvider['processors'].length; i++) {
const processorType = Object.keys(loggerProvider['processors'][i])[0];
if (processorType === 'batch') {
const element = loggerProvider['processors'][i]['batch'];
if (element) {
const parsedExporter = parseConfigExporter(
element['exporter'],
ProviderType.LOGGER
);
const batchConfig: SpanProcessor = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a log processor?

batch: {
schedule_delay:
getNumberFromConfigFile(element['schedule_delay']) ?? 1000,
export_timeout:
getNumberFromConfigFile(element['export_timeout']) ?? 30000,
max_queue_size:
getNumberFromConfigFile(element['max_queue_size']) ?? 2048,
max_export_batch_size:
getNumberFromConfigFile(element['max_export_batch_size']) ??
512,
exporter: parsedExporter,
},
};

config.logger_provider.processors.push(batchConfig);
}
} else if (processorType === 'simple') {
const element = loggerProvider['processors'][i]['simple'];
if (element) {
const parsedExporter = parseConfigExporter(
element['exporter'],
ProviderType.LOGGER
);
const simpleConfig: SpanProcessor = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a log processor?

simple: {
exporter: parsedExporter,
},
};

config.logger_provider.processors.push(simpleConfig);
}
}
}
}
}

// logger_configurator/development
if (loggerProvider['logger_configurator/development']) {
const defaultConfigDisabled = getBooleanFromConfigFile(
loggerProvider['logger_configurator/development']['default_config']?.[
'disabled'
]
);
if (defaultConfigDisabled || defaultConfigDisabled === false) {
if (config.logger_provider == null) {
config.logger_provider = { processors: [] };
}
config.logger_provider['logger_configurator/development'] = {
default_config: {
disabled: defaultConfigDisabled,
},
};
}

if (
loggerProvider['logger_configurator/development'].loggers &&
loggerProvider['logger_configurator/development'].loggers.length > 0
) {
const loggers = [];
for (
let i = 0;
i < loggerProvider['logger_configurator/development'].loggers.length;
i++
Comment on lines +651 to +655
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit... could we replace with something like

const container = loggerProvider['logger_configurator/development'];
for (const logger of container.loggers) {
  ...
}

) {
const logger =
loggerProvider['logger_configurator/development'].loggers[i];
let disabled = false;
if (logger['config']) {
disabled =
getBooleanFromConfigFile(logger['config']['disabled']) ?? false;
}
const name = getStringFromConfigFile(logger['name']);
if (name) {
loggers.push({
name: name,
config: {
disabled: disabled,
},
});
}
}
if (config.logger_provider == null) {
config.logger_provider = { processors: [] };
}
if (config.logger_provider['logger_configurator/development'] == null) {
config.logger_provider['logger_configurator/development'] = {};
}
config.logger_provider['logger_configurator/development'].loggers =
loggers;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,26 @@
*/
'use strict';

export interface IncludeExclude {
/**
* Configure list of attribute key patterns to include from resource detectors.
* Attribute keys from resource detectors are evaluated to match as follows:
* * If the value of the attribute key exactly matches.
* * If the value of the attribute key matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none.
* If omitted, all attributes are included.
*/
include: string[];

/**
* Configure list of attribute key patterns to exclude from resource detectors. Applies after .resource.detectors.attributes.included (i.e. excluded has higher priority than included).
* Attribute keys from resource detectors are evaluated to match as follows:
* * If the value of the attribute key exactly matches.
* * If the value of the attribute key matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none.
* If omitted, .included attributes are included.
*/
exclude: string[];
}

export interface NameStringValuePair {
name: string;
value: string;
Expand Down
Loading