跳转至

监控系统

监控系统在执行期间提供 Stata 进程的实时监控。此功能旨在防止资源耗尽并提高系统稳定性。

概述

监控系统默认禁用以保持 100% 的向后兼容性。启用时,它监控 Stata 子进程执行,并可自动终止超过配置资源限制的进程。

当前功能

  • RAM 监控:跟踪内存使用并终止超过 RAM 限制的进程
  • 跨平台:使用 psutil 在 macOS、Linux 和 Windows 上工作
  • 非侵入式:禁用时开销极小,启用时为守护线程
  • 可扩展:抽象基类用于添加新的监控类型(例如超时监控)

架构

MonitorBase

所有监控器实现的抽象基类:

class MonitorBase(ABC):
    @abstractmethod
    def start(self, process: Any) -> None:
        """开始监控给定进程。"""
        pass

    @abstractmethod
    def stop(self) -> None:
        """停止监控。"""
        pass

RAMMonitor

监控 Stata 进程的 RAM 使用:

  • 检查间隔:0.5 秒
  • 指标:RSS(驻留集大小),单位 MB
  • 动作:超过限制时杀死进程
  • 错误:抛出带详情的 RAMLimitExceededError

配置

启用监控

监控由两个配置选项控制:

选项 1:配置文件

编辑 ~/.statamcp/config.toml

[MONITOR]
IS_MONITOR = true
MAX_RAM_MB = 8192  # 8 GB 限制

选项 2:环境变量

export STATA_MCP__IS_MONITOR=true
export STATA_MCP__RAM_LIMIT=8192

