首页 / 应用软件 / 一步步教你,为WordPress添加网站性能监控与告警功能

一步步教你,为WordPress添加网站性能监控与告警功能

一步步教你,为WordPress添加网站性能监控与告警功能

引言:为什么WordPress网站需要性能监控与告警

在当今数字化时代,网站性能直接影响用户体验、搜索引擎排名和业务转化率。根据Google的研究,页面加载时间每增加1秒,移动端跳出率就会增加20%。对于基于WordPress构建的网站而言,随着插件、主题和内容的不断增加,性能问题往往悄然而至。

许多WordPress站长依赖第三方监控服务,但这些服务往往价格昂贵,且无法深度集成到WordPress管理后台。通过代码二次开发,我们可以为WordPress添加自定义的性能监控与告警功能,不仅能节省成本,还能根据具体需求定制监控指标和告警规则。

本文将详细指导您如何通过WordPress代码二次开发,实现一个完整的网站性能监控与告警系统,涵盖从基础监控到高级告警功能的完整实现过程。

第一部分:准备工作与环境配置

1.1 理解WordPress钩子机制

WordPress的强大之处在于其完善的钩子(Hooks)系统,包括动作(Actions)和过滤器(Filters)。我们的性能监控系统将大量使用这些钩子来插入监控代码。

// 示例:WordPress钩子的基本使用
add_action('init', 'my_monitoring_init');
function my_monitoring_init() {
    // 初始化监控系统
}

add_filter('the_content', 'my_content_monitor');
function my_content_monitor($content) {
    // 监控内容加载
    return $content;
}

1.2 创建专用插件目录结构

为了保持代码的整洁和可维护性,我们创建一个独立的插件来实现监控功能:

wp-performance-monitor/
├── performance-monitor.php      # 主插件文件
├── includes/
│   ├── class-monitor-core.php   # 监控核心类
│   ├── class-alert-system.php   # 告警系统类
│   ├── class-dashboard-widget.php # 仪表板小工具
│   └── class-data-storage.php   # 数据存储类
├── assets/
│   ├── css/
│   │   └── admin-styles.css     # 管理界面样式
│   └── js/
│       └── admin-scripts.js     # 管理界面脚本
├── templates/
│   └── admin-dashboard.php      # 管理面板模板
└── vendor/                      # 第三方库(如果需要)

1.3 主插件文件配置

创建主插件文件 performance-monitor.php

<?php
/**
 * Plugin Name: WordPress性能监控与告警系统
 * Plugin URI: https://yourwebsite.com/
 * Description: 为WordPress添加网站性能监控与告警功能
 * Version: 1.0.0
 * Author: 您的名称
 * License: GPL v2 or later
 * Text Domain: wp-performance-monitor
 */

// 防止直接访问
if (!defined('ABSPATH')) {
    exit;
}

