UNPKG

log-vista

Version:

LogVista Agent - Lightweight system monitoring and log collection for any project/language

229 lines (189 loc) 6.34 kB
const cron = require('node-cron'); const logger = require('./logger'); class Scheduler { constructor(metricsCollector, logCollector, uploader, config) { this.metricsCollector = metricsCollector; this.logCollector = logCollector; this.uploader = uploader; this.config = config; this.tasks = new Map(); this.isRunning = false; } start() { if (this.isRunning) { logger.warn('Scheduler is already running'); return; } logger.info('Starting LogVista Agent Scheduler'); this.isRunning = true; // Schedule metrics collection const metricsInterval = this.config.agent.collection_interval || 30; const metricsSchedule = `*/${metricsInterval} * * * * *`; // Every N seconds const metricsTask = cron.schedule(metricsSchedule, async () => { await this.collectAndUploadMetrics(); }, { scheduled: false }); this.tasks.set('metrics', metricsTask); // Schedule log upload (every 10 seconds for more frequent log updates) const logTask = cron.schedule('*/10 * * * * *', async () => { await this.uploadLogs(); }, { scheduled: false }); this.tasks.set('logs', logTask); // Schedule offline data retry (every 5 minutes) const retryTask = cron.schedule('*/5 * * * *', async () => { await this.retryOfflineData(); }, { scheduled: false }); this.tasks.set('retry', retryTask); // Schedule server info update (every hour) const serverInfoTask = cron.schedule('0 * * * *', async () => { await this.updateServerInfo(); }, { scheduled: false }); this.tasks.set('serverInfo', serverInfoTask); // Start all tasks this.tasks.forEach((task, name) => { task.start(); logger.info(`Started ${name} task`); }); // Initial server info update setTimeout(() => this.updateServerInfo(), 5000); logger.info('All scheduled tasks started successfully'); } stop() { if (!this.isRunning) { logger.warn('Scheduler is not running'); return; } logger.info('Stopping LogVista Agent Scheduler'); this.tasks.forEach((task, name) => { task.stop(); logger.info(`Stopped ${name} task`); }); this.tasks.clear(); this.isRunning = false; logger.info('Scheduler stopped successfully'); } async collectAndUploadMetrics() { try { logger.debug('Collecting system metrics...'); const metrics = []; // Collect system-wide metrics if (this.config.system.collect_system_metrics) { const systemMetrics = await this.metricsCollector.collectSystemMetrics(); metrics.push({ type: 'system', ...systemMetrics }); } // Collect project-specific metrics for (const project of this.config.projects) { if (!project.enabled) continue; try { const projectMetrics = await this.metricsCollector.collectProjectMetrics(project); metrics.push({ type: 'project', ...projectMetrics }); } catch (projectError) { logger.warn(`Failed to collect metrics for project ${project.project_name}:`, projectError.message); } } if (metrics.length > 0) { await this.uploader.withRetry(() => this.uploader.uploadMetrics(metrics)); logger.debug(`Uploaded ${metrics.length} metric records`); } } catch (error) { logger.error('Error in metrics collection and upload:', error); } } async uploadLogs() { try { const bufferedLogs = this.logCollector.getBufferedLogs(); if (bufferedLogs.length > 0) { await this.uploader.withRetry(() => this.uploader.uploadLogs(bufferedLogs)); logger.debug(`Uploaded ${bufferedLogs.length} log records`); } } catch (error) { logger.error('Error in log upload:', error); } } async retryOfflineData() { try { logger.debug('Checking for offline data to retry...'); await this.uploader.retryOfflineData(); } catch (error) { logger.error('Error retrying offline data:', error); } } async updateServerInfo() { try { logger.debug('Updating server information...'); const si = require('systeminformation'); const os = require('os'); const [cpu, osInfo, system] = await Promise.all([ si.cpu(), si.osInfo(), si.system() ]); const serverInfo = { hostname: os.hostname(), platform: os.platform(), architecture: os.arch(), os: { platform: osInfo.platform, distro: osInfo.distro, release: osInfo.release, kernel: osInfo.kernel, arch: osInfo.arch }, cpu: { manufacturer: cpu.manufacturer, brand: cpu.brand, cores: cpu.cores, physicalCores: cpu.physicalCores, speed: cpu.speed }, system: { manufacturer: system.manufacturer, model: system.model, version: system.version, serial: system.serial }, memory: { total: os.totalmem(), free: os.freemem() }, uptime: os.uptime(), loadavg: os.loadavg(), agent: { version: require('../package.json').version, nodeVersion: process.version, pid: process.pid }, projects: this.config.projects.filter(p => p.enabled).map(p => ({ name: p.project_name, path: p.pwd_path, logPaths: p.custom_log_paths || [] })) }; await this.uploader.withRetry(() => this.uploader.uploadServerInfo(serverInfo)); logger.debug('Server information updated successfully'); } catch (error) { logger.error('Error updating server information:', error); } } getStatus() { return { isRunning: this.isRunning, activeTasks: Array.from(this.tasks.keys()), taskCount: this.tasks.size }; } } module.exports = Scheduler;