UNPKG

@vtex/diagnostics-nodejs

Version:

Diagnostics library for Node.js applications

141 lines 5.18 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FileProvider = exports.FileSource = void 0; exports.newFileSource = newFileSource; exports.newFileProvider = newFileProvider; const fs_1 = require("fs"); const fs_2 = require("fs"); const events_1 = require("events"); class FileSource extends events_1.EventEmitter { constructor(config) { super(); this.watcher = null; this.lastContent = ''; this.filePath = config.path; this.refreshIntervalMs = config.refreshIntervalMs || 60000; } async load() { try { const content = await fs_1.promises.readFile(this.filePath, 'utf8'); this.lastContent = content; let config; try { config = JSON.parse(content); } catch (parseError) { const errMsg = parseError instanceof Error ? parseError.message : String(parseError); throw new Error(`Invalid JSON in config file: ${errMsg}`); } for (const [accountId, rate] of Object.entries(config)) { if (typeof rate !== 'number' || rate < 0 || rate > 1) { throw new Error(`Invalid sampling rate for account ${accountId}: ${rate}. Must be between 0 and 1.`); } } return config; } catch (error) { if (error instanceof Error && 'code' in error && error.code === 'ENOENT') { console.warn(`Config file ${this.filePath} not found, using empty configuration`); return {}; } throw error; } } watch() { if (this.watcher) { return; } try { this.watcher = (0, fs_2.watch)(this.filePath, async (eventType) => { if (eventType === 'change') { try { await new Promise(resolve => setTimeout(resolve, 100)); // gambs const content = await fs_1.promises.readFile(this.filePath, 'utf8'); if (content !== this.lastContent) { this.lastContent = content; const config = JSON.parse(content); this.emit('update', config); } } catch (error) { const errMsg = error instanceof Error ? error.message : String(error); console.error(`Error watching config file: ${errMsg}`); } } }); const checkFileInterval = setInterval(async () => { try { const content = await fs_1.promises.readFile(this.filePath, 'utf8'); if (content !== this.lastContent) { this.lastContent = content; const config = JSON.parse(content); this.emit('update', config); } } catch (error) { const errMsg = error instanceof Error ? error.message : String(error); console.debug(`Error checking file: ${errMsg}`); } }, this.refreshIntervalMs); this.once('stopWatch', () => { clearInterval(checkFileInterval); }); } catch (error) { const errMsg = error instanceof Error ? error.message : String(error); console.error(`Error setting up file watcher: ${errMsg}`); } } stopWatch() { if (this.watcher) { this.watcher.close(); this.watcher = null; this.emit('stopWatch'); } } } exports.FileSource = FileSource; function newFileSource(config) { return new FileSource(config); } class FileProvider { constructor(sourceConfig, defaultRate = 0.1) { this.accounts = {}; this.defaultRate = defaultRate; this.source = newFileSource(sourceConfig); this.refresh().catch(err => { console.error('Failed to load initial configuration:', err); }); this.setupWatcher(); } setupWatcher() { this.source.on('update', (newConfig) => { this.accounts = newConfig; console.debug('Account sampling rates updated from file'); }); this.source.watch(); } async refresh() { try { this.accounts = await this.source.load(); } catch (error) { console.error('Failed to reload configuration:', error); } } getSamplingRate(accountId) { const rate = this.accounts[accountId]; return [rate !== undefined ? rate : this.defaultRate, rate !== undefined]; } getDefaultRate() { return this.defaultRate; } shutdown() { this.source.stopWatch(); } } exports.FileProvider = FileProvider; function newFileProvider(sourceConfig, defaultRate = 0.1) { return new FileProvider(sourceConfig, defaultRate); } //# sourceMappingURL=file-source.js.map