// 定义插件常量
define('WPPM_VERSION', '1.0.0');
define('WPPM_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('WPPM_PLUGIN_URL', plugin_dir_url(__FILE__));
define('WPPM_CAPABILITY', 'manage_options');

// 自动加载类文件
spl_autoload_register(function ($class_name) {
    $prefix = 'WPPM_';
    $base_dir = WPPM_PLUGIN_DIR . 'includes/';
    
    if (strpos($class_name, $prefix) !== 0) {
        return;
    }
    
    $relative_class = substr($class_name, strlen($prefix));
    $file = $base_dir . 'class-' . str_replace('_', '-', strtolower($relative_class)) . '.php';
    
    if (file_exists($file)) {
        require_once $file;
    }
});

// 初始化插件
function wppm_init_plugin() {
    // 检查WordPress版本
    if (version_compare(get_bloginfo('version'), '5.0', '<')) {
        add_action('admin_notices', function() {
            echo '<div class="notice notice-error"><p>';
            echo __('WordPress性能监控插件需要WordPress 5.0或更高版本。', 'wp-performance-monitor');
            echo '</p></div>';
        });
        return;
    }
    
    // 初始化核心组件
    WPPM_Monitor_Core::get_instance();
    WPPM_Alert_System::get_instance();
    
    // 如果是管理后台,初始化管理界面
    if (is_admin()) {
        WPPM_Dashboard_Widget::get_instance();
    }
}
add_action('plugins_loaded', 'wppm_init_plugin');

// 插件激活钩子
register_activation_hook(__FILE__, 'wppm_activate_plugin');
function wppm_activate_plugin() {
    // 创建必要的数据库表
    wppm_create_database_tables();
    
    // 设置默认选项
    $default_options = array(
        'monitoring_enabled' => true,
        'alert_enabled' => true,
        'performance_threshold' => 3, // 3秒
        'uptime_monitoring' => true,
        'data_retention_days' => 30,
    );
    
    add_option('wppm_settings', $default_options);
    
    // 添加定时任务
    if (!wp_next_scheduled('wppm_daily_maintenance')) {
        wp_schedule_event(time(), 'daily', 'wppm_daily_maintenance');
    }
}

// 插件停用钩子
register_deactivation_hook(__FILE__, 'wppm_deactivate_plugin');
function wppm_deactivate_plugin() {
    // 清除定时任务
    wp_clear_scheduled_hook('wppm_daily_maintenance');
}

第二部分:核心监控功能实现

2.1 页面加载时间监控

页面加载时间是衡量网站性能的关键指标。我们将通过测量WordPress核心加载时间、主题初始化和页面渲染时间来实现全面监控。

// includes/class-monitor-core.php
class WPPM_Monitor_Core {
    private static $instance = null;
    private $start_time;
    private $memory_start;
    
    public static function get_instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    private function __construct() {
        $this->start_time = microtime(true);
        $this->memory_start = memory_get_usage();
        
        // 在WordPress加载的不同阶段添加监控点
        add_action('init', array($this, 'track_init_time'));
        add_action('wp_loaded', array($this, 'track_wp_loaded_time'));
        add_action('wp', array($this, 'track_wp_time'));
        add_action('shutdown', array($this, 'track_shutdown_time'));
        
        // 监控数据库查询
        add_filter('query', array($this, 'track_database_query'));
        
        // 监控内存使用
        add_action('shutdown', array($this, 'track_memory_usage'));
    }
    
    public function track_init_time() {
        $this->add_performance_point('init', 'WordPress初始化完成');
    }
    
    public function track_wp_loaded_time() {
        $this->add_performance_point('wp_loaded', 'WordPress完全加载');
    }
    
    public function track_wp_time() {
        $this->add_performance_point('wp', '主查询已设置');
    }
    
    public function track_shutdown_time() {
        $total_time = microtime(true) - $this->start_time;
        $this->add_performance_point('shutdown', '页面完全渲染', $total_time);
        
        // 保存性能数据
        $this->save_performance_data($total_time);
    }
    
    private function add_performance_point($stage, $description, $custom_time = null) {
        $time = $custom_time ?: (microtime(true) - $this->start_time);
        
        // 存储到全局变量中,供后续使用
        global $wppm_performance_data;
        if (!isset($wppm_performance_data)) {
            $wppm_performance_data = array();
        }
        
        $wppm_performance_data[$stage] = array(
            'time' => round($time, 4),
            'description' => $description,
            'timestamp' => current_time('mysql')
        );
    }
    
    public function track_database_query($query) {
        if (defined('SAVEQUERIES') && SAVEQUERIES) {
            // WordPress已启用查询保存,我们可以直接使用
            return $query;
        }
        
        // 简单查询监控(不记录查询内容以保护隐私)
        global $wppm_db_queries;
        if (!isset($wppm_db_queries)) {
            $wppm_db_queries = 0;
        }
        $wppm_db_queries++;
        
        return $query;
    }
    
    public function track_memory_usage() {
        $memory_end = memory_get_usage();
        $memory_peak = memory_get_peak_usage();
        $memory_used = $memory_end - $this->memory_start;
        
        global $wppm_performance_data;
        if (!isset($wppm_performance_data)) {
            $wppm_performance_data = array();
        }
        
        $wppm_performance_data['memory'] = array(
            'used' => $this->format_bytes($memory_used),
            'peak' => $this->format_bytes($memory_peak),
            'limit' => ini_get('memory_limit')
        );
    }
    
    private function save_performance_data($total_time) {
        global $wppm_performance_data, $wppm_db_queries;
        
        // 获取当前页面信息
        $current_url = home_url($_SERVER['REQUEST_URI']);
        $is_admin = is_admin();
        $user_role = 'guest';
        
        if (is_user_logged_in()) {
            $user = wp_get_current_user();
            $user_role = implode(',', $user->roles);
        }
        
        // 准备性能数据
        $performance_data = array(
            'url' => $current_url,
            'total_time' => $total_time,
            'is_admin' => $is_admin,
            'user_role' => $user_role,
            'performance_points' => $wppm_performance_data,
            'db_queries' => $wppm_db_queries ?? 0,
            'timestamp' => current_time('mysql'),
            'server_load' => function_exists('sys_getloadavg') ? sys_getloadavg()[0] : 0
        );
        
        // 保存到数据库
        $this->store_performance_record($performance_data);
        
        // 检查是否触发告警
        $this->check_performance_alerts($performance_data);
    }
    
    private function store_performance_record($data) {
        global $wpdb;
        
        $table_name = $wpdb->prefix . 'wppm_performance_logs';
        
        $wpdb->insert(
            $table_name,
            array(
                'url' => substr($data['url'], 0, 500),
                'total_time' => $data['total_time'],
                'is_admin' => $data['is_admin'] ? 1 : 0,
                'user_role' => $data['user_role'],
                'performance_data' => maybe_serialize($data['performance_points']),
                'db_queries' => $data['db_queries'],
                'server_load' => $data['server_load'],
                'created_at' => $data['timestamp']
            ),
            array('%s', '%f', '%d', '%s', '%s', '%d', '%f', '%s')
        );
    }
    
    private function format_bytes($bytes, $precision = 2) {
        $units = array('B', 'KB', 'MB', 'GB', 'TB');
        
        $bytes = max($bytes, 0);
        $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
        $pow = min($pow, count($units) - 1);
        
        $bytes /= pow(1024, $pow);
        
        return round($bytes, $precision) . ' ' . $units[$pow];
    }
}

2.2 数据库性能监控

数据库是WordPress网站性能的关键瓶颈之一。我们需要监控查询数量、慢查询和数据库连接时间。

// 扩展监控核心类,添加数据库监控
class WPPM_DB_Monitor {
    private $queries = array();
    private $slow_query_threshold = 0.1; // 100毫秒
    
    public function __construct() {
        // 如果SAVEQUERIES未启用,我们需要自己监控
        if (!defined('SAVEQUERIES') || !SAVEQUERIES) {
            add_filter('query', array($this, 'capture_query'));
        }
        
        add_action('shutdown', array($this, 'analyze_queries'));
    }
    
    public function capture_query($query) {
        $start_time = microtime(true);
        
        // 执行查询并计算时间
        $result = $this->execute_query($query);
        
        $end_time = microtime(true);
        $execution_time = $end_time - $start_time;
        
        // 记录查询信息
        $this->queries[] = array(
            'query' => $this->sanitize_query($query),
            'time' => $execution_time,
            'trace' => $this->get_query_trace(),
            'timestamp' => microtime(true)
        );
        
        return $result;
    }
    
    public function analyze_queries() {
        if (empty($this->queries)) {
            return;
        }
        
        $total_query_time = 0;
        $slow_queries = array();
        
        foreach ($this->queries as $query) {
            $total_query_time += $query['time'];
            
            if ($query['time'] > $this->slow_query_threshold) {
                $slow_queries[] = $query;
            }
        }
        
        // 保存分析结果
        $this->save_query_analysis($total_query_time, $slow_queries);
    }
    
    private function save_query_analysis($total_time, $slow_queries) {
        global $wpdb;
        
        $table_name = $wpdb->prefix . 'wppm_query_logs';
        
        $wpdb->insert(
            $table_name,
            array(
                'total_queries' => count($this->queries),
                'total_query_time' => $total_time,
                'slow_queries' => maybe_serialize($slow_queries),
                'average_query_time' => count($this->queries) > 0 ? $total_time / count($this->queries) : 0,
                'created_at' => current_time('mysql')
            ),
            array('%d', '%f', '%s', '%f', '%s')
        );
    }
    
    private function sanitize_query($query) {
        // 移除敏感数据(如密码)
        $query = preg_replace('/passwords*=s*'.*?'/i', "password = '***'", $query);
        $query = preg_replace('/passwords*=s*".*?"/i', 'password = "***"', $query);
        
        return substr($query, 0, 1000); // 限制长度
    }
    
    private function get_query_trace() {
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10);
        $simplified_trace = array();
        
        foreach ($trace as $item) {
            if (isset($item['file']) && strpos($item['file'], 'wp-content') !== false) {
                $simplified_trace[] = array(
                    'file' => str_replace(ABSPATH, '', $item['file']),
                    'line' => $item['line'] ?? 0,
                    'function' => $item['function'] ?? ''
                );
            }
        }
        
        return $simplified_trace;
    }
}

