UNPKG

node-os-utils

Version:

Advanced cross-platform operating system monitoring utilities with TypeScript support

460 lines 15.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ProcessMonitor = void 0; const base_monitor_1 = require("../core/base-monitor"); const types_1 = require("../types"); /** * 进程监控器 * * 提供进程相关的监控功能,包括进程列表、进程信息、资源使用等 */ class ProcessMonitor extends base_monitor_1.BaseMonitor { constructor(adapter, config = {}, cache) { super(adapter, config, cache); this.processConfig = { ...this.getDefaultConfig(), ...config }; } /** * 获取进程信息(实现抽象方法) */ async info() { return this.list(); } /** * 获取所有进程列表 */ async list(options = {}) { const limitKey = options.skipLimit ? 'all' : (this.processConfig.maxResults || 'all'); const cacheKey = `process-list-${limitKey}`; return this.executeWithCache(cacheKey, async () => { this.validatePlatformSupport('process.list'); const rawData = await this.adapter.getProcessList(); const processes = this.transformProcessList(rawData); // 应用过滤和限制 const filteredProcesses = this.applyFilters(processes, options); return filteredProcesses; }, this.processConfig.cacheTTL || 5000); } /** * 根据 PID 获取进程信息 */ async byPid(pid) { const cacheKey = `process-${pid}`; return this.executeWithCache(cacheKey, async () => { this.validatePlatformSupport('process.info'); const rawData = await this.adapter.getProcessInfo(pid); if (!rawData) { return null; } return this.transformProcessInfo(rawData); }, this.processConfig.cacheTTL || 2000); } /** * 根据进程名称搜索进程 */ async byName(name) { const listResult = await this.list({ skipLimit: true }); if (!listResult.success || !listResult.data) { return listResult; } const matchingProcesses = listResult.data.filter(process => process.name.toLowerCase().includes(name.toLowerCase()) || process.command.toLowerCase().includes(name.toLowerCase())); return this.createSuccessResult(matchingProcesses); } /** * 获取当前进程信息 */ async current() { return this.byPid(process.pid); } /** * 获取子进程列表 */ async children(parentPid) { if (!this.processConfig.includeChildren) { return this.createErrorResult(this.createUnsupportedError('process.children (disabled in config)')); } const listResult = await this.list({ skipLimit: true }); if (!listResult.success || !listResult.data) { return listResult; } const childProcesses = listResult.data.filter(process => process.ppid === parentPid); return this.createSuccessResult(childProcesses); } /** * 获取进程树 */ async tree(rootPid) { const listResult = await this.list({ skipLimit: true }); if (!listResult.success || !listResult.data) { return listResult; } const processTree = this.buildProcessTree(listResult.data, rootPid); return this.createSuccessResult(processTree); } /** * 获取最占用 CPU 的进程 */ async topByCpu(limit = 10) { const listResult = await this.list({ skipLimit: true }); if (!listResult.success || !listResult.data) { return listResult; } const sortedProcesses = listResult.data .filter(process => process.cpuUsage > 0) .sort((a, b) => b.cpuUsage - a.cpuUsage) .slice(0, limit); return this.createSuccessResult(sortedProcesses); } /** * 获取最占用内存的进程 */ async topByMemory(limit = 10) { const listResult = await this.list({ skipLimit: true }); if (!listResult.success || !listResult.data) { return listResult; } const sortedProcesses = listResult.data .filter(process => process.memoryUsage.toBytes() > 0) .sort((a, b) => b.memoryUsage.toBytes() - a.memoryUsage.toBytes()) .slice(0, limit); return this.createSuccessResult(sortedProcesses); } /** * 获取进程统计信息 */ async stats() { const cacheKey = 'process-stats'; return this.executeWithCache(cacheKey, async () => { const listResult = await this.list({ skipLimit: true }); if (!listResult.success || !listResult.data) { throw new Error('Failed to get process list for statistics'); } const processes = listResult.data; const stats = { total: processes.length, running: 0, sleeping: 0, waiting: 0, zombie: 0, stopped: 0, unknown: 0, totalCpuUsage: 0, totalMemoryUsage: new types_1.DataSize(0) }; let totalMemoryBytes = 0; for (const process of processes) { // 按状态计数 switch (process.state) { case 'running': stats.running++; break; case 'sleeping': stats.sleeping++; break; case 'waiting': stats.waiting++; break; case 'zombie': stats.zombie++; break; case 'stopped': stats.stopped++; break; default: stats.unknown++; } // 累计资源使用 stats.totalCpuUsage += process.cpuUsage; totalMemoryBytes += process.memoryUsage.toBytes(); } stats.totalMemoryUsage = new types_1.DataSize(totalMemoryBytes); return stats; }, this.processConfig.cacheTTL || 5000); } /** * 检查进程是否存在 */ async exists(pid) { try { const processResult = await this.byPid(pid); return this.createSuccessResult(processResult.success && processResult.data !== null); } catch (error) { return this.createSuccessResult(false); } } /** * 杀死进程 */ async kill(pid, signal = 'SIGTERM') { try { this.validatePlatformSupport('process.kill'); const result = await this.adapter.killProcess(pid, signal); return this.createSuccessResult(result); } catch (error) { return this.handleError(error); } } /** * 获取进程的打开文件 */ async openFiles(pid) { if (!this.processConfig.includeOpenFiles) { return this.createErrorResult(this.createUnsupportedError('process.openFiles (disabled in config)')); } const cacheKey = `process-openfiles-${pid}`; return this.executeWithCache(cacheKey, async () => { this.validatePlatformSupport('process.openFiles'); const rawData = await this.adapter.getProcessOpenFiles(pid); return rawData || []; }, this.processConfig.cacheTTL || 10000); } /** * 获取进程的环境变量 */ async environment(pid) { if (!this.processConfig.includeEnvironment) { return this.createErrorResult(this.createUnsupportedError('process.environment (disabled in config)')); } const cacheKey = `process-env-${pid}`; return this.executeWithCache(cacheKey, async () => { this.validatePlatformSupport('process.environment'); const rawData = await this.adapter.getProcessEnvironment(pid); return rawData || {}; }, this.processConfig.cacheTTL || 30000); } /** * 配置是否包含子进程 */ withChildren(include) { this.processConfig.includeChildren = include; return this; } /** * 配置是否包含线程信息 */ withThreads(include) { this.processConfig.includeThreads = include; return this; } /** * 配置是否包含环境变量 */ withEnvironment(include) { this.processConfig.includeEnvironment = include; return this; } /** * 配置是否包含打开文件 */ withOpenFiles(include) { this.processConfig.includeOpenFiles = include; return this; } /** * 配置进程名称过滤 */ withNameFilter(filter) { this.processConfig.nameFilter = filter; return this; } /** * 配置最大返回结果数 */ withMaxResults(max) { this.processConfig.maxResults = max; return this; } /** * 配置目标进程 ID 列表 */ withPids(pids) { this.processConfig.pids = pids; return this; } /** * 获取默认配置 */ getDefaultConfig() { return { interval: 5000, timeout: 15000, cacheEnabled: true, cacheTTL: 3000, samples: 1, includeDetails: true, includeChildren: false, includeThreads: false, includeEnvironment: false, includeOpenFiles: false, maxResults: 100 // 默认限制返回进程数以提高性能 }; } // 私有转换方法 /** * 转换进程列表 */ transformProcessList(rawData) { if (!Array.isArray(rawData)) { return []; } return rawData.map(process => this.transformProcessInfo(process)); } /** * 转换进程信息 */ transformProcessInfo(rawProcess) { const startTime = this.parseStartTime(rawProcess.startTime || rawProcess.start_time); const currentTime = Date.now(); const runtime = currentTime - startTime; return { pid: this.safeParseNumber(rawProcess.pid), ppid: this.safeParseNumber(rawProcess.ppid), name: rawProcess.name || rawProcess.comm || 'unknown', command: rawProcess.command || rawProcess.cmd || rawProcess.args || '', state: this.normalizeProcessState(rawProcess.state || rawProcess.status), cpuUsage: this.safeParseNumber(rawProcess.cpuUsage || rawProcess.cpu), memoryUsage: new types_1.DataSize(this.safeParseNumber(rawProcess.memoryUsage || rawProcess.memory || rawProcess.rss)), memoryPercentage: this.safeParseNumber(rawProcess.memoryPercentage || rawProcess.mem), startTime, runtime, priority: rawProcess.priority || rawProcess.pri, nice: rawProcess.nice, threads: rawProcess.threads || rawProcess.nlwp, uid: rawProcess.uid, gid: rawProcess.gid, username: rawProcess.username || rawProcess.user }; } /** * 应用过滤器 */ applyFilters(processes, options = {}) { let filtered = [...processes]; // PID 过滤 if (this.processConfig.pids && this.processConfig.pids.length > 0) { filtered = filtered.filter(process => this.processConfig.pids.includes(process.pid)); } // 名称过滤 if (this.processConfig.nameFilter) { const filter = this.processConfig.nameFilter.toLowerCase(); filtered = filtered.filter(process => process.name.toLowerCase().includes(filter) || process.command.toLowerCase().includes(filter)); } // 限制结果数量 if (!options.skipLimit && this.processConfig.maxResults && this.processConfig.maxResults > 0) { filtered = filtered.slice(0, this.processConfig.maxResults); } return filtered; } /** * 构建进程树 */ buildProcessTree(processes, rootPid) { const processMap = new Map(); const childrenMap = new Map(); // 建立进程映射 for (const process of processes) { processMap.set(process.pid, process); if (!childrenMap.has(process.ppid)) { childrenMap.set(process.ppid, []); } childrenMap.get(process.ppid).push(process); } // 递归构建树 const buildNode = (pid) => { const process = processMap.get(pid); if (!process) return null; const children = childrenMap.get(pid) || []; return { ...process, children: children.map(child => buildNode(child.pid)).filter(child => child !== null) }; }; if (rootPid !== undefined) { return buildNode(rootPid); } // 返回所有根进程(ppid 不在进程列表中的进程) const rootProcesses = []; for (const process of processes) { if (!processMap.has(process.ppid)) { rootProcesses.push(buildNode(process.pid)); } } return rootProcesses; } /** * 规范化进程状态 */ normalizeProcessState(state) { if (!state || typeof state !== 'string') { return 'unknown'; } const normalizedState = state.toLowerCase().trim(); // Linux 状态码 if (normalizedState === 'r' || normalizedState.includes('running')) { return 'running'; } if (normalizedState === 's' || normalizedState.includes('sleeping') || normalizedState.includes('sleep')) { return 'sleeping'; } if (normalizedState === 'd' || normalizedState.includes('waiting') || normalizedState.includes('wait')) { return 'waiting'; } if (normalizedState === 'z' || normalizedState.includes('zombie')) { return 'zombie'; } if (normalizedState === 't' || normalizedState.includes('stopped') || normalizedState.includes('stop')) { return 'stopped'; } // macOS/Windows 状态 if (normalizedState.includes('active') || normalizedState.includes('normal')) { return 'running'; } if (normalizedState.includes('idle')) { return 'sleeping'; } return 'unknown'; } /** * 解析启动时间 */ parseStartTime(startTime) { if (typeof startTime === 'number') { // 如果是时间戳 if (startTime > 1000000000000) { // 毫秒时间戳 return startTime; } else { // 秒时间戳 return startTime * 1000; } } if (typeof startTime === 'string') { const parsed = Date.parse(startTime); if (!isNaN(parsed)) { return parsed; } } // 默认返回当前时间 return Date.now(); } /** * 安全解析数字 */ safeParseNumber(value) { if (typeof value === 'number') { return isNaN(value) ? 0 : value; } if (typeof value === 'string') { const parsed = parseFloat(value); return isNaN(parsed) ? 0 : parsed; } return 0; } } exports.ProcessMonitor = ProcessMonitor; //# sourceMappingURL=process-monitor.js.map