-
Notifications
You must be signed in to change notification settings - Fork 13
feat(otel-node)!: update to SDK 2.0 #663
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 14 commits
5434be2
953df8d
812b216
41526d0
589e5a3
32b657d
0df1c2d
10f9d28
60cba77
f9d1ed7
115d231
921295f
1806b05
a9cf349
9bf2054
fd51e00
3c28ba4
0edea7d
924354c
d2f4e36
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,7 +17,9 @@ const {resolveDetectors} = require('./detectors'); | |
| const { | ||
| setupEnvironment, | ||
| restoreEnvironment, | ||
| getEnvVar, | ||
| getEnvString, | ||
| getEnvBoolean, | ||
| getEnvNumber, | ||
| } = require('./environment'); | ||
| const {getInstrumentations} = require('./instrumentations'); | ||
| const {enableHostMetrics, HOST_METRICS_VIEWS} = require('./metrics/host'); | ||
|
|
@@ -53,7 +55,7 @@ class ElasticNodeSDK extends NodeSDK { | |
| // Get logs exporter protocol based on environment. | ||
| const logsExportProtocol = | ||
| process.env.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL || | ||
| getEnvVar('OTEL_EXPORTER_OTLP_PROTOCOL'); | ||
| getEnvString('OTEL_EXPORTER_OTLP_PROTOCOL'); | ||
| let logExporterType = exporterPkgNameFromEnvVar[logsExportProtocol]; | ||
| if (!logExporterType) { | ||
| log.warn( | ||
|
|
@@ -77,12 +79,15 @@ class ElasticNodeSDK extends NodeSDK { | |
| // TODO what `temporalityPreference`? | ||
|
|
||
| // Disable metrics by config | ||
| const metricsDisabled = getEnvVar('ELASTIC_OTEL_METRICS_DISABLED'); | ||
| const metricsDisabled = getEnvBoolean( | ||
| 'ELASTIC_OTEL_METRICS_DISABLED', | ||
| false | ||
| ); | ||
| if (!metricsDisabled) { | ||
| // Get metrics exporter protocol based on environment. | ||
| const metricsExportProtocol = | ||
| process.env.OTEL_EXPORTER_OTLP_METRICS_PROTOCOL || | ||
| getEnvVar('OTEL_EXPORTER_OTLP_PROTOCOL'); | ||
| getEnvString('OTEL_EXPORTER_OTLP_PROTOCOL'); | ||
|
||
| let metricExporterType = | ||
| exporterPkgNameFromEnvVar[metricsExportProtocol]; | ||
| if (!metricExporterType) { | ||
|
|
@@ -98,8 +103,16 @@ class ElasticNodeSDK extends NodeSDK { | |
| `@opentelemetry/exporter-metrics-otlp-${metricExporterType}` | ||
| ); | ||
|
|
||
| const metricsInterval = getEnvVar('OTEL_METRIC_EXPORT_INTERVAL'); | ||
| const metricsTimeout = getEnvVar('OTEL_METRIC_EXPORT_TIMEOUT'); | ||
| // Note: Default values has been taken from the specs | ||
| // https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/#periodic-exporting-metricreader | ||
| const metricsInterval = getEnvNumber( | ||
| 'OTEL_METRIC_EXPORT_INTERVAL', | ||
| 60000 | ||
| ); | ||
| const metricsTimeout = getEnvNumber( | ||
| 'OTEL_METRIC_EXPORT_TIMEOUT', | ||
| 30000 | ||
| ); | ||
| defaultConfig.metricReader = | ||
| new metrics.PeriodicExportingMetricReader({ | ||
| exporter: new OTLPMetricExporter(), | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,55 +3,16 @@ | |
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| // NOTE: this API may be removed in future | ||
| // ref: https://github.com/open-telemetry/opentelemetry-js/issues/5172 | ||
| const {getEnv} = require('@opentelemetry/core'); | ||
| const { | ||
| getBooleanFromEnv, | ||
| getNumberFromEnv, | ||
| getStringListFromEnv, | ||
| getStringFromEnv, | ||
| } = require('@opentelemetry/core'); | ||
|
|
||
| /** @type {NodeJS.ProcessEnv} */ | ||
| const envToRestore = {}; | ||
|
|
||
| /** | ||
| * Returns an array of strings from the given input. If undefined returns the fallback | ||
| * value. | ||
| * @param {string | undefined} str | ||
| * @param {string[]} [fallback=[]] | ||
| * @returns {string[]} | ||
| */ | ||
| function parseStringList(str, fallback = []) { | ||
| if (!str) { | ||
| return fallback; | ||
| } | ||
| return str.split(',').map((s) => s.trim()); | ||
| } | ||
|
|
||
| /** | ||
| * Returns a boolean from the given input | ||
| * @param {string | undefined} str | ||
| * @param {boolean} fallback | ||
| * @returns {boolean} | ||
| */ | ||
| function parseBoolean(str, fallback) { | ||
| if (!str) { | ||
| return fallback; | ||
| } | ||
| return str.toLowerCase() === 'true'; | ||
| } | ||
|
|
||
| /** | ||
| * Returns a boolean from te given input | ||
| * @param {string | undefined} str | ||
| * @param {number} fallback | ||
| * @returns {number} | ||
| */ | ||
| function parseNumber(str, fallback) { | ||
| if (!str) { | ||
| return fallback; | ||
| } | ||
|
|
||
| const num = Number(str); | ||
| return isNaN(num) ? fallback : num; | ||
| } | ||
|
|
||
| /** | ||
| * This funtion makes necessari changes to the environment so: | ||
| * - Avoid OTEL's NodeSDK known warnings (eg. OTEL_TRACES_EXPORTER not set) | ||
|
|
@@ -86,75 +47,42 @@ function setupEnvironment() { | |
| function restoreEnvironment() { | ||
| Object.keys(envToRestore).forEach((k) => { | ||
| process.env[k] = envToRestore[k]; | ||
| delete envToRestore[k]; | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. note for reviewer: IMO the getters defined below should take values directly from |
||
| }); | ||
| } | ||
|
|
||
| /** | ||
| * @typedef {Object} EdotEnv | ||
| * @property {string[]} OTEL_NODE_RESOURCE_DETECTORS | ||
| * @property {number} OTEL_METRIC_EXPORT_INTERVAL | ||
| * @property {number} OTEL_METRIC_EXPORT_TIMEOUT | ||
| * @property {boolean} ELASTIC_OTEL_METRICS_DISABLED | ||
| */ | ||
| /** | ||
| * @typedef {keyof EdotEnv} EdotEnvKey | ||
| */ | ||
| /** @type {EdotEnv} */ | ||
| const edotEnv = { | ||
| // Missing OTEL_ vars from global spec and nodejs specific spec | ||
| OTEL_NODE_RESOURCE_DETECTORS: parseStringList( | ||
| process.env.OTEL_NODE_RESOURCE_DETECTORS, | ||
| ['all'] | ||
| ), | ||
| // Note: Default values has been taken from the specs | ||
| // https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/#periodic-exporting-metricreader | ||
| OTEL_METRIC_EXPORT_INTERVAL: parseNumber( | ||
| process.env.OTEL_METRIC_EXPORT_INTERVAL, | ||
| 60000 | ||
| ), | ||
| OTEL_METRIC_EXPORT_TIMEOUT: parseNumber( | ||
| process.env.OTEL_METRIC_EXPORT_TIMEOUT, | ||
| 30000 | ||
| ), | ||
| // ELASTIC_OTEL_ vars | ||
| ELASTIC_OTEL_METRICS_DISABLED: parseBoolean( | ||
| process.env.ELASTIC_OTEL_METRICS_DISABLED, | ||
| false | ||
| ), | ||
| }; | ||
|
|
||
| /** | ||
| * @typedef {import('@opentelemetry/core').ENVIRONMENT} OtelEnv | ||
| */ | ||
| /** | ||
| * @typedef {keyof OtelEnv} OtelEnvKey | ||
| */ | ||
| const otelEnv = getEnv(); | ||
|
|
||
| /** | ||
| * @template T | ||
| * @typedef {T extends OtelEnvKey ? OtelEnv[T] : T extends EdotEnvKey ? EdotEnv[T] : never} EnvValue<T> | ||
| */ | ||
| /** | ||
| * @template {OtelEnvKey | EdotEnvKey} T | ||
| * Returns the value of the env var already parsed to the proper type. If | ||
| * the variable is not defined it will return the default value based on | ||
| * the environmment variables spec https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/ | ||
| * @param {T} name | ||
| * @returns {EnvValue<T>} | ||
| * @param {(name: string) => T} getterFn | ||
| * @returns {(name: string, defaultValue?: T) => T} | ||
| */ | ||
| function getEnvVar(name) { | ||
| if (name in otelEnv) { | ||
| // @ts-ignore -- T is {keyof OtelEnv} but not sure how to make TS infer that | ||
| return otelEnv[name]; | ||
| } | ||
| function makeEnvVarGetter(getterFn) { | ||
|
||
| return function (name, defaultValue = undefined) { | ||
| const isStashed = name in envToRestore; | ||
| let result; | ||
|
|
||
| // @ts-ignore -- T is {keyof EdotEnv} but not sure how to make TS infer that | ||
| return edotEnv[name]; | ||
| if (isStashed) { | ||
| process.env[name] = envToRestore[name]; | ||
| } | ||
| result = getterFn(name); | ||
| if (isStashed) { | ||
| delete process.env[name]; | ||
| } | ||
|
|
||
| return typeof result === 'undefined' ? defaultValue : result; | ||
| }; | ||
| } | ||
|
|
||
| const getEnvBoolean = makeEnvVarGetter(getBooleanFromEnv); | ||
| const getEnvNumber = makeEnvVarGetter(getNumberFromEnv); | ||
| const getEnvString = makeEnvVarGetter(getStringFromEnv); | ||
| const getEnvStringList = makeEnvVarGetter(getStringListFromEnv); | ||
|
|
||
| module.exports = { | ||
| setupEnvironment, | ||
| restoreEnvironment, | ||
| getEnvVar, | ||
| getEnvBoolean, | ||
| getEnvNumber, | ||
| getEnvString, | ||
| getEnvStringList, | ||
| }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that log warn is because this doesn't have a default fallback now.