2.3 服务器资源监控

监控服务器资源使用情况,包括CPU、内存和磁盘空间。

// includes/class-server-monitor.php
class WPPM_Server_Monitor {
    
    public static function get_server_stats() {
        $stats = array(
            'cpu' => self::get_cpu_usage(),
            'memory' => self::get_memory_usage(),
            'disk' => self::get_disk_usage(),
            'php' => self::get_php_stats(),
            'mysql' => self::get_mysql_stats(),
            'timestamp' => current_time('mysql')
        );
        
        return $stats;
    }
    
    private static function get_cpu_usage() {
        if (!function_exists('sys_getloadavg')) {
            return array('error' => '无法获取CPU负载信息');
        }
        
        $load = sys_getloadavg();
        
        return array(
            '1min' => $load[0],
            '5min' => $load[1],
            '15min' => $load[2],
            'cores' => self::get_cpu_cores()
        );
    }
    
    private static function get_cpu_cores() {
        if (is_readable('/proc/cpuinfo')) {
            $cpuinfo = file_get_contents('/proc/cpuinfo');
            preg_match_all('/^processor/m', $cpuinfo, $matches);
            return count($matches[0]);
        }
        
        // 备用方法
        $cores = intval(shell_exec('nproc 2>/dev/null'));
        return $cores > 0 ? $cores : 1;
    }
    
