in packages/opentelemetry-node/lib/sdk.js [80:215]
function startNodeSDK(cfg = {}) {
log.trace('startNodeSDK cfg:', cfg);
// TODO: test behaviour with OTEL_SDK_DISABLED.
// Do we still log preamble? See NodeSDK _disabled handling.
// Do we still attempt to enableHostMetrics()?
if (getBooleanFromEnv('OTEL_SDK_DISABLED')) {
// Note: This differs slightly from current NodeSDK, which does *some*
// processing, even if disabled.
log.trace('startNodeSDK: disabled');
return {
shutdown() {
return Promise.resolve();
},
};
}
registerOTelDiagLogger(api);
/** @type {Partial<NodeSDKConfiguration>} */
const defaultConfig = {
resourceDetectors: resolveDetectors(cfg.resourceDetectors),
instrumentations: cfg.instrumentations || getInstrumentations(),
// Avoid setting `spanProcessor` or `traceExporter` to have NodeSDK
// use its `TracerProviderWithEnvExporters` for tracing setup.
};
const exporterPkgNameFromEnvVar = {
grpc: 'grpc',
'http/json': 'http',
'http/protobuf': 'proto', // default
};
// Logs config.
const logsExportProtocol =
getStringFromEnv('OTEL_EXPORTER_OTLP_LOGS_PROTOCOL') ||
getStringFromEnv('OTEL_EXPORTER_OTLP_PROTOCOL') ||
'http/protobuf';
let logExporterType = exporterPkgNameFromEnvVar[logsExportProtocol];
if (!logExporterType) {
log.warn(
`Logs exporter protocol "${logsExportProtocol}" unknown. Using default "http/protobuf" protocol`
);
logExporterType = 'proto';
}
log.trace(`Logs exporter protocol set to ${logsExportProtocol}`);
const {OTLPLogExporter} = require(
`@opentelemetry/exporter-logs-otlp-${logExporterType}`
);
defaultConfig.logRecordProcessors = [
new BatchLogRecordProcessor(new OTLPLogExporter()),
];
// Metrics config.
// TODO: support `OTEL_METRICS_EXPORTER`, including being a list of exporters (e.g. console, debug)
// TODO: metrics exporter should do for metrics what `TracerProviderWithEnvExporters` does for traces, does that include `url` export endpoint?
// Setting default temporality to delta to avoid histogram storing issues in ES.
// Or log if there is a different value set by the user
// Ref: https://github.com/elastic/opentelemetry/pull/63
const temporalityPreference = getStringFromEnv(
'OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE'
);
if (typeof temporalityPreference === 'undefined') {
process.env.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE = 'delta';
} else if (temporalityPreference !== 'delta') {
const docsUrl =
'https://elastic.github.io/opentelemetry/compatibility/limitations.html#ingestion-of-metrics-data';
log.info(
`Metrics temporality preference set to "${temporalityPreference}". Use "delta" temporality if you want to store Histogram metrics in Elasticsearch. See ${docsUrl}`
);
}
// The implementation in SDK does treats the undefined and 'none' value
// as same. https://github.com/open-telemetry/opentelemetry-js/blob/dac72912b3a895c91ee95cfa39a22a916411ba4c/experimental/packages/opentelemetry-sdk-node/src/sdk.ts#L117
// According to https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/#exporter-selection
// the default should be 'otlp' so IMHO the implementation is wrong
// We need to set the default value if env var is not defined until it's fixed in
// upstream SDK
// TODO: remove this when https://github.com/open-telemetry/opentelemetry-js/issues/5612 is closed
if (!process.env.OTEL_METRICS_EXPORTER?.trim()) {
process.env.OTEL_METRICS_EXPORTER = 'otlp';
}
const metricsExporters = getStringListFromEnv('OTEL_METRICS_EXPORTER');
const metricsEnabled = metricsExporters.every((e) => e !== 'none');
if (metricsEnabled) {
defaultConfig.views = [
// Add views for `host-metrics` to avoid excess of data being sent
// to the server.
...HOST_METRICS_VIEWS,
];
}
const config = Object.assign(defaultConfig, cfg);
setupEnvironment();
const sdk = new NodeSDK(config);
if (config.elasticSetupShutdownHandlers ?? true) {
setupShutdownHandlers(sdk);
}
log.info(
{
preamble: true,
distroVersion: DISTRO_VERSION,
env: {
// For darwin: https://en.wikipedia.org/wiki/Darwin_%28operating_system%29#Release_history
os: `${os.platform()} ${os.release()}`,
arch: os.arch(),
runtime: `Node.js ${process.version}`,
},
// The "config" object structure is not stable.
config: {
logLevel: luggite.nameFromLevel[log.level()] ?? log.level(),
},
},
'start EDOT Node.js'
);
sdk.start(); // .start() *does* use `process.env` though I think it should not.
restoreEnvironment();
if (metricsEnabled) {
// TODO: make this configurable, user might collect host metrics with a separate utility. Perhaps use 'host-metrics' in DISABLED_INSTRs existing env var.
enableHostMetrics();
}
// Return an object that is a subset of the upstream NodeSDK interface,
// just enough to shutdown.
return {
shutdown() {
return sdk.shutdown();
},
};
}