node-os-utils
Version:
Advanced cross-platform operating system monitoring utilities with TypeScript support
443 lines • 15.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MemoryMonitor = void 0;
const base_monitor_1 = require("../core/base-monitor");
const types_1 = require("../types");
/**
* 内存监控器
*
* 提供内存相关的监控功能,包括内存使用情况、交换空间、内存压力等
*/
class MemoryMonitor extends base_monitor_1.BaseMonitor {
constructor(adapter, config = {}, cache) {
super(adapter, config, cache);
this.memoryConfig = { ...this.getDefaultConfig(), ...config };
}
/**
* 获取内存基本信息
*/
async info() {
const cacheKey = 'memory-info';
return this.executeWithCache(cacheKey, async () => {
this.validatePlatformSupport('memory.info');
const rawData = await this.adapter.getMemoryInfo();
return this.transformMemoryInfo(rawData);
}, this.memoryConfig.cacheTTL || 2000 // 内存信息缓存 2 秒
);
}
/**
* 获取详细内存信息
*/
async detailed() {
const cacheKey = 'memory-detailed';
return this.executeWithCache(cacheKey, async () => {
this.validatePlatformSupport('memory.detailed');
const rawData = await this.adapter.getMemoryInfo();
const basicInfo = this.transformMemoryInfo(rawData);
const breakdown = this.extractDetailedBreakdown(rawData);
return {
...basicInfo,
breakdown
};
}, this.memoryConfig.cacheTTL || 2000);
}
/**
* 获取内存使用率百分比
*/
async usage() {
const cacheKey = 'memory-usage';
return this.executeWithCache(cacheKey, async () => {
const rawData = await this.adapter.getMemoryInfo();
const memInfo = this.transformMemoryInfo(rawData);
return memInfo.usagePercentage;
}, this.memoryConfig.cacheTTL || 1000);
}
/**
* 获取可用内存
*/
async available() {
const cacheKey = 'memory-available';
return this.executeWithCache(cacheKey, async () => {
const rawData = await this.adapter.getMemoryInfo();
const memInfo = this.transformMemoryInfo(rawData);
return memInfo.available;
}, this.memoryConfig.cacheTTL || 1000);
}
/**
* 获取已用内存(异步版本)
*/
async usedAsync() {
const cacheKey = 'memory-used';
return this.executeWithCache(cacheKey, async () => {
const rawData = await this.adapter.getMemoryInfo();
const memInfo = this.transformMemoryInfo(rawData);
return memInfo.used;
}, this.memoryConfig.cacheTTL || 1000);
}
/**
* 获取交换空间信息
*/
async swap() {
if (!this.memoryConfig.includeSwap) {
return this.createErrorResult(this.createUnsupportedError('memory.swap (disabled in config)'));
}
const cacheKey = 'memory-swap';
return this.executeWithCache(cacheKey, async () => {
this.validatePlatformSupport('memory.swap');
const rawData = await this.adapter.getMemoryInfo();
return this.transformSwapInfo(rawData);
}, this.memoryConfig.cacheTTL || 2000);
}
/**
* 获取内存压力信息
*/
async pressure() {
if (!this.memoryConfig.includePressure) {
return this.createErrorResult(this.createUnsupportedError('memory.pressure (disabled in config)'));
}
const cacheKey = 'memory-pressure';
return this.executeWithCache(cacheKey, async () => {
this.validatePlatformSupport('memory.pressure');
const rawData = await this.adapter.getMemoryInfo();
return this.calculateMemoryPressure(rawData);
}, this.memoryConfig.cacheTTL || 5000);
}
/**
* 获取缓存和缓冲区信息
*/
async buffers() {
if (!this.memoryConfig.includeBuffers) {
return this.createErrorResult(this.createUnsupportedError('memory.buffers (disabled in config)'));
}
const cacheKey = 'memory-buffers';
return this.executeWithCache(cacheKey, async () => {
const rawData = await this.adapter.getMemoryInfo();
return {
cached: new types_1.DataSize(this.safeParseNumber(rawData.cached)),
buffers: new types_1.DataSize(this.safeParseNumber(rawData.buffers))
};
}, this.memoryConfig.cacheTTL || 2000);
}
/**
* 获取总内存大小
*/
async total() {
const cacheKey = 'memory-total';
return this.executeWithCache(cacheKey, async () => {
const rawData = await this.adapter.getMemoryInfo();
return new types_1.DataSize(this.safeParseNumber(rawData.total));
}, this.memoryConfig.cacheTTL || 60000 // 总内存很少变化,缓存 1 分钟
);
}
/**
* 获取内存统计摘要
*/
async summary() {
const cacheKey = 'memory-summary';
return this.executeWithCache(cacheKey, async () => {
const rawData = await this.adapter.getMemoryInfo();
const memInfo = this.transformMemoryInfo(rawData);
const swapInfo = this.transformSwapInfo(rawData);
return {
total: memInfo.total.toString(this.memoryConfig.unit || 'auto'),
used: memInfo.used.toString(this.memoryConfig.unit || 'auto'),
available: memInfo.available.toString(this.memoryConfig.unit || 'auto'),
usagePercentage: Math.round(memInfo.usagePercentage * 100) / 100,
swap: {
total: swapInfo.total.toString(this.memoryConfig.unit || 'auto'),
used: swapInfo.used.toString(this.memoryConfig.unit || 'auto'),
usagePercentage: Math.round(swapInfo.usagePercentage * 100) / 100
}
};
}, this.memoryConfig.cacheTTL || 2000);
}
/**
* 配置是否包含交换空间信息
*/
withSwap(include) {
this.memoryConfig.includeSwap = include;
return this;
}
/**
* 配置是否包含缓存和缓冲区信息
*/
withBuffers(include) {
this.memoryConfig.includeBuffers = include;
return this;
}
/**
* 配置是否包含内存压力信息
*/
withPressure(include) {
this.memoryConfig.includePressure = include;
return this;
}
/**
* 配置内存单位
*/
withUnit(unit) {
this.memoryConfig.unit = unit;
return this;
}
/**
* 获取默认配置
*/
getDefaultConfig() {
return {
interval: 1000,
timeout: 5000,
cacheEnabled: true,
cacheTTL: 2000,
samples: 1,
includeDetails: true,
includeSwap: true,
includeBuffers: true,
includePressure: false, // 默认不包含压力信息,可能需要特殊权限
unit: 'auto'
};
}
// 私有转换方法
/**
* 转换内存基本信息
*/
transformMemoryInfo(rawData) {
const total = new types_1.DataSize(this.safeParseNumber(rawData.total));
const available = new types_1.DataSize(this.safeParseNumber(rawData.available || rawData.free));
const used = new types_1.DataSize(this.safeParseNumber(rawData.used || (rawData.total - rawData.available)));
const free = new types_1.DataSize(this.safeParseNumber(rawData.free));
const cached = new types_1.DataSize(this.safeParseNumber(rawData.cached));
const buffers = new types_1.DataSize(this.safeParseNumber(rawData.buffers));
const usagePercentage = total.toBytes() > 0
? (used.toBytes() / total.toBytes()) * 100
: 0;
const memInfo = {
total,
available,
used,
free,
cached,
buffers,
usagePercentage
};
// 添加内存压力信息(如果可用)
if (rawData.pressure) {
memInfo.pressure = this.transformMemoryPressure(rawData.pressure);
}
// 添加其他详细信息
if (rawData.shared !== undefined) {
memInfo.shared = new types_1.DataSize(this.safeParseNumber(rawData.shared));
}
if (rawData.reclaimable !== undefined) {
memInfo.reclaimable = new types_1.DataSize(this.safeParseNumber(rawData.reclaimable));
}
return memInfo;
}
/**
* 转换交换空间信息
*/
transformSwapInfo(rawData) {
const swapData = rawData.swap || {};
const total = new types_1.DataSize(this.safeParseNumber(swapData.total));
const used = new types_1.DataSize(this.safeParseNumber(swapData.used));
const free = new types_1.DataSize(this.safeParseNumber(swapData.free || (swapData.total - swapData.used)));
const usagePercentage = total.toBytes() > 0
? (used.toBytes() / total.toBytes()) * 100
: 0;
const swapInfo = {
total,
used,
free,
usagePercentage
};
// 添加交换活动信息(如果可用)
if (swapData.swapIn !== undefined) {
swapInfo.swapIn = this.safeParseNumber(swapData.swapIn);
}
if (swapData.swapOut !== undefined) {
swapInfo.swapOut = this.safeParseNumber(swapData.swapOut);
}
return swapInfo;
}
/**
* 转换内存压力信息
*/
transformMemoryPressure(pressureData) {
if (typeof pressureData === 'string') {
// 简单的字符串压力级别
return {
level: this.normalizePressureLevel(pressureData),
score: this.pressureLevelToScore(pressureData)
};
}
if (typeof pressureData === 'object') {
return {
level: this.normalizePressureLevel(pressureData.level),
score: this.safeParseNumber(pressureData.score || pressureData.percentage),
swapActivity: this.safeParseNumber(pressureData.swapActivity)
};
}
return {
level: 'low',
score: 0
};
}
/**
* 计算内存压力
*/
calculateMemoryPressure(rawData) {
// 如果已有压力信息,直接使用
if (rawData.pressure) {
return this.transformMemoryPressure(rawData.pressure);
}
// 否则基于使用率计算压力
const total = this.safeParseNumber(rawData.total);
const available = this.safeParseNumber(rawData.available || rawData.free);
if (total <= 0) {
return { level: 'low', score: 0 };
}
const usagePercentage = ((total - available) / total) * 100;
let level;
if (usagePercentage >= 95) {
level = 'critical';
}
else if (usagePercentage >= 85) {
level = 'high';
}
else if (usagePercentage >= 70) {
level = 'medium';
}
else {
level = 'low';
}
return {
level,
score: Math.min(100, Math.max(0, usagePercentage))
};
}
/**
* 提取详细内存分解信息
*/
extractDetailedBreakdown(rawData) {
const breakdown = {};
// Linux 特定字段
if (rawData.active !== undefined) {
breakdown.active = new types_1.DataSize(this.safeParseNumber(rawData.active));
}
if (rawData.inactive !== undefined) {
breakdown.inactive = new types_1.DataSize(this.safeParseNumber(rawData.inactive));
}
if (rawData.wired !== undefined) {
breakdown.wired = new types_1.DataSize(this.safeParseNumber(rawData.wired));
}
if (rawData.compressed !== undefined) {
breakdown.compressed = new types_1.DataSize(this.safeParseNumber(rawData.compressed));
}
// 内核内存
if (rawData.kernel !== undefined) {
breakdown.kernel = new types_1.DataSize(this.safeParseNumber(rawData.kernel));
}
// 设备驱动内存
if (rawData.drivers !== undefined) {
breakdown.drivers = new types_1.DataSize(this.safeParseNumber(rawData.drivers));
}
// 共享内存
if (rawData.shared !== undefined) {
breakdown.shared = new types_1.DataSize(this.safeParseNumber(rawData.shared));
}
return breakdown;
}
/**
* 规范化压力级别
*/
normalizePressureLevel(level) {
const normalizedLevel = level.toLowerCase();
if (normalizedLevel.includes('critical') || normalizedLevel.includes('severe')) {
return 'critical';
}
else if (normalizedLevel.includes('high') || normalizedLevel.includes('warn')) {
return 'high';
}
else if (normalizedLevel.includes('medium') || normalizedLevel.includes('moderate')) {
return 'medium';
}
else {
return 'low';
}
}
/**
* 压力级别转分数
*/
pressureLevelToScore(level) {
const scores = {
'low': 10,
'normal': 10,
'medium': 50,
'moderate': 50,
'high': 80,
'warn': 80,
'warning': 80,
'critical': 95,
'severe': 95
};
return scores[level.toLowerCase()] || 0;
}
/**
* 安全解析数字
*/
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;
}
// ==================== 向后兼容的同步方法 ====================
/**
* 获取总内存大小(同步版本,向后兼容)
* @returns 总内存大小(字节)或 'not supported'
*/
totalMem() {
try {
const os = require('os');
return os.totalmem();
}
catch (error) {
return 'not supported';
}
}
/**
* 获取空闲内存大小(同步版本,向后兼容)
* @returns 空闲内存大小(字节)或 'not supported'
*/
free() {
try {
const os = require('os');
return os.freemem();
}
catch (error) {
return 'not supported';
}
}
/**
* 获取已用内存大小(同步版本,向后兼容)
* @returns 已用内存大小(字节)或 'not supported'
*/
used() {
try {
const total = this.totalMem();
const free = this.free();
if (total === 'not supported' || free === 'not supported') {
return 'not supported';
}
return total - free;
}
catch (error) {
return 'not supported';
}
}
}
exports.MemoryMonitor = MemoryMonitor;
//# sourceMappingURL=memory-monitor.js.map