UNPKG

@vtex/diagnostics-nodejs

Version:

Diagnostics library for Node.js applications

184 lines 6.71 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.configureDefaults = configureDefaults; const tslib_1 = require("tslib"); const resources_1 = require("@opentelemetry/resources"); const semantic_conventions_1 = require("@opentelemetry/semantic-conventions"); const diagnostics_semconv_1 = require("@vtex/diagnostics-semconv"); const os = tslib_1.__importStar(require("os")); const uuid_1 = require("uuid"); const fs = tslib_1.__importStar(require("fs/promises")); const resource_detector_aws_1 = require("@opentelemetry/resource-detector-aws"); const utils_1 = require("../utils"); const config_1 = require("../config"); const ENV_SERVICE_VERSION = 'SERVICE_VERSION'; const ENV_DEPLOYMENT_ENV = 'DEPLOYMENT_ENVIRONMENT'; const ENV_KUBERNETES_HOST = 'KUBERNETES_SERVICE_HOST'; const ENV_KUBERNETES_NAMESPACE = 'KUBERNETES_NAMESPACE'; const ENV_KUBERNETES_NODE_NAME = 'KUBERNETES_NODE_NAME'; const ENV_KUBERNETES_POD_NAME = 'KUBERNETES_POD_NAME'; let cachedHostname = null; const envVarsCache = {}; let isKubernetesEnv = null; function getHostname() { if (cachedHostname === null) { try { cachedHostname = os.hostname(); } catch { cachedHostname = 'unknown-host'; } } return cachedHostname; } function getEnvVarsWithPrefix(prefix) { if (!envVarsCache[prefix]) { const result = {}; for (const key in process.env) { if (key.startsWith(prefix)) { result[key] = process.env[key]; } } envVarsCache[prefix] = result; } return envVarsCache[prefix]; } async function configureDefaults(config) { const resourceAttrs = await discoverResourceAttributes(config); const instanceId = generateInstanceId(config.clientName); const baseAttrs = { [diagnostics_semconv_1.ATTR_VTEX_DIAGNOSTICS_VERSION]: (0, config_1.getLibraryVersion)(), [diagnostics_semconv_1.ATTR_VTEX_DIAGNOSTICS_NAME]: (0, config_1.getLibraryName)(), [semantic_conventions_1.ATTR_SERVICE_NAME]: config.serviceName, [semantic_conventions_1.SEMRESATTRS_SERVICE_INSTANCE_ID]: instanceId, [semantic_conventions_1.ATTR_SERVICE_VERSION]: process.env[ENV_SERVICE_VERSION] || 'unknown', [semantic_conventions_1.SEMRESATTRS_DEPLOYMENT_ENVIRONMENT]: process.env[ENV_DEPLOYMENT_ENV] || config.environment || 'unknown', 'application.id': config.applicationID, ...resourceAttrs }; let resource = (0, utils_1.createResource)(baseAttrs); if (!config.disableCloudDetect) { resource = await detectCloudResources(resource); } if (config.additionalAttrs) { resource = resource.merge((0, utils_1.createResource)(config.additionalAttrs)); } return resource; } async function discoverResourceAttributes(config) { const attrs = { [semantic_conventions_1.SEMRESATTRS_HOST_NAME]: getHostname() }; if (inKubernetes() && !config.disableK8sDetect) { Object.assign(attrs, getKubernetesAttributes()); } const envAttrs = await getEnvironmentAttributes(config); return { ...attrs, ...envAttrs }; } async function getEnvironmentAttributes(config) { const attrs = {}; if (config.envMappings?.length) { for (const mapping of config.envMappings) { const value = process.env[mapping.envVar] || mapping.defaultValue; if (value !== undefined) { attrs[mapping.attributeName] = value; } } } if (!config.disableEnvPrefixDetection) { const prefix = config.envPrefix || 'TELEMETRY_ATTR_'; const prefixedVars = getEnvVarsWithPrefix(prefix); for (const key in prefixedVars) { const attrKey = key.substring(prefix.length) .toLowerCase() .replace(/_/g, '.'); attrs[attrKey] = prefixedVars[key]; } } if (!config.disableEnvMappingsFromEnv) { const mappingsEnv = process.env.TELEMETRY_ATTR_MAPPINGS; if (mappingsEnv) { const mappings = mappingsEnv.split(','); for (const mapping of mappings) { const parts = mapping.trim().split(':'); if (parts.length === 2) { const [envVar, attrKey] = parts; if (process.env[envVar]) { attrs[attrKey] = process.env[envVar]; } } } } } if (config.customAttributesFile) { try { const customAttrs = await readCustomAttributesFile(config.customAttributesFile); if (customAttrs.environmentVariables) { for (const [envVar, attrKey] of Object.entries(customAttrs.environmentVariables)) { if (process.env[envVar]) { attrs[attrKey] = process.env[envVar]; } } } if (customAttrs.attributes) { Object.assign(attrs, customAttrs.attributes); } } catch { } } return attrs; } async function readCustomAttributesFile(filePath) { try { const fileContent = await fs.readFile(filePath, 'utf8'); return JSON.parse(fileContent); } catch { return {}; } } async function detectCloudResources(baseResource) { let detectedResources = await (0, resources_1.detectResources)({ detectors: [ new resource_detector_aws_1.AwsEcsDetectorSync(), ] }); return baseResource.merge(detectedResources); } function getKubernetesAttributes() { const attrs = {}; const k8sVars = { [ENV_KUBERNETES_NAMESPACE]: semantic_conventions_1.SemanticResourceAttributes.K8S_NAMESPACE_NAME, [ENV_KUBERNETES_NODE_NAME]: semantic_conventions_1.SemanticResourceAttributes.K8S_NODE_NAME, }; for (const [envVar, semAttr] of Object.entries(k8sVars)) { const value = process.env[envVar]; if (value) { attrs[semAttr] = value; } } return attrs; } function inKubernetes() { if (isKubernetesEnv === null) { isKubernetesEnv = Boolean(process.env[ENV_KUBERNETES_HOST]); } return isKubernetesEnv; } function generateInstanceId(clientName) { const parts = [clientName, getHostname()]; if (inKubernetes()) { const podName = process.env[ENV_KUBERNETES_POD_NAME]; if (podName) { parts.push(podName); } } if (parts.length < 2) { parts.push((0, uuid_1.v4)()); } return parts.join('-'); } exports.default = { configureDefaults }; //# sourceMappingURL=resource-discovery.js.map