UNPKG

@uyu423/pinpoint-node-agent

Version:

Pinpoint node agent provided by NAVER (Personalized version)

219 lines (186 loc) 6.17 kB
/** * Pinpoint Node.js Agent * Copyright 2020-present NAVER Corp. * Apache License v2.0 */ 'use strict' const path = require('path') const fs = require('fs') const defaultConfig = require('./pinpoint-config-default') const log = require('./utils/logger') const ROOT_PATH = path.dirname(require.main.filename || process.mainModule.filename) const valueOfString = (envName) => { return () => { if (process.env[envName] === undefined) { return undefined } return process.env[envName] } } const valueOfBoolean = (envName) => { return () => { if (process.env[envName] === undefined) { return undefined } return process.env[envName] === 'true' } } const valueOfNumber = (envName) => { return () => { if (process.env[envName] === undefined) { return undefined } return Number(process.env[envName]) } } const ENV_MAP = { agentId: valueOfString('PINPOINT_AGENT_ID'), applicationName: valueOfString('PINPOINT_APPLICATION_NAME'), serviceType: valueOfNumber('PINPOINT_SERVICE_TYPE'), collectorIp: valueOfString('PINPOINT_COLLECTOR_IP'), collectorTcpPort: valueOfNumber('PINPOINT_COLLECTOR_TCP_PORT'), collectorStatPort: valueOfNumber('PINPOINT_COLLECTOR_STAT_PORT'), collectorSpanPort: valueOfNumber('PINPOINT_COLLECTOR_SPAN_PORT'), sampling: valueOfBoolean('PINPOINT_SAMPLING'), sampleRate: valueOfNumber('PINPOINT_SAMPLING_RATE'), logLevel: valueOfString('PINPOINT_LOG_LEVEL'), enable: valueOfBoolean('PINPOINT_ENABLE'), container: valueOfBoolean('PINPOINT_CONTAINER'), traceExclusionUrlPatterns: valueOfString('PINPOINT_TRACE_EXCLUSION_URL_PATTERN'), traceExclusionUrlCacheSize: valueOfNumber('PINPOINT_TRACE_EXCLUSION_URL_CACHE_SIZE'), } const CONFIG_FILE_MAP = { agentId: 'agent-id', applicationName: 'application-name', serviceType: 'application-type', collectorIp: 'collector.ip', collectorTcpPort: 'collector.tcp-port', collectorStatPort: 'collector.stat-port', collectorSpanPort: 'collector.span-port', sampling: 'sampling.enable', sampleRate: 'sampling.rate', httpStatusCodeErrors: 'http-status-code-errors', logLevel: 'log-level', enabledDataSending: 'enabled-data-sending', enabledStatsMonitor: 'enabled-stats-monitor-sending', enabledActiveThreadCount: 'enabled-active-thread-count', express: 'express.enable', koa: 'koa.enable', mongo: 'mongo.enable', redis: 'redis.enable', enable: 'enable', container: 'container', traceExclusionUrlPatterns: 'trace-exclusion-url.pattern', traceExclusionUrlCacheSize: 'trace-exclusion-url.cache-size' } let agentConfig = null const REQUIRE_CONFIG = { agentId: 'an Agent ID', applicationName: 'an Application Name' } // ref: https://github.com/elastic/apm-agent-nodejs/blob/master/lib/config.js const ARRAY_CONFIG = [ 'traceExclusionUrlPatterns' ] const configurationValueValidations = { validateTraceExclusionUrlCacheSize: () => { if (typeof agentConfig.traceExclusionUrlCacheSize !== 'undefined' && typeof agentConfig.traceExclusionUrlPatterns === 'undefined') { delete agentConfig.traceExclusionUrlCacheSize log.warn(`You have to set the PINPOINT_TRACE_EXCLUSION_URL_PATTERN, PINPOINT_TRACE_EXCLUSION_URL_CACHE_SIZE or trace-exclusion-url{ pattern: 'pattern', 'cache-size': 100} for using excludsion url cache.`) } if (Array.isArray(agentConfig.traceExclusionUrlPatterns) && Number.isInteger(agentConfig.traceExclusionUrlCacheSize)) { if (agentConfig.traceExclusionUrlCacheSize < 100) { agentConfig.traceExclusionUrlCacheSize = 100 } } } } const init = (initOptions = {}) => { agentConfig = Object.assign({}, readConfigJson(defaultConfig), readConfigJson(readRootConfigFile()), readFromEnv(), initOptions) log.init(agentConfig.logLevel) Object.entries(REQUIRE_CONFIG).forEach(([propertyName, description]) => { if (agentConfig.enable && !agentConfig[propertyName]) { agentConfig.enable = false log.error(`You must set ${description}. The Pinpoint Node JS Agent has been shutdown.`) } }) if (!ENV_MAP.container() && isContainerEnvironment()) { agentConfig.container = true } for (const [key, validation] of Object.entries(configurationValueValidations)) { validation() } } const readFromEnv = () => { return Object.entries(ENV_MAP).reduce((acc, [key, valueOf]) => { const value = valueOf() if (typeof value === 'undefined') { return acc } acc[key] = ARRAY_CONFIG.includes(key) ? splitString(value) : value return acc }, {}) } const splitString = (value) => { if (typeof value !== 'string') { return value } return value.split(',').map(token => token.trim()).filter(token => token.length > 0) } const readConfigJson = (formattedConfig) => { return Object.entries(CONFIG_FILE_MAP).reduce((acc, [key, propName]) => { const value = getValue(propName, formattedConfig) if (value !== undefined) { acc[key] = value } return acc }, {}) } const readRootConfigFile = () => { const fileName = 'pinpoint-config' const fileFullPath = path.join(ROOT_PATH, '/', fileName) if (fs.existsSync(fileFullPath.concat('.json')) || fs.existsSync(fileFullPath.concat('.js'))) { return require(fileFullPath) } return {} } const getValue = (key, configFile) => { if (key) { return key.split('.').reduce((object, prop) => object && object[prop], configFile) } } const getConfig = (initOptions) => { if (!agentConfig) { init(initOptions) } return agentConfig } const clear = () => agentConfig && (agentConfig = null) //https://github.com/sindresorhus/is-docker const isContainerEnvironment = () => { return hasDockerEnv() || hasDockerCGroup() || (process.env['KUBERNETES_SERVICE_HOST'] && process.env['KUBERNETES_SERVICE_HOST'].length > 0) } function hasDockerEnv() { try { fs.statSync('/.dockerenv'); return true; } catch (_) { return false; } } function hasDockerCGroup() { try { return fs.readFileSync('/proc/self/cgroup', 'utf8').includes('docker'); } catch (_) { return false; } } module.exports = { getConfig, clear, readConfigJson }