配置优先级

  1. 环境变量(最高)
  2. 配置文件(~/.statamcp/config.toml
  3. 默认值(最低)

RAM 限制值

  • -1None:无限制(默认)
  • 0:不推荐(将立即杀死)
  • 正值:以 MB 为单位的 RAM 限制

示例:

# 无限制(默认)
export STATA_MCP__RAM_LIMIT=-1

# 4 GB 限制
export STATA_MCP__RAM_LIMIT=4096

# 8 GB 限制
export STATA_MCP__RAM_LIMIT=8192

# 16 GB 限制
export STATA_MCP__RAM_LIMIT=16384

使用

基本设置

  1. 在配置中启用监控bash export STATA_MCP__IS_MONITOR=true export STATA_MCP__RAM_LIMIT=8192

  2. 正常运行 Stata-MCPbash stata-mcp # 或 stata-mcp agent run

  3. 启用时监控自动进行

  4. 无需代码更改
  5. 适用于所有 MCP 工具
  6. 与现有工作流程无缝集成

编程使用

如果您将 Stata-MCP 作为库使用:

from stata_mcp.monitor import RAMMonitor
from stata_mcp.core.stata import StataDo

# 创建带 8GB 限制的监控器
monitor = RAMMonitor(max_ram_mb=8192)

# 传递给 StataDo
stata = StataDo(
    dofile_path="analysis.do",
    monitors=[monitor]  # 可选:监控器列表
)

# 执行自动被监控
result = stata.execute()

行为

当超过 RAM 限制时

  1. 检测:监控器检测到 RAM 使用 > 限制
  2. 日志记录:记录带详情的警告
  3. 终止:立即杀死进程
  4. 错误:抛出 RAMLimitExceededError

示例输出

WARNING: RAM limit exceeded: 8256MB > 8192MB. Killing Stata process (PID: 12345)
ERROR: RAM limit exceeded: Used 8256MB, Limit 8192MB

正常完成

如果进程在超过限制前完成: - 监控器优雅停止 - 不抛出错误 - 正常执行流程继续

性能考虑

开销

  • 禁用:零开销(默认)
  • 启用:守护线程带来的极小开销
  • 每 0.5 秒进行一次 RAM 检查
  • 使用 psutil 实现跨平台兼容性

建议

对于生产环境

[MONITOR]
IS_MONITOR = true
MAX_RAM_MB = 16384  # 根据您的硬件设置合理限制

对于开发环境

[MONITOR]
IS_MONITOR = false  # 禁用以避免意外终止

对于高性能计算

[MONITOR]
IS_MONITOR = true
MAX_RAM_MB = 65536  # 64 GB 用于大数据集

错误处理

RAMLimitExceededError

当超过 RAM 限制时抛出:

from stata_mcp.core.types import RAMLimitExceededError

try:
    result = stata.execute()
except RAMLimitExceededError as e:
    print(f"RAM exceeded: {e.ram_used_mb:.0f}MB > {e.ram_limit_mb}MB")
    # 处理错误:保存工作、通知用户等

错误属性: - ram_used_mb:超过限制时实际使用的 RAM - ram_limit_mb:配置的 RAM 限制

可扩展性

创建自定义监控器

您可以通过扩展 MonitorBase 创建自定义监控器:

from stata_mcp.monitor.base import MonitorBase
import time
import threading

class TimeoutMonitor(MonitorBase):
    """监控并超时长时间运行的进程。"""

    def __init__(self, timeout_seconds: int):
        self.timeout = timeout_seconds
        self._start_time = None
        self._monitor_thread = None
        self._stop_event = threading.Event()

    def start(self, process):
        """开始超时监控。"""
        self._start_time = time.time()
        self.process = process

        def monitor_loop():
            while not self._stop_event.is_set():
                if time.time() - self._start_time > self.timeout:
                    self.process.kill()
                    break
                self._stop_event.wait(1)

        self._monitor_thread = threading.Thread(
            target=monitor_loop,
            daemon=True
        )
        self._monitor_thread.start()

    def stop(self):
        """停止监控。"""
        self._stop_event.set()
        if self._monitor_thread:
            self._monitor_thread.join(timeout=1.0)

使用多个监控器

您可以同时使用多个监控器:

from stata_mcp.monitor import RAMMonitor, TimeoutMonitor

# 创建多个监控器
ram_monitor = RAMMonitor(max_ram_mb=8192)
timeout_monitor = TimeoutMonitor(timeout_seconds=3600)

# 传递给 StataDo
stata = StataDo(
    dofile_path="analysis.do",
    monitors=[ram_monitor, timeout_monitor]
)

故障排除

监控器不工作

  1. 检查是否启用监控bash echo $STATA_MCP__IS_MONITOR

  2. 验证配置文件语法bash cat ~/.statamcp/config.toml

  3. 检查环境变量冲突bash env | grep STATA_MCP

进程意外被杀死

  1. 检查 RAM 限制是否合理bash echo $STATA_MCP__RAM_LIMIT

  2. 查看日志了解终止原因bash tail -f ~/.statamcp/stata_mcp_debug.log

  3. 如需要增加限制bash export STATA_MCP__RAM_LIMIT=16384

psutil 问题

如果遇到 psutil 错误:

  1. 确保 psutil 已安装bash uv pip install psutil>=6.0.0

  2. 检查 psutil 版本bash python3 -c "import psutil; print(psutil.__version__)"

  3. 验证进程访问权限(Linux/macOS): bash # 监控器应该有访问子进程的权限 # 子进程不需要特殊操作

最佳实践

1. 从无限制开始

对于初始测试:

export STATA_MCP__IS_MONITOR=true
export STATA_MCP__RAM_LIMIT=-1  # 最初无限制

2. 监控典型使用

运行典型工作负载并观察日志中的 RAM 使用。

3. 设置合理限制

将限制设置为典型使用量的 20-50% 以上:

# 如果典型使用量是 6GB
export STATA_MCP__RAM_LIMIT=8192  # 8GB 限制

4. 测试边缘情况

使用大数据集测试以确保限制适当。

5. 记录限制

在项目文档中为团队成员记录 RAM 限制。

安全考虑

  • 监控器在守护线程中运行(主线程退出时终止)
  • 不需要权限提升
  • 使用标准 psutil 库实现跨平台兼容性
  • 监控器只能访问它创建的子进程

未来增强

未来可能的监控类型: - 超时监控器:限制执行时间 - CPU 监控器:跟踪 CPU 使用百分比 - 磁盘 I/O 监控器:监控磁盘读写操作 - 网络监控器:跟踪网络活动(如适用)

注意事项

  • 此功能是在 Claude Code 和 GLM-4.7 的协助下开发的
  • 监控是通过配置选择性加入
  • 禁用时,行为与以前版本 100% 相同
  • 监控系统设计为可扩展,以支持未来的用例