    private static function get_memory_usage() {
        if (!is_readable('/proc/meminfo')) {
            return array('error' => '无法获取内存信息');
        }
        
        $meminfo = file_get_contents('/proc/meminfo');
        $memory = array();
        
        preg_match('/MemTotal:s+(d+)/', $meminfo, $matches);
        $memory['total'] = $matches[1] ?? 0;
        
        preg_match('/MemFree:s+(d+)/', $meminfo, $matches);
        $memory['free'] = $matches[1] ?? 0;
        
    $memory['available'] = $matches[1] ?? 0;
    
    preg_match('/Cached:s+(d+)/', $meminfo, $matches);
    $memory['cached'] = $matches[1] ?? 0;
    
    // 计算使用率
    if ($memory['total'] > 0) {
        $memory['used'] = $memory['total'] - $memory['available'];
        $memory['usage_percent'] = round(($memory['used'] / $memory['total']) * 100, 2);
    }
    
    return $memory;
}

private static function get_disk_usage() {
    $disk_total = disk_total_space(ABSPATH);
    $disk_free = disk_free_space(ABSPATH);
    
    if ($disk_total === false || $disk_free === false) {
        return array('error' => '无法获取磁盘信息');
    }
    
    $disk_used = $disk_total - $disk_free;
    $usage_percent = ($disk_total > 0) ? round(($disk_used / $disk_total) * 100, 2) : 0;
    
    return array(
        'total' => $disk_total,
        'free' => $disk_free,
        'used' => $disk_used,
        'usage_percent' => $usage_percent,
        'total_human' => self::format_bytes($disk_total),
        'free_human' => self::format_bytes($disk_free),
        'used_human' => self::format_bytes($disk_used)
    );
}

private static function get_php_stats() {
    return array(
        'version' => PHP_VERSION,
        'memory_limit' => ini_get('memory_limit'),
        'max_execution_time' => ini_get('max_execution_time'),
        'upload_max_filesize' => ini_get('upload_max_filesize'),
        'post_max_size' => ini_get('post_max_size'),
        'extensions' => get_loaded_extensions()
    );
}

private static function get_mysql_stats() {
    global $wpdb;
    
    $stats = array();
    
    // 获取MySQL版本
    $version = $wpdb->get_var("SELECT VERSION()");
    $stats['version'] = $version;
    
    // 获取数据库大小
    $db_name = DB_NAME;
    $size_query = $wpdb->get_row(
        "SELECT 
            SUM(data_length + index_length) as size
        FROM information_schema.TABLES 
        WHERE table_schema = '$db_name'
        GROUP BY table_schema"
    );
    
    $stats['database_size'] = $size_query ? $size_query->size : 0;
    $stats['database_size_human'] = self::format_bytes($stats['database_size']);
    
    // 获取表状态
    $tables = $wpdb->get_results("SHOW TABLE STATUS");
    $stats['tables'] = count($tables);
    
    return $stats;
}

private static function format_bytes($bytes, $precision = 2) {
    $units = array('B', 'KB', 'MB', 'GB', 'TB');
    
    $bytes = max($bytes, 0);
    $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
    $pow = min($pow, count($units) - 1);
    
    $bytes /= pow(1024, $pow);
    
    return round($bytes, $precision) . ' ' . $units[$pow];
}

}


