Skip to main content
Glama

health_check

Monitor server health and performance metrics to detect issues and ensure system reliability. Generate detailed reports for comprehensive analysis.

Instructions

獲取服務器健康狀態和性能指標

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
detailedNo是否返回詳細報告

Implementation Reference

  • src/index.js:169-183 (registration)
    Registers the 'health_check' tool in the tool registry, including its name, description, input schema (detailed boolean), scope, and inline handler function that delegates to healthChecker.getHealthReport() or getSimpleHealth() based on the 'detailed' parameter.
    registerTool({
      name: 'health_check',
      description: '獲取服務器健康狀態和性能指標',
      inputSchema: z.object({
        detailed: z.boolean().default(false).describe('是否返回詳細報告')
      }),
      scope: 'system',
      async handler(args) {
        if (args.detailed) {
          return await healthChecker.getHealthReport();
        } else {
          return await healthChecker.getSimpleHealth();
        }
      }
    }, 'system');
  • Implementation of getHealthReport() called by the health_check tool handler for detailed reports, aggregating health checks, metrics, memory usage, and manager sizes.
    async getHealthReport() {
      const healthCheck = await this.checkHealth();
      const metrics = this.metrics.getMetrics();
      const memUsage = process.memoryUsage();
    
      return {
        status: healthCheck.status,
        timestamp: healthCheck.timestamp,
        uptime: metrics.uptime,
        version: process.env.npm_package_version || '0.1.0',
        node_version: process.version,
        pid: process.pid,
        memory: {
          rss: memUsage.rss,
          heapTotal: memUsage.heapTotal,
          heapUsed: memUsage.heapUsed,
          external: memUsage.external,
          heapUsedPercent: ((memUsage.heapUsed / memUsage.heapTotal) * 100).toFixed(2)
        },
        metrics: {
          requests: metrics.requests,
          latency: metrics.latency,
          cache: metrics.cache
        },
        checks: healthCheck.checks,
        managers: {
          shortTerm: this.managers.shortTerm?.size || 0,
          longTerm: this.managers.longTerm?.size || 0,
          storage: this.managers.storage?.size || 0
        }
      };
    }
  • Implementation of getSimpleHealth() called by the health_check tool handler for simple reports, providing status, timestamp, and uptime.
    async getSimpleHealth() {
      const healthCheck = await this.checkHealth();
      return {
        status: healthCheck.status,
        timestamp: healthCheck.timestamp,
        uptime: process.uptime()
      };
    }
  • Core checkHealth() method in HealthChecker class that executes all registered health checks (memory, error_rate, cache) and determines overall status.
    async checkHealth() {
      const results = {};
      let overallStatus = HealthStatus.HEALTHY;
    
      for (const [name, checkFn] of this.checks.entries()) {
        try {
          const result = await checkFn();
          results[name] = result;
    
          // 更新整體狀態
          if (result.status === HealthStatus.UNHEALTHY) {
            overallStatus = HealthStatus.UNHEALTHY;
          } else if (result.status === HealthStatus.DEGRADED && overallStatus !== HealthStatus.UNHEALTHY) {
            overallStatus = HealthStatus.DEGRADED;
          }
        } catch (error) {
          results[name] = {
            status: HealthStatus.UNHEALTHY,
            message: `Check failed: ${error.message}`,
            error: error.message
          };
          overallStatus = HealthStatus.UNHEALTHY;
        }
      }
    
      this.lastCheckTime = new Date().toISOString();
      this.lastStatus = overallStatus;
    
      return {
        status: overallStatus,
        timestamp: this.lastCheckTime,
        checks: results
      };
    }
  • HealthStatus constants used throughout the health checking logic.
    export const HealthStatus = {
      HEALTHY: 'healthy',
      DEGRADED: 'degraded',
      UNHEALTHY: 'unhealthy'
    };
    
    /**
     * 健康檢查器
     */
    export class HealthChecker {
      constructor(managers, metrics) {
        this.managers = managers;
        this.metrics = metrics;
        this.checks = new Map();
        this.lastCheckTime = null;
        this.lastStatus = HealthStatus.HEALTHY;
    
        // 註冊默認檢查
        this.registerDefaultChecks();
      }
    
      /**
       * 註冊默認健康檢查
       */
      registerDefaultChecks() {
        // 內存檢查
        this.registerCheck('memory', async () => {
          const memUsage = process.memoryUsage();
          const heapUsedPercent = (memUsage.heapUsed / memUsage.heapTotal) * 100;
    
          if (heapUsedPercent > 90) {
            return {
              status: HealthStatus.UNHEALTHY,
              message: `Heap usage critical: ${heapUsedPercent.toFixed(2)}%`
            };
          } else if (heapUsedPercent > 75) {
            return {
              status: HealthStatus.DEGRADED,
              message: `Heap usage high: ${heapUsedPercent.toFixed(2)}%`
            };
          }
    
          return {
            status: HealthStatus.HEALTHY,
            message: `Heap usage normal: ${heapUsedPercent.toFixed(2)}%`
          };
        });
    
        // 錯誤率檢查
        this.registerCheck('error_rate', async () => {
          const metrics = this.metrics.getMetrics();
          const errorRate = parseFloat(metrics.requests.errorRate);
    
          if (errorRate > 50) {
            return {
              status: HealthStatus.UNHEALTHY,
              message: `Error rate critical: ${errorRate}%`
            };
          } else if (errorRate > 20) {
            return {
              status: HealthStatus.DEGRADED,
              message: `Error rate elevated: ${errorRate}%`
            };
          }
    
          return {
            status: HealthStatus.HEALTHY,
            message: `Error rate normal: ${errorRate}%`
          };
        });
    
        // 緩存檢查
        this.registerCheck('cache', async () => {
          if (!this.managers.shortTerm || !this.managers.longTerm) {
            return {
              status: HealthStatus.HEALTHY,
              message: 'Cache managers initialized'
            };
          }
    
          const stSize = this.managers.shortTerm.size;
          const ltSize = this.managers.longTerm.size;
    
          if (stSize > 500 || ltSize > 500) {
            return {
              status: HealthStatus.DEGRADED,
              message: `Cache size high: ST=${stSize}, LT=${ltSize}`
            };
          }
    
          return {
            status: HealthStatus.HEALTHY,
            message: `Cache size normal: ST=${stSize}, LT=${ltSize}`
          };
        });
      }
    
      /**
       * 註冊健康檢查
       * @param {string} name - 檢查名稱
       * @param {Function} checkFn - 檢查函數
       */
      registerCheck(name, checkFn) {
        this.checks.set(name, checkFn);
      }
    
      /**
       * 執行所有健康檢查
       * @returns {Promise<Object>}
       */
      async checkHealth() {
        const results = {};
        let overallStatus = HealthStatus.HEALTHY;
    
        for (const [name, checkFn] of this.checks.entries()) {
          try {
            const result = await checkFn();
            results[name] = result;
    
            // 更新整體狀態
            if (result.status === HealthStatus.UNHEALTHY) {
              overallStatus = HealthStatus.UNHEALTHY;
            } else if (result.status === HealthStatus.DEGRADED && overallStatus !== HealthStatus.UNHEALTHY) {
              overallStatus = HealthStatus.DEGRADED;
            }
          } catch (error) {
            results[name] = {
              status: HealthStatus.UNHEALTHY,
              message: `Check failed: ${error.message}`,
              error: error.message
            };
            overallStatus = HealthStatus.UNHEALTHY;
          }
        }
    
        this.lastCheckTime = new Date().toISOString();
        this.lastStatus = overallStatus;
    
        return {
          status: overallStatus,
          timestamp: this.lastCheckTime,
          checks: results
        };
      }
    
      /**
       * 獲取完整的健康報告
       * @returns {Promise<Object>}
       */
      async getHealthReport() {
        const healthCheck = await this.checkHealth();
        const metrics = this.metrics.getMetrics();
        const memUsage = process.memoryUsage();
    
        return {
          status: healthCheck.status,
          timestamp: healthCheck.timestamp,
          uptime: metrics.uptime,
          version: process.env.npm_package_version || '0.1.0',
          node_version: process.version,
          pid: process.pid,
          memory: {
            rss: memUsage.rss,
            heapTotal: memUsage.heapTotal,
            heapUsed: memUsage.heapUsed,
            external: memUsage.external,
            heapUsedPercent: ((memUsage.heapUsed / memUsage.heapTotal) * 100).toFixed(2)
          },
          metrics: {
            requests: metrics.requests,
            latency: metrics.latency,
            cache: metrics.cache
          },
          checks: healthCheck.checks,
          managers: {
            shortTerm: this.managers.shortTerm?.size || 0,
            longTerm: this.managers.longTerm?.size || 0,
            storage: this.managers.storage?.size || 0
          }
        };
      }
    
      /**
       * 獲取簡單的健康狀態
       * @returns {Promise<Object>}
       */
      async getSimpleHealth() {
        const healthCheck = await this.checkHealth();
        return {
          status: healthCheck.status,
          timestamp: healthCheck.timestamp,
          uptime: process.uptime()
        };
      }
    }
    
    /**
     * 創建健康檢查器
     * @param {Object} managers - 管理器對象
     * @param {Object} metrics - 指標收集器
     * @returns {HealthChecker}
     */
    export function createHealthChecker(managers, metrics) {
      return new HealthChecker(managers, metrics);
    }
    
    export default { HealthChecker, createHealthChecker, HealthStatus };

Latest Blog Posts

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/win10ogod/memory-mcp-server'

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