Skip to content

Commit ebfb75f

Browse files
authored
feat(configuration): set logger provider exporter type from env variable (#6104)
1 parent b4ff5c3 commit ebfb75f

File tree

4 files changed

+274
-52
lines changed

4 files changed

+274
-52
lines changed

experimental/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2
1111
### :rocket: Features
1212

1313
* feat(exporter-prometheus): support withoutScopeInfo option [#5993](https://github.com/open-telemetry/opentelemetry-js/pull/5993) @cjihrig
14-
* feat(configuration): improvements on package [#6101](https://github.com/open-telemetry/opentelemetry-js/pull/6101) @maryliag
14+
* refactor(configuration): improvements on package [#6101](https://github.com/open-telemetry/opentelemetry-js/pull/6101) @maryliag
15+
* feat(configuration): set logger provider exporter type from env variable [#6104](https://github.com/open-telemetry/opentelemetry-js/pull/6104) @maryliag
1516

1617
### :bug: Bug Fixes
1718

experimental/packages/configuration/src/EnvironmentConfigFactory.ts

Lines changed: 119 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import {
3131
ExporterDefaultHistogramAggregation,
3232
ExporterTemporalityPreference,
3333
} from './models/meterProviderModel';
34+
import { OtlpHttpEncoding } from './models/commonModel';
35+
import { diag } from '@opentelemetry/api';
3436

3537
/**
3638
* EnvironmentConfigProvider provides a configuration based on environment variables.
@@ -456,57 +458,123 @@ export function setLoggerProvider(config: ConfigurationModel): void {
456458
batch.max_export_batch_size = maxExportBatchSize;
457459
}
458460

459-
const endpoint =
460-
getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_ENDPOINT') ??
461-
(getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT')
462-
? `${getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT')}/v1/logs`
463-
: null);
464-
if (endpoint && batch.exporter.otlp_http) {
465-
batch.exporter.otlp_http.endpoint = endpoint;
466-
}
467-
468-
const certificateFile =
469-
getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE') ??
470-
getStringFromEnv('OTEL_EXPORTER_OTLP_CERTIFICATE');
471-
if (certificateFile && batch.exporter.otlp_http) {
472-
batch.exporter.otlp_http.certificate_file = certificateFile;
473-
}
474-
475-
const clientKeyFile =
476-
getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY') ??
477-
getStringFromEnv('OTEL_EXPORTER_OTLP_CLIENT_KEY');
478-
if (clientKeyFile && batch.exporter.otlp_http) {
479-
batch.exporter.otlp_http.client_key_file = clientKeyFile;
480-
}
481-
482-
const clientCertificateFile =
483-
getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE') ??
484-
getStringFromEnv('OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE');
485-
if (clientCertificateFile && batch.exporter.otlp_http) {
486-
batch.exporter.otlp_http.client_certificate_file = clientCertificateFile;
487-
}
488-
489-
const compression =
490-
getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_COMPRESSION') ??
491-
getStringFromEnv('OTEL_EXPORTER_OTLP_COMPRESSION');
492-
if (compression && batch.exporter.otlp_http) {
493-
batch.exporter.otlp_http.compression = compression;
494-
}
495-
496-
const timeout =
497-
getNumberFromEnv('OTEL_EXPORTER_OTLP_LOGS_TIMEOUT') ??
498-
getNumberFromEnv('OTEL_EXPORTER_OTLP_TIMEOUT');
499-
if (timeout && batch.exporter.otlp_http) {
500-
batch.exporter.otlp_http.timeout = timeout;
501-
}
502-
503-
const headersList =
504-
getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_HEADERS') ??
505-
getStringFromEnv('OTEL_EXPORTER_OTLP_HEADERS');
506-
if (headersList && batch.exporter.otlp_http) {
507-
batch.exporter.otlp_http.headers_list = headersList;
461+
const exportersType = Array.from(
462+
new Set(getStringListFromEnv('OTEL_LOGS_EXPORTER'))
463+
);
464+
if (exportersType.length === 0) {
465+
exportersType.push('otlp');
466+
}
467+
468+
config.logger_provider.processors = [];
469+
if (exportersType.includes('none')) {
470+
diag.info(
471+
`OTEL_LOGS_EXPORTER contains "none". Logger provider will not be initialized.`
472+
);
473+
return;
474+
}
475+
476+
for (let i = 0; i < exportersType.length; i++) {
477+
const exporterType = exportersType[i];
478+
const batchInfo = { ...batch };
479+
if (exporterType === 'console') {
480+
config.logger_provider.processors.push({
481+
simple: { exporter: { console: {} } },
482+
});
483+
} else {
484+
// 'otlp' and default
485+
const protocol =
486+
getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_PROTOCOL') ??
487+
getStringFromEnv('OTEL_EXPORTER_OTLP_PROTOCOL') ??
488+
'http/protobuf';
489+
const certificateFile =
490+
getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE') ??
491+
getStringFromEnv('OTEL_EXPORTER_OTLP_CERTIFICATE');
492+
const clientKeyFile =
493+
getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY') ??
494+
getStringFromEnv('OTEL_EXPORTER_OTLP_CLIENT_KEY');
495+
const clientCertificateFile =
496+
getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE') ??
497+
getStringFromEnv('OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE');
498+
const compression =
499+
getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_COMPRESSION') ??
500+
getStringFromEnv('OTEL_EXPORTER_OTLP_COMPRESSION');
501+
const timeout =
502+
getNumberFromEnv('OTEL_EXPORTER_OTLP_LOGS_TIMEOUT') ??
503+
getNumberFromEnv('OTEL_EXPORTER_OTLP_TIMEOUT') ??
504+
10000;
505+
const headersList =
506+
getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_HEADERS') ??
507+
getStringFromEnv('OTEL_EXPORTER_OTLP_HEADERS');
508+
509+
if (protocol === 'grpc') {
510+
delete batchInfo.exporter.otlp_http;
511+
batchInfo.exporter.otlp_grpc = {};
512+
const endpoint =
513+
getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_ENDPOINT') ??
514+
getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT') ??
515+
'http://localhost:4317';
516+
if (endpoint) {
517+
batchInfo.exporter.otlp_grpc.endpoint = endpoint;
518+
}
519+
if (certificateFile) {
520+
batchInfo.exporter.otlp_grpc.certificate_file = certificateFile;
521+
}
522+
if (clientKeyFile) {
523+
batchInfo.exporter.otlp_grpc.client_key_file = clientKeyFile;
524+
}
525+
if (clientCertificateFile) {
526+
batchInfo.exporter.otlp_grpc.client_certificate_file =
527+
clientCertificateFile;
528+
}
529+
if (compression) {
530+
batchInfo.exporter.otlp_grpc.compression = compression;
531+
}
532+
if (timeout) {
533+
batchInfo.exporter.otlp_grpc.timeout = timeout;
534+
}
535+
if (headersList) {
536+
batchInfo.exporter.otlp_grpc.headers_list = headersList;
537+
}
538+
} else {
539+
if (batchInfo.exporter.otlp_http == null) {
540+
batchInfo.exporter.otlp_http = {};
541+
}
542+
const endpoint =
543+
getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_ENDPOINT') ??
544+
(getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT')
545+
? `${getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT')}/v1/logs`
546+
: null);
547+
if (endpoint) {
548+
batchInfo.exporter.otlp_http.endpoint = endpoint;
549+
}
550+
if (certificateFile) {
551+
batchInfo.exporter.otlp_http.certificate_file = certificateFile;
552+
}
553+
if (clientKeyFile) {
554+
batchInfo.exporter.otlp_http.client_key_file = clientKeyFile;
555+
}
556+
if (clientCertificateFile) {
557+
batchInfo.exporter.otlp_http.client_certificate_file =
558+
clientCertificateFile;
559+
}
560+
if (compression) {
561+
batchInfo.exporter.otlp_http.compression = compression;
562+
}
563+
if (timeout) {
564+
batchInfo.exporter.otlp_http.timeout = timeout;
565+
}
566+
if (headersList) {
567+
batchInfo.exporter.otlp_http.headers_list = headersList;
568+
}
569+
570+
if (protocol === 'http/json') {
571+
batchInfo.exporter.otlp_http.encoding = OtlpHttpEncoding.JSON;
572+
} else if (protocol === 'http/protobuf') {
573+
batchInfo.exporter.otlp_http.encoding = OtlpHttpEncoding.Protobuf;
574+
}
575+
}
576+
config.logger_provider.processors.push({ batch: batchInfo });
577+
}
508578
}
509-
510-
config.logger_provider.processors[0].batch = batch;
511579
}
512580
}

experimental/packages/configuration/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@
1616

1717
export type { ConfigFactory } from './IConfigFactory';
1818
export type { ConfigurationModel } from './models/configModel';
19+
export type { LogRecordExporter as LogRecordExporterModel } from './models/loggerProviderModel';
1920
export { createConfigFactory } from './ConfigFactory';

experimental/packages/configuration/test/ConfigProvider.test.ts renamed to experimental/packages/configuration/test/ConfigFactory.test.ts

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,158 @@ describe('ConfigProvider', function () {
10301030
assert.deepStrictEqual(configProvider.getConfigModel(), expectedConfig);
10311031
});
10321032

1033+
it('should return config with logger_provider with console exporter', function () {
1034+
process.env.OTEL_LOGS_EXPORTER = 'console';
1035+
const expectedConfig: ConfigurationModel = {
1036+
...defaultConfig,
1037+
logger_provider: {
1038+
limits: {
1039+
attribute_count_limit: 128,
1040+
},
1041+
processors: [
1042+
{
1043+
simple: {
1044+
exporter: {
1045+
console: {},
1046+
},
1047+
},
1048+
},
1049+
],
1050+
},
1051+
};
1052+
const configProvider = createConfigFactory();
1053+
assert.deepStrictEqual(configProvider.getConfigModel(), expectedConfig);
1054+
});
1055+
1056+
it('should return config with logger_provider with no exporter', function () {
1057+
process.env.OTEL_LOGS_EXPORTER = 'none,console';
1058+
const expectedConfig: ConfigurationModel = {
1059+
...defaultConfig,
1060+
logger_provider: {
1061+
limits: {
1062+
attribute_count_limit: 128,
1063+
},
1064+
processors: [],
1065+
},
1066+
};
1067+
const configProvider = createConfigFactory();
1068+
assert.deepStrictEqual(configProvider.getConfigModel(), expectedConfig);
1069+
});
1070+
1071+
it('should return config with logger_provider with exporter list', function () {
1072+
process.env.OTEL_LOGS_EXPORTER = 'otlp,console';
1073+
const expectedConfig: ConfigurationModel = {
1074+
...defaultConfig,
1075+
logger_provider: {
1076+
limits: {
1077+
attribute_count_limit: 128,
1078+
},
1079+
processors: [
1080+
{
1081+
batch: {
1082+
schedule_delay: 1000,
1083+
export_timeout: 30000,
1084+
max_queue_size: 2048,
1085+
max_export_batch_size: 512,
1086+
exporter: {
1087+
otlp_http: {
1088+
endpoint: 'http://localhost:4318/v1/logs',
1089+
timeout: 10000,
1090+
encoding: OtlpHttpEncoding.Protobuf,
1091+
},
1092+
},
1093+
},
1094+
},
1095+
{
1096+
simple: {
1097+
exporter: {
1098+
console: {},
1099+
},
1100+
},
1101+
},
1102+
],
1103+
},
1104+
};
1105+
const configProvider = createConfigFactory();
1106+
assert.deepStrictEqual(configProvider.getConfigModel(), expectedConfig);
1107+
});
1108+
1109+
it('should return config with logger_provider with otlp grpc exporter', function () {
1110+
process.env.OTEL_LOGS_EXPORTER = 'otlp';
1111+
process.env.OTEL_EXPORTER_OTLP_PROTOCOL = 'grpc';
1112+
process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = 'http://localhost:4317';
1113+
process.env.OTEL_EXPORTER_OTLP_TIMEOUT = '10000';
1114+
process.env.OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE = 'log-cert.pem';
1115+
process.env.OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY = 'log-key.pem';
1116+
process.env.OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE =
1117+
'log-client-cert.pem';
1118+
process.env.OTEL_EXPORTER_OTLP_LOGS_HEADERS = 'host=localhost';
1119+
process.env.OTEL_EXPORTER_OTLP_LOGS_COMPRESSION = 'gzip';
1120+
const expectedConfig: ConfigurationModel = {
1121+
...defaultConfig,
1122+
logger_provider: {
1123+
limits: {
1124+
attribute_count_limit: 128,
1125+
},
1126+
processors: [
1127+
{
1128+
batch: {
1129+
schedule_delay: 1000,
1130+
export_timeout: 30000,
1131+
max_queue_size: 2048,
1132+
max_export_batch_size: 512,
1133+
exporter: {
1134+
otlp_grpc: {
1135+
endpoint: 'http://localhost:4317',
1136+
timeout: 10000,
1137+
certificate_file: 'log-cert.pem',
1138+
client_key_file: 'log-key.pem',
1139+
client_certificate_file: 'log-client-cert.pem',
1140+
headers_list: 'host=localhost',
1141+
compression: 'gzip',
1142+
},
1143+
},
1144+
},
1145+
},
1146+
],
1147+
},
1148+
};
1149+
const configProvider = createConfigFactory();
1150+
assert.deepStrictEqual(configProvider.getConfigModel(), expectedConfig);
1151+
});
1152+
1153+
it('should return config with logger_provider with otlp http/json exporter', function () {
1154+
process.env.OTEL_LOGS_EXPORTER = 'otlp';
1155+
process.env.OTEL_EXPORTER_OTLP_PROTOCOL = 'http/json';
1156+
const expectedConfig: ConfigurationModel = {
1157+
...defaultConfig,
1158+
logger_provider: {
1159+
limits: {
1160+
attribute_count_limit: 128,
1161+
},
1162+
processors: [
1163+
{
1164+
batch: {
1165+
schedule_delay: 1000,
1166+
export_timeout: 30000,
1167+
max_queue_size: 2048,
1168+
max_export_batch_size: 512,
1169+
exporter: {
1170+
otlp_http: {
1171+
endpoint: 'http://localhost:4318/v1/logs',
1172+
timeout: 10000,
1173+
encoding: OtlpHttpEncoding.JSON,
1174+
},
1175+
},
1176+
},
1177+
},
1178+
],
1179+
},
1180+
};
1181+
const configProvider = createConfigFactory();
1182+
assert.deepStrictEqual(configProvider.getConfigModel(), expectedConfig);
1183+
});
1184+
10331185
it('should use backup options for exporters', function () {
10341186
process.env.OTEL_EXPORTER_OTLP_CERTIFICATE =
10351187
'backup_certificate_file.pem';

0 commit comments

Comments
 (0)