## 第三部分:告警系统实现

### 3.1 告警规则配置与管理

// includes/class-alert-system.php
class WPPM_Alert_System {

private static $instance = null;
private $alert_rules = array();

public static function get_instance() {
    if (null === self::$instance) {
        self::$instance = new self();
    }
    return self::$instance;
}

private function __construct() {
    $this->load_alert_rules();
    
    // 添加定时检查任务
    add_action('wppm_check_alerts', array($this, 'check_all_alerts'));
    
    // 注册定时任务
    if (!wp_next_scheduled('wppm_check_alerts')) {
        wp_schedule_event(time(), 'hourly', 'wppm_check_alerts');
    }
    
    // 性能数据检查
    add_action('shutdown', array($this, 'check_realtime_alerts'));
}

private function load_alert_rules() {
    $default_rules = array(
        'performance' => array(
            'enabled' => true,
            'threshold' => 3, // 秒
            'consecutive_failures' => 3,
            'notification_channels' => array('email', 'dashboard')
        ),
        'uptime' => array(
            'enabled' => true,
            'check_interval' => 300, // 5分钟
            'timeout' => 10,
            'notification_channels' => array('email', 'sms')
        ),
        'server' => array(
            'enabled' => true,
            'cpu_threshold' => 80, // 百分比
            'memory_threshold' => 85,
            'disk_threshold' => 90,
            'notification_channels' => array('email')
        ),
        'errors' => array(
            'enabled' => true,
            'php_errors' => true,
            'http_errors' => array(500, 502, 503, 504),
            'notification_channels' => array('email', 'dashboard')
        )
    );
    
    $saved_rules = get_option('wppm_alert_rules', array());
    $this->alert_rules = wp_parse_args($saved_rules, $default_rules);
}

public function check_realtime_alerts() {
    global $wppm_performance_data;
    
    if (empty($wppm_performance_data) || !isset($wppm_performance_data['shutdown'])) {
        return;
    }
    
    $total_time = $wppm_performance_data['shutdown']['time'];
    $threshold = $this->alert_rules['performance']['threshold'];
    
    if ($total_time > $threshold) {
        $this->trigger_alert('performance', array(
            'page_url' => home_url($_SERVER['REQUEST_URI']),
            'load_time' => $total_time,
            'threshold' => $threshold,
            'timestamp' => current_time('mysql')
        ));
    }
}

public function check_all_alerts() {
    $this->check_server_alerts();
    $this->check_uptime_alerts();
    $this->check_error_alerts();
    $this->check_scheduled_performance_alerts();
}

private function check_server_alerts() {
    if (!$this->alert_rules['server']['enabled']) {
        return;
    }
    
    $stats = WPPM_Server_Monitor::get_server_stats();
    
    // 检查CPU使用率
    if (isset($stats['cpu']['1min']) && $stats['cpu']['1min'] > $this->alert_rules['server']['cpu_threshold']) {
        $this->trigger_alert('server_cpu', array(
            'current_usage' => $stats['cpu']['1min'],
            'threshold' => $this->alert_rules['server']['cpu_threshold'],
            'timestamp' => $stats['timestamp']
        ));
    }
    
    // 检查内存使用率
    if (isset($stats['memory']['usage_percent']) && 
        $stats['memory']['usage_percent'] > $this->alert_rules['server']['memory_threshold']) {
        $this->trigger_alert('server_memory', array(
            'current_usage' => $stats['memory']['usage_percent'],
            'threshold' => $this->alert_rules['server']['memory_threshold'],
            'total_memory' => $stats['memory']['total_human'] ?? 'N/A',
            'timestamp' => $stats['timestamp']
        ));
    }
    
    // 检查磁盘使用率
    if (isset($stats['disk']['usage_percent']) && 
        $stats['disk']['usage_percent'] > $this->alert_rules['server']['disk_threshold']) {
        $this->trigger_alert('server_disk', array(
            'current_usage' => $stats['disk']['usage_percent'],
            'threshold' => $this->alert_rules['server']['disk_threshold'],
            'free_space' => $stats['disk']['free_human'] ?? 'N/A',
            'timestamp' => $stats['timestamp']
        ));
    }
}

private function check_uptime_alerts() {
    if (!$this->alert_rules['uptime']['enabled']) {
        return;
    }
    
    $site_url = home_url();
    $timeout = $this->alert_rules['uptime']['timeout'];
    
    // 使用wp_remote_get检查网站可访问性
    $response = wp_remote_get($site_url, array(
        'timeout' => $timeout,
        'sslverify' => false
    ));
    
    if (is_wp_error($response)) {
        $error_message = $response->get_error_message();
        $this->trigger_alert('uptime', array(
            'site_url' => $site_url,
            'error' => $error_message,
            'timestamp' => current_time('mysql')
        ));
        
        // 记录宕机时间
        $this->log_downtime($site_url, $error_message);
    } else {
        $response_code = wp_remote_retrieve_response_code($response);
        
        if ($response_code >= 400) {
            $this->trigger_alert('http_error', array(
                'site_url' => $site_url,
                'status_code' => $response_code,
                'timestamp' => current_time('mysql')
            ));
        }
    }
}

private function check_error_alerts() {
    if (!$this->alert_rules['errors']['enabled']) {
        return;
    }
    
    global $wpdb;
    
    // 检查最近的PHP错误
    if ($this->alert_rules['errors']['php_errors']) {
        $error_log_path = ini_get('error_log');
        
        if ($error_log_path && file_exists($error_log_path)) {
            $recent_errors = $this->get_recent_php_errors($error_log_path);
            
            if (!empty($recent_errors)) {
                $this->trigger_alert('php_errors', array(
                    'error_count' => count($recent_errors),
                    'recent_errors' => array_slice($recent_errors, 0, 5),
                    'timestamp' => current_time('mysql')
                ));
            }
        }
    }
}

private function check_scheduled_performance_alerts() {
    global $wpdb;
    
    $table_name = $wpdb->prefix . 'wppm_performance_logs';
    $threshold = $this->alert_rules['performance']['threshold'];
    $consecutive = $this->alert_rules['performance']['consecutive_failures'];
    
    // 检查过去一小时内的性能数据
    $one_hour_ago = date('Y-m-d H:i:s', strtotime('-1 hour'));
    
    $slow_pages = $wpdb->get_results($wpdb->prepare(
        "SELECT url, COUNT(*) as slow_count, AVG(total_time) as avg_time
        FROM $table_name 
        WHERE created_at > %s AND total_time > %f
        GROUP BY url
        HAVING slow_count >= %d",
        $one_hour_ago, $threshold, $consecutive
    ));
    
    foreach ($slow_pages as $page) {
        $this->trigger_alert('performance_trend', array(
            'page_url' => $page->url,
            'slow_count' => $page->slow_count,
            'average_time' => round($page->avg_time, 2),
            'threshold' => $threshold,
            'time_period' => '过去1小时',
            'timestamp' => current_time('mysql')
        ));
    }
}

private function trigger_alert($alert_type, $data) {
    // 检查是否已经发送过相同类型的告警(防止告警风暴)
    if ($this->is_alert_cooldown($alert_type, $data)) {
        return;
    }
    
    // 获取告警配置
    $alert_config = $this->get_alert_config($alert_type);
    
    if (!$alert_config || !$alert_config['enabled']) {
        return;
    }
    
    // 准备告警消息
    $message = $this->format_alert_message($alert_type, $data);
    $subject = $this->format_alert_subject($alert_type, $data);
    
    // 通过配置的渠道发送告警
    foreach ($alert_config['notification_channels'] as $channel) {
        switch ($channel) {
            case 'email':
                $this->send_email_alert($subject, $message, $alert_type);
                break;
            case 'dashboard':
                $this->add_dashboard_notification($subject, $message, $alert_type);
                break;
            case 'sms':
                $this->send_sms_alert($message, $alert_type);
                break;
            case 'webhook':
                $this->send_webhook_alert($alert_type, $data);
                break;
        }
    }
    
    // 记录告警
    $this->log_alert($alert_type, $data, $message);
    
    // 设置冷却时间
    $this->set_alert_cooldown($alert_type, $data);
}

private function format_alert_message($alert_type, $data) {
    $messages = array(
        'performance' => "网站性能告警nn页面加载时间超过阈值n页面: {page_url}n加载时间: {load_time}秒n阈值: {threshold}秒n时间: {timestamp}",
        'server_cpu' => "服务器CPU告警nnCPU使用率超过阈值n当前使用率: {current_usage}%n阈值: {threshold}%n时间: {timestamp}",
        'server_memory' => "服务器内存告警nn内存使用率超过阈值n当前使用率: {current_usage}%n总内存: {total_memory}n阈值: {threshold}%n时间: {timestamp}",
        'uptime' => "网站可用性告警nn网站无法访问n网址: {site_url}n错误: {error}n时间: {timestamp}",
        'php_errors' => "PHP错误告警nn检测到新的PHP错误n错误数量: {error_count}n时间: {timestamp}"
    );
    
    $template = $messages[$alert_type] ?? "系统告警nn类型: {$alert_type}n数据: " . json_encode($data, JSON_PRETTY_PRINT);
    
    // 替换模板变量
    foreach ($data as $key => $value) {
        if (is_array($value)) {
            $value = json_encode($value, JSON_PRETTY_PRINT);
        }
        $template = str_replace('{' . $key . '}', $value, $template);
    }
    
    return $template;
}

private function send_email_alert($subject, $message, $alert_type) {
    $admin_email = get_option('admin_email');
    $site_name = get_bloginfo('name');
    
    $headers = array('Content-Type: text/plain; charset=UTF-8');
    
    // 添加紧急标记
    if (in_array($alert_type, array('uptime', 'server_cpu', 'server_memory'))) {
        $subject = '[紧急] ' . $subject;
    }
    
    wp_mail($admin_email, $subject, $message, $headers);
}

private function log_alert($alert_type, $data, $message) {
    global $wpdb;
    
    $table_name = $wpdb->prefix . 'wppm_alert_logs';
    
    $wpdb->insert(
        $table_name,
        array(
            'alert_type' => $alert_type,
            'alert_data' => maybe_serialize($data),
            'message' => $message,
            'sent_via' => maybe_serialize($this->get_alert_config($alert_type)['notification_channels'] ?? array()),
            'created_at' => current_time('mysql')
        ),
        array('%s', '%s', '%s', '%s', '%s')
    );
}

}


