文章目录[隐藏]
一步步教你,为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
