Skip to main content
Glama

NetBrain MCP

by NorthLaneMS
data_storage.md32.3 kB
# NetBrain MCP 数据存储设计 本文档详细描述NetBrain MCP系统的数据存储设计,包括实际的数据存储方案、数据模型、缓存策略和数据操作方法。 ## 1. 数据存储架构概述 ### 1.1 存储方案选择 NetBrain MCP系统采用**JSON文件存储**作为主要数据持久化方案,具有以下特点: - **轻量级部署**:无需额外的数据库服务器 - **简单维护**:人类可读的JSON格式,便于调试和维护 - **快速启动**:无需数据库初始化和配置 - **跨平台兼容**:完全兼容Windows、Linux、macOS - **备份简单**:数据文件可直接复制备份 ### 1.2 数据存储结构 ``` NetBrainMCP/ ├── data/ # 主数据存储目录 │ ├── devices.json # 设备信息存储 │ └── credentials.json # 凭据信息存储(敏感数据) ├── resource_cache/ # 资源缓存目录 │ ├── device_*.json # 设备资源缓存 │ ├── topology_*.json # 拓扑资源缓存 │ └── scan_*.json # 扫描结果缓存 ├── templates/ # 模板缓存目录 │ └── *.json # 模板元数据缓存 └── logs/ # 日志文件目录 ├── netbrain_mcp.log # 应用主日志 ├── device_connector.log # 设备连接日志 └── audit.log # 审计日志(安全增强) ``` ## 2. 核心数据模型 ### 2.1 网络设备模型 #### 2.1.1 NetworkDevice数据类 基于实际代码实现(`network_devices.py`第125-155行): ```python @dataclass class NetworkDevice: """网络设备模型""" id: str = field(default_factory=lambda: str(uuid.uuid4())) name: str = "" ip_address: str = "" device_type: DeviceType = DeviceType.OTHER vendor: DeviceVendor = DeviceVendor.OTHER platform: str = "" # Scrapli平台类型(重要字段) model: str = "" os_version: str = "" status: DeviceStatus = DeviceStatus.UNKNOWN location: str = "" credential_id: Optional[str] = None description: str = "" tags: List[str] = field(default_factory=list) last_seen: Optional[datetime] = None created_at: datetime = field(default_factory=datetime.now) updated_at: datetime = field(default_factory=datetime.now) custom_attributes: Dict[str, Any] = field(default_factory=dict) ``` #### 2.1.2 设备相关枚举 ```python class DeviceType(Enum): """网络设备类型枚举""" ROUTER = "router" SWITCH = "switch" FIREWALL = "firewall" LOAD_BALANCER = "load_balancer" WIRELESS_CONTROLLER = "wireless_controller" ACCESS_POINT = "access_point" OTHER = "other" class DeviceVendor(Enum): """网络设备厂商枚举""" CISCO = "cisco" HUAWEI = "huawei" H3C = "h3c" JUNIPER = "juniper" ARISTA = "arista" FORTINET = "fortinet" CHECKPOINT = "checkpoint" OTHER = "other" class DeviceStatus(Enum): """设备状态枚举""" ONLINE = "online" OFFLINE = "offline" UNREACHABLE = "unreachable" MAINTENANCE = "maintenance" UNKNOWN = "unknown" ``` #### 2.1.3 设备数据JSON示例 ```json { "device-uuid-123": { "id": "device-uuid-123", "name": "Router-01", "ip_address": "192.168.1.1", "device_type": "router", "vendor": "cisco", "platform": "cisco_iosxe", "model": "ISR4321", "os_version": "16.09.04", "status": "online", "location": "数据中心机房A", "credential_id": "cred-uuid-456", "description": "核心路由器", "tags": ["core", "production", "datacenter"], "last_seen": "2024-01-15T10:30:45.123456", "created_at": "2024-01-10T09:00:00.000000", "updated_at": "2024-01-15T10:30:45.123456", "custom_attributes": { "management_vlan": "100", "backup_schedule": "daily" } } } ``` ### 2.2 设备凭据模型 #### 2.2.1 DeviceCredential类 基于实际代码实现(`network_devices.py`第64-123行): ```python class DeviceCredential: """设备凭据类""" def __init__(self, id: str = None, name: str = "", username: str = "", password: str = "", protocol: ConnectionProtocol = ConnectionProtocol.SSH, port: int = None, enable_password: str = None, ssh_key_file: str = None): self.id = id or str(uuid.uuid4()) self.name = name self.username = username self.password = password self.protocol = protocol self.port = port or (22 if protocol == ConnectionProtocol.SSH else 23) self.enable_password = enable_password self.ssh_key_file = ssh_key_file ``` #### 2.2.2 连接协议枚举 ```python class ConnectionProtocol(Enum): """连接协议枚举""" SSH = "ssh" TELNET = "telnet" SNMP = "snmp" HTTP = "http" HTTPS = "https" NETCONF = "netconf" ``` #### 2.2.3 凭据数据JSON示例 ```json { "cred-uuid-456": { "id": "cred-uuid-456", "name": "思科设备SSH凭据", "username": "admin", "password": "cisco123", "protocol": "ssh", "port": 22, "enable_password": "enable123", "ssh_key_file": null } } ``` **⚠️ 安全注意**: 当前凭据以明文形式存储,生产环境中应实施加密存储。 ## 3. 数据管理器实现 ### 3.1 DeviceManager类 基于实际代码实现(`network_devices.py`第161-462行): #### 3.1.1 初始化和配置 ```python class DeviceManager: """设备管理器,负责设备的创建、查询和管理""" def __init__(self): self.devices: Dict[str, NetworkDevice] = {} self.credentials: Dict[str, DeviceCredential] = {} self.data_dir = "data" self.devices_file = os.path.join(self.data_dir, "devices.json") self.credentials_file = os.path.join(self.data_dir, "credentials.json") # 创建数据目录(如不存在) os.makedirs(self.data_dir, exist_ok=True) # 加载持久化数据 self.load_data() logger.info("设备管理器初始化完成") ``` #### 3.1.2 数据持久化方法 **保存数据**: ```python def save_data(self): """将设备和凭据数据保存到文件""" # 保存设备数据 devices_data = {} for device_id, device in self.devices.items(): devices_data[device_id] = device.to_dict() with open(self.devices_file, 'w', encoding='utf-8') as f: json.dump(devices_data, f, ensure_ascii=False, indent=2) # 保存凭据数据 credentials_data = {} for cred_id, credential in self.credentials.items(): cred_dict = { "id": credential.id, "name": credential.name, "username": credential.username, "password": credential.password, # 明文存储(待加密) "protocol": credential.protocol.value, "port": credential.port, "enable_password": credential.enable_password, "ssh_key_file": credential.ssh_key_file } credentials_data[cred_id] = cred_dict with open(self.credentials_file, 'w', encoding='utf-8') as f: json.dump(credentials_data, f, ensure_ascii=False, indent=2) logger.info(f"数据已保存到: {self.data_dir}") ``` **加载数据**: ```python def load_data(self): """从文件加载设备和凭据数据""" # 加载设备数据 if os.path.exists(self.devices_file): try: with open(self.devices_file, 'r', encoding='utf-8') as f: devices_data = json.load(f) for device_id, device_dict in devices_data.items(): # 转换枚举类型 device_type = DeviceType(device_dict.get("device_type", "other")) vendor = DeviceVendor(device_dict.get("vendor", "other")) status = DeviceStatus(device_dict.get("status", "unknown")) # 转换日期时间 created_at = datetime.fromisoformat(device_dict.get("created_at", datetime.now().isoformat())) updated_at = datetime.fromisoformat(device_dict.get("updated_at", datetime.now().isoformat())) last_seen = None if device_dict.get("last_seen"): last_seen = datetime.fromisoformat(device_dict.get("last_seen")) # 创建设备对象 device = NetworkDevice( id=device_id, name=device_dict.get("name", ""), ip_address=device_dict.get("ip_address", ""), device_type=device_type, vendor=vendor, platform=device_dict.get("platform", ""), model=device_dict.get("model", ""), os_version=device_dict.get("os_version", ""), status=status, location=device_dict.get("location", ""), credential_id=device_dict.get("credential_id"), description=device_dict.get("description", ""), tags=device_dict.get("tags", []), last_seen=last_seen, created_at=created_at, updated_at=updated_at, custom_attributes=device_dict.get("custom_attributes", {}) ) self.devices[device_id] = device logger.info(f"从 {self.devices_file} 加载了 {len(self.devices)} 个设备") except Exception as e: logger.error(f"加载设备数据失败: {e}") ``` #### 3.1.3 CRUD操作 **添加设备**: ```python def add_device(self, device: NetworkDevice) -> str: """添加设备""" self.devices[device.id] = device logger.info(f"设备添加成功: {device.name} ({device.ip_address})") self.save_data() # 立即保存到文件 return device.id ``` **查询设备**: ```python def get_device(self, device_id: str) -> Optional[NetworkDevice]: """获取设备""" return self.devices.get(device_id) def list_devices(self, vendor: Optional[DeviceVendor] = None, device_type: Optional[DeviceType] = None, status: Optional[DeviceStatus] = None, tag: Optional[str] = None) -> List[NetworkDevice]: """列出设备,支持过滤条件""" devices = list(self.devices.values()) if vendor: devices = [d for d in devices if d.vendor == vendor] if device_type: devices = [d for d in devices if d.device_type == device_type] if status: devices = [d for d in devices if d.status == status] if tag: devices = [d for d in devices if tag in d.tags] return devices ``` **更新设备**: ```python def update_device(self, device_id: str, **kwargs) -> Optional[NetworkDevice]: """更新设备信息""" device = self.get_device(device_id) if not device: logger.warning(f"设备不存在: {device_id}") return None for key, value in kwargs.items(): if hasattr(device, key): setattr(device, key, value) device.updated_at = datetime.now() logger.info(f"设备更新成功: {device.name} ({device.ip_address})") self.save_data() # 保存更改 return device ``` **删除设备**: ```python def delete_device(self, device_id: str) -> bool: """删除设备""" if device_id in self.devices: device = self.devices[device_id] del self.devices[device_id] logger.info(f"设备删除成功: {device.name} ({device.ip_address})") self.save_data() # 保存更改 return True return False ``` ## 4. 缓存系统设计 ### 4.1 资源缓存机制 基于实际代码实现(`mcp_resources.py`第56-180行): #### 4.1.1 ResourceManager缓存实现 ```python class ResourceManager: """MCP资源管理器,负责资源注册和提供""" def __init__(self): self.resources = {} self.resource_patterns = {} self.resource_cache = {} # 内存缓存 self.cache_expiration = {} # 缓存过期时间 self.default_cache_ttl = 300 # 默认缓存5分钟 # 缓存目录 self.cache_dir = os.path.join(os.getcwd(), "resource_cache") if not os.path.exists(self.cache_dir): try: os.makedirs(self.cache_dir) logger.info(f"已创建资源缓存目录: {self.cache_dir}") except Exception as e: logger.warning(f"无法创建资源缓存目录: {str(e)}") ``` #### 4.1.2 双层缓存策略 **内存缓存**: ```python async def get_resource(self, uri: str, use_cache: bool = True, cache_ttl: Optional[int] = None) -> Dict[str, Any]: """获取资源""" # 检查内存缓存 if use_cache and uri in self.resource_cache: # 检查缓存是否过期 if uri in self.cache_expiration and self.cache_expiration[uri] > datetime.datetime.now(): logger.info(f"从内存缓存获取资源: {uri}") return self.resource_cache[uri] else: # 缓存过期,从缓存中删除 logger.info(f"资源缓存已过期: {uri}") if uri in self.resource_cache: del self.resource_cache[uri] if uri in self.cache_expiration: del self.cache_expiration[uri] ``` **文件缓存**: ```python # 从文件缓存加载 if use_cache: cache_file = self._get_cache_filename(uri) if os.path.exists(cache_file): try: with open(cache_file, 'r', encoding='utf-8') as f: cache_data = json.load(f) # 检查缓存是否过期 if "expiration" in cache_data: expiration = datetime.datetime.fromisoformat(cache_data["expiration"]) if expiration > datetime.datetime.now(): logger.info(f"从文件缓存加载资源: {uri}") self.resource_cache[uri] = cache_data["data"] self.cache_expiration[uri] = expiration return cache_data["data"] except Exception as e: logger.warning(f"加载资源缓存文件失败: {str(e)}") ``` **缓存写入**: ```python # 缓存结果 if use_cache: self.resource_cache[uri] = result ttl = cache_ttl or self.default_cache_ttl expiration = datetime.datetime.now() + datetime.timedelta(seconds=ttl) self.cache_expiration[uri] = expiration # 保存到文件缓存 try: cache_file = self._get_cache_filename(uri) with open(cache_file, 'w', encoding='utf-8') as f: json.dump({ "data": result, "expiration": expiration.isoformat() }, f, ensure_ascii=False, indent=2) except Exception as e: logger.warning(f"保存资源缓存文件失败: {str(e)}") ``` #### 4.1.3 缓存文件命名 ```python def _get_cache_filename(self, uri: str) -> str: """获取缓存文件名""" # 将URI转换为文件名安全的字符串 safe_uri = uri.replace(':', '_').replace('/', '_').replace('.', '_').replace('\\', '_') return os.path.join(self.cache_dir, f"{safe_uri}.json") ``` #### 4.1.4 缓存清理机制 ```python def clear_cache(self, uri: Optional[str] = None) -> bool: """清除资源缓存""" try: if uri: if uri in self.resource_cache: del self.resource_cache[uri] if uri in self.cache_expiration: del self.cache_expiration[uri] # 删除文件缓存 cache_file = self._get_cache_filename(uri) if os.path.exists(cache_file): os.remove(cache_file) logger.info(f"已清除资源缓存: {uri}") else: self.resource_cache.clear() self.cache_expiration.clear() # 删除所有缓存文件 if os.path.exists(self.cache_dir): for filename in os.listdir(self.cache_dir): if filename.endswith('.json'): os.remove(os.path.join(self.cache_dir, filename)) logger.info("已清除所有资源缓存") return True except Exception as e: logger.error(f"清除缓存失败: {str(e)}") return False ``` ### 4.2 缓存配置策略 #### 4.2.1 默认缓存时间(TTL) ```python # 资源类型对应的缓存时间 CACHE_TTL_CONFIG = { "device": 300, # 设备信息:5分钟 "config": 600, # 设备配置:10分钟 "topology": 900, # 拓扑信息:15分钟 "scan": 1800, # 扫描结果:30分钟 "system": 60, # 系统状态:1分钟 "credential": 3600 # 凭据信息:1小时 } ``` #### 4.2.2 缓存策略 - **即时缓存**:数据获取后立即缓存 - **延迟过期**:使用TTL控制缓存生命周期 - **主动清理**:提供手动清理接口 - **容量控制**:内存缓存大小限制(待实现) ## 5. 连接数据管理 ### 5.1 连接状态存储 基于实际代码实现(`device_connector.py`第659-865行): #### 5.1.1 ConnectionManager实现 ```python class ConnectionManager: """连接管理器""" def __init__(self): self.active_connections: Dict[str, DeviceConnector] = {} # 连接键格式:"{device_id}:{credential_id}" def _get_connection_key(self, device_id: str, credential_id: str) -> str: """生成连接键""" return f"{device_id}:{credential_id}" ``` #### 5.1.2 连接状态数据结构 ```python # 活动连接信息示例 { "device-123:cred-456": { "device_connector": ScrapliConnector实例, "device_info": { "id": "device-123", "name": "Router-01", "ip_address": "192.168.1.1" }, "credential_info": { "id": "cred-456", "username": "admin", "protocol": "ssh" }, "connection_status": { "connected": True, "last_activity": "2024-01-15T10:30:45", "connection_time": "2024-01-15T10:25:30" } } } ``` #### 5.1.3 连接查询接口 ```python def get_active_connections(self) -> List[Dict[str, Any]]: """获取活动连接列表""" connections = [] for connection_key, connector in self.active_connections.items(): device_id, credential_id = connection_key.split(':', 1) connection_info = { "device_id": device_id, "credential_id": credential_id, "device_name": connector.device.name, "device_ip": connector.device.ip_address, "connected": connector.connected, "last_activity": connector.last_activity.isoformat() if connector.last_activity else None, "connection_key": connection_key } connections.append(connection_info) return connections ``` ## 6. 日志数据管理 ### 6.1 日志存储结构 #### 6.1.1 日志文件分类 **应用主日志**(`logs/netbrain_mcp.log`): ``` 2024-01-15 10:30:45,123 - netbrain_mcp - INFO - MCP服务器已启动 2024-01-15 10:31:02,456 - network_devices - INFO - 设备添加成功: Router-01 (192.168.1.1) 2024-01-15 10:31:15,789 - mcp_resources - INFO - 从缓存获取资源: device/device-123 ``` **设备连接日志**(`logs/device_connector.log`): ``` 2024-01-15 10:32:00,123 - device_connector - INFO - 正在通过Scrapli连接到设备: Router-01 (192.168.1.1) 2024-01-15 10:32:03,456 - device_connector - INFO - 已成功连接到设备: Router-01 (192.168.1.1) 2024-01-15 10:32:10,789 - device_connector - INFO - 命令 'show version' 在设备 Router-01 上执行成功 ``` **审计日志**(`logs/audit.log`,安全增强功能): ```json {"timestamp": "2024-01-15T10:30:45.123Z", "event_type": "device.added", "user_id": "admin", "resource": "device:123", "action": "add", "result": "success"} {"timestamp": "2024-01-15T10:32:10.789Z", "event_type": "command.executed", "user_id": "admin", "resource": "device:123", "details": {"command": "show version"}} ``` #### 6.1.2 日志格式化 基于实际代码实现(所有模块的JsonFormatter): ```python class JsonFormatter(logging.Formatter): def __init__(self, fmt=None, datefmt=None, style='%'): super().__init__(fmt, datefmt, style) def format(self, record): log_record = super().format(record) return log_record.encode('utf-8', errors='replace').decode('utf-8') # 配置日志格式 logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[ logging.StreamHandler(stream=sys.stdout) ] ) # 设置所有处理器使用UTF-8编码格式化 for handler in logging.root.handlers: if isinstance(handler, logging.StreamHandler): handler.setFormatter(JsonFormatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')) ``` ## 7. 数据备份和恢复 ### 7.1 数据备份策略 #### 7.1.1 手动备份 ```bash # 备份核心数据文件 cp -r data/ backup/data_$(date +%Y%m%d_%H%M%S)/ # 备份缓存数据(可选) cp -r resource_cache/ backup/cache_$(date +%Y%m%d_%H%M%S)/ # 备份日志文件 cp -r logs/ backup/logs_$(date +%Y%m%d_%H%M%S)/ ``` #### 7.1.2 自动备份脚本 ```python # backup.py - 数据备份脚本 import os import shutil import datetime from pathlib import Path def backup_data(): """执行数据备份""" timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") backup_dir = Path(f"backup/backup_{timestamp}") backup_dir.mkdir(parents=True, exist_ok=True) # 备份数据文件 if Path("data").exists(): shutil.copytree("data", backup_dir / "data") print(f"数据文件已备份到: {backup_dir / 'data'}") # 备份重要日志 if Path("logs").exists(): shutil.copytree("logs", backup_dir / "logs") print(f"日志文件已备份到: {backup_dir / 'logs'}") return backup_dir if __name__ == "__main__": backup_path = backup_data() print(f"备份完成: {backup_path}") ``` ### 7.2 数据恢复 #### 7.2.1 数据恢复流程 ```python def restore_data(backup_path: str): """从备份恢复数据""" backup_dir = Path(backup_path) if not backup_dir.exists(): raise ValueError(f"备份目录不存在: {backup_path}") # 备份当前数据(安全措施) current_backup = backup_data() print(f"当前数据已备份到: {current_backup}") try: # 恢复数据文件 if (backup_dir / "data").exists(): if Path("data").exists(): shutil.rmtree("data") shutil.copytree(backup_dir / "data", "data") print("数据文件恢复完成") # 重新加载数据到内存 device_manager.load_data() print("数据已重新加载到内存") except Exception as e: print(f"恢复失败: {str(e)}") raise ``` ## 8. 性能优化 ### 8.1 数据访问优化 #### 8.1.1 内存索引 ```python class OptimizedDeviceManager(DeviceManager): """优化的设备管理器""" def __init__(self): super().__init__() self._ip_index = {} # IP地址索引 self._name_index = {} # 设备名称索引 self._vendor_index = {} # 厂商索引 self._build_indexes() def _build_indexes(self): """构建索引""" for device_id, device in self.devices.items(): # IP地址索引 self._ip_index[device.ip_address] = device_id # 名称索引 self._name_index[device.name.lower()] = device_id # 厂商索引 vendor = device.vendor.value if vendor not in self._vendor_index: self._vendor_index[vendor] = [] self._vendor_index[vendor].append(device_id) def get_device_by_ip(self, ip_address: str) -> Optional[NetworkDevice]: """通过IP地址快速查找设备""" device_id = self._ip_index.get(ip_address) return self.devices.get(device_id) if device_id else None ``` #### 8.1.2 批量操作优化 ```python def bulk_add_devices(self, devices: List[NetworkDevice]) -> List[str]: """批量添加设备(减少I/O操作)""" device_ids = [] for device in devices: self.devices[device.id] = device device_ids.append(device.id) logger.info(f"设备添加到内存: {device.name}") # 一次性保存所有更改 self.save_data() logger.info(f"批量添加 {len(devices)} 个设备完成") return device_ids ``` ### 8.2 缓存优化 #### 8.2.1 预加载策略 ```python async def preload_common_resources(self): """预加载常用资源""" common_resources = [ "system/status", "credentials", "topology/statistics" ] for uri in common_resources: try: await self.get_resource(uri, use_cache=True) logger.info(f"预加载资源: {uri}") except Exception as e: logger.warning(f"预加载资源失败: {uri}, {str(e)}") ``` #### 8.2.2 智能缓存清理 ```python def cleanup_expired_cache(self): """清理过期缓存""" now = datetime.datetime.now() expired_uris = [] for uri, expiration in self.cache_expiration.items(): if expiration <= now: expired_uris.append(uri) for uri in expired_uris: self.clear_cache(uri) logger.info(f"清理了 {len(expired_uris)} 个过期缓存项") ``` ## 9. 数据迁移 ### 9.1 版本升级迁移 #### 9.1.1 数据格式版本管理 ```python DATA_FORMAT_VERSION = "1.0" def check_data_format_version(): """检查数据格式版本""" version_file = Path("data/version.json") if not version_file.exists(): # 首次运行,创建版本文件 create_version_file() return True with open(version_file, 'r') as f: version_data = json.load(f) current_version = version_data.get("version", "0.0") if current_version != DATA_FORMAT_VERSION: logger.info(f"检测到数据格式升级: {current_version} -> {DATA_FORMAT_VERSION}") migrate_data(current_version, DATA_FORMAT_VERSION) update_version_file() return True ``` #### 9.1.2 数据迁移处理 ```python def migrate_data(from_version: str, to_version: str): """执行数据迁移""" logger.info(f"开始数据迁移: {from_version} -> {to_version}") # 备份原始数据 backup_path = backup_data() logger.info(f"原始数据已备份到: {backup_path}") try: if from_version == "0.9" and to_version == "1.0": migrate_0_9_to_1_0() # 添加其他版本迁移逻辑 logger.info("数据迁移完成") except Exception as e: logger.error(f"数据迁移失败: {str(e)}") raise def migrate_0_9_to_1_0(): """0.9版本到1.0版本的迁移""" # 示例:添加platform字段 for device in device_manager.devices.values(): if not hasattr(device, 'platform') or not device.platform: # 根据vendor自动推断platform if device.vendor == DeviceVendor.CISCO: device.platform = "cisco_iosxe" elif device.vendor == DeviceVendor.HUAWEI: device.platform = "huawei_vrp" # 添加其他厂商映射 # 保存迁移后的数据 device_manager.save_data() ``` ## 10. 监控和维护 ### 10.1 数据健康检查 ```python def health_check(): """数据健康检查""" issues = [] # 检查数据文件完整性 if not Path("data/devices.json").exists(): issues.append("设备数据文件缺失") if not Path("data/credentials.json").exists(): issues.append("凭据数据文件缺失") # 检查数据一致性 for device in device_manager.devices.values(): if device.credential_id and not device_manager.get_credential(device.credential_id): issues.append(f"设备 {device.name} 引用的凭据不存在: {device.credential_id}") # 检查缓存目录 if not Path("resource_cache").exists(): issues.append("资源缓存目录缺失") if issues: logger.warning(f"发现 {len(issues)} 个数据问题:") for issue in issues: logger.warning(f" - {issue}") else: logger.info("数据健康检查通过") return len(issues) == 0 ``` ### 10.2 存储空间管理 ```python def get_storage_usage(): """获取存储使用情况""" def get_dir_size(path): total = 0 for dirpath, dirnames, filenames in os.walk(path): for filename in filenames: filepath = os.path.join(dirpath, filename) if os.path.exists(filepath): total += os.path.getsize(filepath) return total usage = { "data": get_dir_size("data") if Path("data").exists() else 0, "cache": get_dir_size("resource_cache") if Path("resource_cache").exists() else 0, "logs": get_dir_size("logs") if Path("logs").exists() else 0, "templates": get_dir_size("templates") if Path("templates").exists() else 0 } total = sum(usage.values()) logger.info(f"存储使用情况 (总计: {total / 1024 / 1024:.2f} MB):") for category, size in usage.items(): logger.info(f" {category}: {size / 1024 / 1024:.2f} MB") return usage ``` ## 11. 总结 NetBrain MCP的数据存储设计采用了轻量级、高效的JSON文件存储方案,具有以下特点: ### 11.1 设计优势 - **简单可靠**:JSON格式人类可读,便于维护和调试 - **无依赖性**:无需额外的数据库服务器 - **跨平台**:完全兼容各种操作系统 - **快速部署**:零配置即可使用 - **易于备份**:简单的文件复制即可备份 ### 11.2 性能特性 - **双层缓存**:内存+文件双层缓存机制 - **智能过期**:基于TTL的缓存过期策略 - **批量操作**:支持批量数据操作以减少I/O - **索引优化**:内存索引提高查询性能 ### 11.3 扩展能力 - **版本迁移**:完整的数据格式升级迁移机制 - **健康检查**:数据完整性和一致性检查 - **监控告警**:存储使用情况监控 - **安全增强**:计划实施数据加密存储 这种数据存储设计很好地平衡了简单性、性能和可维护性,为NetBrain MCP系统提供了稳定可靠的数据持久化基础。

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/NorthLaneMS/NetBrain_MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server