### 3.2 告警冷却与防风暴机制

// 在WPPM_Alert_System类中添加以下方法
private function is_alert_cooldown($alert_type, $data) {

$cooldown_key = 'wppm_alert_cooldown_' . $alert_type . '_' . md5(json_encode($data));
$cooldown_time = get_transient($cooldown_key);

return $cooldown_time !== false;

}

private function set_alert_cooldown($alert_type, $data) {

$cooldown_key = 'wppm_alert_cooldown_' . $alert_type . '_' . md5(json_encode($data));

// 根据告警类型设置不同的冷却时间
$cooldown_periods = array(
    'performance' => HOUR_IN_SECONDS, // 1小时
    'server_cpu' => 30 * MINUTE_IN_SECONDS, // 30分钟
    'server_memory' => 30 * MINUTE_IN_SECONDS,
    'uptime' => 15 * MINUTE_IN_SECONDS, // 15分钟
    'php_errors' => 2 * HOUR_IN_SECONDS // 2小时
);

$cooldown = $cooldown_periods[$alert_type] ?? HOUR_IN_SECONDS;
set_transient($cooldown_key, time(), $cooldown);

}

private function get_alert_config($alert_type) {

$config_map = array(
    'performance' => $this->alert_rules['performance'],
    'performance_trend' => $this->alert_rules['performance'],
    'server_cpu' => $this->alert_rules['server'],
    'server_memory' => $this->alert_rules['server'],
    'server_d
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/5100.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

工作时间:周一至周五,9:00-17:30,节假日休息
返回顶部