文章目录[隐藏]
手把手教程:在WordPress中集成网站第三方API状态监控与异常报警面板
引言:为什么WordPress需要API状态监控功能
在当今数字化时代,网站已经不再是简单的信息展示平台,而是集成了各种第三方服务和API的复杂生态系统。无论是支付网关、社交媒体集成、地图服务、数据分析工具还是云存储服务,现代网站通常依赖多个外部API来提供完整功能。然而,这些第三方服务偶尔会出现故障或响应缓慢,直接影响网站性能和用户体验。
传统的解决方案是使用独立的监控服务,但这些服务往往需要额外订阅费用,且与WordPress后台分离,增加了管理复杂度。本教程将向您展示如何通过WordPress代码二次开发,创建一个集成的API状态监控与异常报警面板,让您在一个熟悉的界面中监控所有关键服务的健康状况。
通过本教程,您将学习到如何利用WordPress的灵活性,扩展其功能,实现一个专业级的监控系统,而无需依赖外部高价服务。这个解决方案不仅成本效益高,而且完全可控,可以根据您的具体需求进行定制。
第一部分:准备工作与环境配置
1.1 确定监控目标与需求
在开始编码之前,我们需要明确监控系统的目标。您应该列出所有需要监控的第三方API,例如:
- 支付网关(PayPal、Stripe等)
- 社交媒体API(Facebook、Twitter、Instagram等)
- 地图服务(Google Maps、Mapbox等)
- 邮件服务(SMTP、SendGrid、MailChimp等)
- 云存储(AWS S3、Google Cloud Storage等)
- CDN服务(Cloudflare、Akamai等)
对于每个API,确定以下监控参数:
- 检查频率(每5分钟、每15分钟等)
- 超时阈值
- 响应状态码要求
- 响应内容验证规则
- 性能基准(响应时间)
1.2 开发环境设置
为了安全地进行开发,建议在本地或测试服务器上设置WordPress开发环境:
- 安装本地服务器环境:使用XAMPP、MAMP或Local by Flywheel
- 设置WordPress测试站点:安装最新版本的WordPress
-
启用调试模式:在wp-config.php中添加以下代码:
define('WP_DEBUG', true); define('WP_DEBUG_LOG', true); define('WP_DEBUG_DISPLAY', false); - 安装代码编辑器:推荐VS Code、PHPStorm或Sublime Text
- 创建子主题或插件目录:我们将创建一个独立插件来实现功能
1.3 创建基础插件结构
在wp-content/plugins目录下创建新文件夹api-status-monitor,并创建以下文件结构:
api-status-monitor/
├── api-status-monitor.php # 主插件文件
├── includes/
│ ├── class-api-monitor.php # 核心监控类
│ ├── class-alert-system.php # 报警系统类
│ └── class-dashboard-widget.php # 仪表板小工具
├── admin/
│ ├── css/
│ │ └── admin-style.css # 管理界面样式
│ ├── js/
│ │ └── admin-script.js # 管理界面脚本
│ └── partials/
│ └── settings-page.php # 设置页面模板
├── assets/
│ ├── css/
│ │ └── frontend-style.css # 前端样式(可选)
│ └── js/
│ └── frontend-script.js # 前端脚本(可选)
└── uninstall.php # 插件卸载清理脚本
第二部分:构建核心监控系统
2.1 创建主插件文件
编辑api-status-monitor.php,添加插件基本信息:
<?php
/**
* Plugin Name: API状态监控与异常报警面板
* Plugin URI: https://yourwebsite.com/
* Description: 在WordPress中集成第三方API状态监控与异常报警功能
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
* Text Domain: api-status-monitor
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('ASM_VERSION', '1.0.0');
define('ASM_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('ASM_PLUGIN_URL', plugin_dir_url(__FILE__));
// 包含必要文件
require_once ASM_PLUGIN_DIR . 'includes/class-api-monitor.php';
require_once ASM_PLUGIN_DIR . 'includes/class-alert-system.php';
require_once ASM_PLUGIN_DIR . 'includes/class-dashboard-widget.php';
// 初始化插件
function asm_init() {
// 检查WordPress版本
if (version_compare(get_bloginfo('version'), '5.0', '<')) {
add_action('admin_notices', function() {
echo '<div class="notice notice-error"><p>';
echo __('API状态监控插件需要WordPress 5.0或更高版本。', 'api-status-monitor');
echo '</p></div>';
});
return;
}
// 初始化核心类
$api_monitor = new API_Monitor();
$alert_system = new Alert_System();
$dashboard_widget = new Dashboard_Widget();
// 注册激活/停用钩子
register_activation_hook(__FILE__, array($api_monitor, 'activate'));
register_deactivation_hook(__FILE__, array($api_monitor, 'deactivate'));
// 初始化
add_action('init', array($api_monitor, 'init'));
add_action('admin_menu', array($api_monitor, 'add_admin_menu'));
}
add_action('plugins_loaded', 'asm_init');
2.2 实现API监控核心类
创建includes/class-api-monitor.php文件:
<?php
class API_Monitor {
private $monitored_apis;
private $check_interval;
private $options_name = 'asm_settings';
public function __construct() {
$this->check_interval = 300; // 默认5分钟
$this->monitored_apis = array();
}
public function init() {
// 加载文本域
load_plugin_textdomain('api-status-monitor', false, dirname(plugin_basename(__FILE__)) . '/languages');
// 注册设置
add_action('admin_init', array($this, 'register_settings'));
// 安排定时任务
$this->schedule_cron_jobs();
// 加载监控的API列表
$this->load_monitored_apis();
// 添加AJAX处理
add_action('wp_ajax_asm_test_api', array($this, 'ajax_test_api'));
add_action('wp_ajax_asm_get_status', array($this, 'ajax_get_status'));
}
public function activate() {
// 创建数据库表
$this->create_tables();
// 设置默认选项
$default_options = array(
'check_interval' => 300,
'enable_email_alerts' => true,
'enable_sms_alerts' => false,
'alert_email' => get_option('admin_email'),
'history_days' => 30
);
if (!get_option($this->options_name)) {
add_option($this->options_name, $default_options);
}
// 安排初始监控任务
wp_schedule_event(time(), 'asm_five_minutes', 'asm_check_all_apis');
}
public function deactivate() {
// 清除定时任务
wp_clear_scheduled_hook('asm_check_all_apis');
// 清理选项(可选)
// delete_option($this->options_name);
}
private function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_name = $wpdb->prefix . 'asm_api_status';
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
api_name varchar(100) NOT NULL,
endpoint varchar(255) NOT NULL,
status_code smallint(3) NOT NULL,
response_time float NOT NULL,
status varchar(20) NOT NULL,
checked_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
response_message text,
PRIMARY KEY (id),
KEY api_name (api_name),
KEY checked_at (checked_at)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
// 创建报警日志表
$alert_table = $wpdb->prefix . 'asm_alerts';
$alert_sql = "CREATE TABLE IF NOT EXISTS $alert_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
api_name varchar(100) NOT NULL,
alert_type varchar(50) NOT NULL,
alert_message text NOT NULL,
alert_level varchar(20) NOT NULL,
sent_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
resolved_at datetime,
PRIMARY KEY (id),
KEY api_name (api_name),
KEY alert_level (alert_level),
KEY sent_at (sent_at)
) $charset_collate;";
dbDelta($alert_sql);
}
private function schedule_cron_jobs() {
// 添加自定义cron间隔
add_filter('cron_schedules', array($this, 'add_cron_intervals'));
// 添加监控任务
add_action('asm_check_all_apis', array($this, 'check_all_apis'));
}
public function add_cron_intervals($schedules) {
$schedules['asm_five_minutes'] = array(
'interval' => 300,
'display' => __('每5分钟', 'api-status-monitor')
);
$schedules['asm_fifteen_minutes'] = array(
'interval' => 900,
'display' => __('每15分钟', 'api-status-monitor')
);
$schedules['asm_thirty_minutes'] = array(
'interval' => 1800,
'display' => __('每30分钟', 'api-status-monitor')
);
return $schedules;
}
private function load_monitored_apis() {
// 从数据库或选项加载API列表
$default_apis = array(
array(
'name' => 'Stripe支付网关',
'endpoint' => 'https://api.stripe.com/v1/',
'method' => 'GET',
'expected_status' => 200,
'check_interval' => 300,
'timeout' => 10,
'headers' => array(),
'body' => '',
'validation' => 'json',
'active' => true
),
array(
'name' => 'Google Maps API',
'endpoint' => 'https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA',
'method' => 'GET',
'expected_status' => 200,
'check_interval' => 900,
'timeout' => 15,
'headers' => array(),
'body' => '',
'validation' => 'json_contains',
'validation_value' => 'OK',
'active' => true
),
// 添加更多API配置
);
$saved_apis = get_option('asm_monitored_apis', array());
if (empty($saved_apis)) {
$this->monitored_apis = $default_apis;
update_option('asm_monitored_apis', $default_apis);
} else {
$this->monitored_apis = $saved_apis;
}
}
public function check_all_apis() {
foreach ($this->monitored_apis as $api) {
if ($api['active']) {
$this->check_single_api($api);
}
}
}
private function check_single_api($api_config) {
$start_time = microtime(true);
$args = array(
'method' => $api_config['method'],
'timeout' => $api_config['timeout'],
'headers' => $api_config['headers']
);
if (!empty($api_config['body'])) {
$args['body'] = $api_config['body'];
}
$response = wp_remote_request($api_config['endpoint'], $args);
$response_time = round((microtime(true) - $start_time) * 1000, 2); // 毫秒
$status_code = wp_remote_retrieve_response_code($response);
$response_body = wp_remote_retrieve_body($response);
// 验证响应
$status = 'unknown';
$message = '';
if (is_wp_error($response)) {
$status = 'error';
$message = $response->get_error_message();
} elseif ($status_code == $api_config['expected_status']) {
// 进一步验证响应内容
if ($this->validate_response($api_config, $response_body)) {
$status = 'healthy';
$message = __('API响应正常', 'api-status-monitor');
} else {
$status = 'warning';
$message = __('API响应异常', 'api-status-monitor');
}
} else {
$status = 'error';
$message = sprintf(__('HTTP状态码异常: %d', 'api-status-monitor'), $status_code);
}
// 保存结果到数据库
$this->save_api_status($api_config['name'], $api_config['endpoint'],
$status_code, $response_time, $status, $message);
// 触发报警检查
if ($status != 'healthy') {
do_action('asm_api_status_changed', $api_config['name'], $status, $message);
}
return array(
'status' => $status,
'response_time' => $response_time,
'status_code' => $status_code,
'message' => $message
);
}
private function validate_response($api_config, $response_body) {
if (empty($api_config['validation'])) {
return true;
}
switch ($api_config['validation']) {
case 'json':
json_decode($response_body);
return json_last_error() === JSON_ERROR_NONE;
case 'json_contains':
$data = json_decode($response_body, true);
if (json_last_error() !== JSON_ERROR_NONE) {
return false;
}
// 检查响应中是否包含特定值
$needle = $api_config['validation_value'];
$haystack = json_encode($data);
return strpos($haystack, $needle) !== false;
case 'regex':
return preg_match($api_config['validation_pattern'], $response_body) === 1;
default:
return true;
}
}
private function save_api_status($api_name, $endpoint, $status_code, $response_time, $status, $message) {
global $wpdb;
$table_name = $wpdb->prefix . 'asm_api_status';
$wpdb->insert(
$table_name,
array(
'api_name' => $api_name,
'endpoint' => $endpoint,
'status_code' => $status_code,
'response_time' => $response_time,
'status' => $status,
'response_message' => $message
),
array('%s', '%s', '%d', '%f', '%s', '%s')
);
// 清理旧记录(保留最近30天)
$history_days = get_option($this->options_name)['history_days'] ?? 30;
$cutoff_date = date('Y-m-d H:i:s', strtotime("-{$history_days} days"));
$wpdb->query(
$wpdb->prepare(
"DELETE FROM $table_name WHERE checked_at < %s",
$cutoff_date
)
);
}
// 更多方法将在后续部分添加...
}
第三部分:实现报警系统
3.1 创建报警系统类
创建includes/class-alert-system.php文件:
<?php
class Alert_System {
private $alert_methods;
public function __construct() {
$this->alert_methods = array();
// 初始化报警方法
$this->init_alert_methods();
}
public function init() {
// 监听API状态变化事件
add_action('asm_api_status_changed', array($this, 'handle_status_change'), 10, 3);
// 注册报警方法
add_action('asm_send_email_alert', array($this, 'send_email_alert'), 10, 3);
add_action('asm_send_sms_alert', array($this, 'send_sms_alert'), 10, 3);
add_action('asm_send_slack_alert', array($this, 'send_slack_alert'), 10, 3);
// 添加报警设置页面
add_action('admin_menu', array($this, 'add_alert_settings_page'));
}
private function init_alert_methods() {
$settings = get_option('asm_settings', array());
$this->alert_methods = array(
'email' => array(
'enabled' => $settings['enable_email_alerts'] ?? true,
'recipients' => isset($settings['alert_email']) ?
explode(',', $settings['alert_email']) :
array(get_option('admin_email'))
),
'sms' => array(
'enabled' => $settings['enable_sms_alerts'] ?? false,
'provider' => $settings['sms_provider'] ?? '',
'api_key' => $settings['sms_api_key'] ?? '',
'phone_numbers' => isset($settings['sms_numbers']) ?
explode(',', $settings['sms_numbers']) :
),
'slack' => array(
'enabled' => $settings['enable_slack_alerts'] ?? false,
'webhook_url' => $settings['slack_webhook'] ?? '',
'channel' => $settings['slack_channel'] ?? '#alerts'
)
);
}
public function handle_status_change($api_name, $status, $message) {
// 检查是否需要发送报警(避免重复报警)
if ($this->should_send_alert($api_name, $status)) {
$alert_data = array(
'api_name' => $api_name,
'status' => $status,
'message' => $message,
'timestamp' => current_time('mysql'),
'site_url' => get_site_url()
);
// 根据状态确定报警级别
$alert_level = $this->determine_alert_level($status);
// 记录报警
$this->log_alert($api_name, 'status_change', $message, $alert_level);
// 发送报警
$this->dispatch_alerts($alert_data, $alert_level);
}
}
private function should_send_alert($api_name, $status) {
global $wpdb;
$table_name = $wpdb->prefix . 'asm_alerts';
// 检查最近是否已发送相同报警
$recent_alerts = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM $table_name
WHERE api_name = %s
AND alert_type = 'status_change'
AND alert_level = %s
AND sent_at > DATE_SUB(NOW(), INTERVAL 1 HOUR)
AND resolved_at IS NULL",
$api_name,
$this->determine_alert_level($status)
));
return $recent_alerts == 0;
}
private function determine_alert_level($status) {
switch ($status) {
case 'error':
return 'critical';
case 'warning':
return 'warning';
case 'unknown':
return 'info';
default:
return 'info';
}
}
private function log_alert($api_name, $alert_type, $message, $alert_level) {
global $wpdb;
$table_name = $wpdb->prefix . 'asm_alerts';
$wpdb->insert(
$table_name,
array(
'api_name' => $api_name,
'alert_type' => $alert_type,
'alert_message' => $message,
'alert_level' => $alert_level
),
array('%s', '%s', '%s', '%s')
);
}
private function dispatch_alerts($alert_data, $alert_level) {
$settings = get_option('asm_settings', array());
// 发送邮件报警
if ($this->alert_methods['email']['enabled']) {
do_action('asm_send_email_alert', $alert_data, $alert_level, $this->alert_methods['email']);
}
// 发送短信报警
if ($this->alert_methods['sms']['enabled'] && $alert_level == 'critical') {
do_action('asm_send_sms_alert', $alert_data, $alert_level, $this->alert_methods['sms']);
}
// 发送Slack报警
if ($this->alert_methods['slack']['enabled']) {
do_action('asm_send_slack_alert', $alert_data, $alert_level, $this->alert_methods['slack']);
}
}
public function send_email_alert($alert_data, $alert_level, $email_config) {
$subject = sprintf(
'[%s] API监控报警: %s - %s',
get_bloginfo('name'),
$alert_data['api_name'],
strtoupper($alert_level)
);
$message = $this->build_alert_message($alert_data, $alert_level);
$headers = array('Content-Type: text/html; charset=UTF-8');
foreach ($email_config['recipients'] as $recipient) {
wp_mail(trim($recipient), $subject, $message, $headers);
}
}
public function send_sms_alert($alert_data, $alert_level, $sms_config) {
// 这里实现短信发送逻辑
// 可以使用Twilio、阿里云、腾讯云等短信服务
$message = sprintf(
"API报警: %s状态异常(%s)。详情请查看%s",
$alert_data['api_name'],
$alert_level,
get_site_url()
);
// 示例:使用Twilio发送短信
if ($sms_config['provider'] === 'twilio') {
$this->send_twilio_sms($sms_config, $message);
}
// 可以添加更多短信服务商
}
public function send_slack_alert($alert_data, $alert_level, $slack_config) {
$message = array(
'text' => sprintf("*API监控报警* :warning:n*服务*: %sn*状态*: %sn*详情*: %sn*时间*: %s",
$alert_data['api_name'],
$alert_level,
$alert_data['message'],
$alert_data['timestamp']
),
'channel' => $slack_config['channel'],
'username' => 'API监控机器人',
'icon_emoji' => ':robot_face:'
);
if ($alert_level === 'critical') {
$message['attachments'] = array(array(
'color' => 'danger',
'fields' => array(
array(
'title' => '紧急程度',
'value' => '需要立即处理',
'short' => true
)
)
));
}
wp_remote_post($slack_config['webhook_url'], array(
'body' => json_encode($message),
'headers' => array('Content-Type' => 'application/json')
));
}
private function build_alert_message($alert_data, $alert_level) {
$color = $alert_level === 'critical' ? '#dc3545' :
($alert_level === 'warning' ? '#ffc107' : '#17a2b8');
ob_start();
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.header { background-color: <?php echo $color; ?>; color: white; padding: 15px; border-radius: 5px 5px 0 0; }
.content { background-color: #f8f9fa; padding: 20px; border-radius: 0 0 5px 5px; }
.alert-level { display: inline-block; padding: 3px 10px; border-radius: 3px; background-color: <?php echo $color; ?>; color: white; font-weight: bold; }
.details { margin-top: 20px; }
.button { display: inline-block; padding: 10px 20px; background-color: <?php echo $color; ?>; color: white; text-decoration: none; border-radius: 4px; }
.footer { margin-top: 30px; padding-top: 20px; border-top: 1px solid #dee2e6; color: #6c757d; font-size: 12px; }
</style>
</head>
<body>
<div class="container">
<div class="header">
<h2>API监控系统报警通知</h2>
</div>
<div class="content">
<p><strong>报警级别:</strong> <span class="alert-level"><?php echo strtoupper($alert_level); ?></span></p>
<p><strong>API服务:</strong> <?php echo esc_html($alert_data['api_name']); ?></p>
<p><strong>状态:</strong> <?php echo esc_html($alert_data['status']); ?></p>
<p><strong>详细信息:</strong> <?php echo esc_html($alert_data['message']); ?></p>
<p><strong>发生时间:</strong> <?php echo $alert_data['timestamp']; ?></p>
<div class="details">
<p>请及时处理此问题,避免影响网站正常功能。</p>
<a href="<?php echo admin_url('admin.php?page=api-status-monitor'); ?>" class="button">查看详细报告</a>
</div>
<div class="footer">
<p>此邮件由 <?php echo get_bloginfo('name'); ?> API监控系统自动发送</p>
<p>如需修改报警设置,请访问: <?php echo admin_url('admin.php?page=api-status-monitor-settings'); ?></p>
</div>
</div>
</div>
</body>
</html>
<?php
return ob_get_clean();
}
public function add_alert_settings_page() {
add_submenu_page(
'api-status-monitor',
'报警设置',
'报警设置',
'manage_options',
'api-status-monitor-alerts',
array($this, 'render_alert_settings_page')
);
}
public function render_alert_settings_page() {
include ASM_PLUGIN_DIR . 'admin/partials/alert-settings-page.php';
}
}
第四部分:创建仪表板小工具
4.1 创建仪表板小工具类
创建includes/class-dashboard-widget.php文件:
<?php
class Dashboard_Widget {
public function __construct() {
// 初始化方法
}
public function init() {
// 添加仪表板小工具
add_action('wp_dashboard_setup', array($this, 'add_dashboard_widget'));
// 添加AJAX处理
add_action('wp_ajax_asm_refresh_status', array($this, 'ajax_refresh_status'));
// 添加前端样式和脚本
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_assets'));
}
public function add_dashboard_widget() {
wp_add_dashboard_widget(
'asm_api_status_widget',
'API状态监控',
array($this, 'render_dashboard_widget'),
null,
null,
'normal',
'high'
);
}
public function render_dashboard_widget() {
global $wpdb;
$table_name = $wpdb->prefix . 'asm_api_status';
// 获取最近一次检查结果
$recent_status = $wpdb->get_results(
"SELECT t1.* FROM $table_name t1
INNER JOIN (
SELECT api_name, MAX(checked_at) as latest
FROM $table_name
GROUP BY api_name
) t2 ON t1.api_name = t2.api_name AND t1.checked_at = t2.latest
ORDER BY
CASE WHEN t1.status = 'error' THEN 1
WHEN t1.status = 'warning' THEN 2
WHEN t1.status = 'unknown' THEN 3
ELSE 4 END,
t1.api_name",
ARRAY_A
);
// 获取24小时内的统计数据
$stats = $wpdb->get_row(
$wpdb->prepare(
"SELECT
COUNT(DISTINCT api_name) as total_apis,
SUM(CASE WHEN status = 'healthy' THEN 1 ELSE 0 END) as healthy_count,
SUM(CASE WHEN status = 'error' THEN 1 ELSE 0 END) as error_count,
SUM(CASE WHEN status = 'warning' THEN 1 ELSE 0 END) as warning_count,
AVG(response_time) as avg_response_time
FROM $table_name
WHERE checked_at > DATE_SUB(NOW(), INTERVAL 24 HOUR)",
array()
),
ARRAY_A
);
include ASM_PLUGIN_DIR . 'admin/partials/dashboard-widget.php';
}
public function ajax_refresh_status() {
// 验证nonce
check_ajax_referer('asm_refresh_nonce', 'nonce');
// 验证权限
if (!current_user_can('manage_options')) {
wp_die('权限不足');
}
// 执行一次API检查
$api_monitor = new API_Monitor();
$api_monitor->check_all_apis();
// 返回更新后的状态
$this->render_dashboard_widget();
wp_die();
}
public function enqueue_admin_assets($hook) {
if ('index.php' !== $hook) {
return;
}
wp_enqueue_style(
'asm-dashboard-style',
ASM_PLUGIN_URL . 'admin/css/admin-style.css',
array(),
ASM_VERSION
);
wp_enqueue_script(
'asm-dashboard-script',
ASM_PLUGIN_URL . 'admin/js/admin-script.js',
array('jquery'),
ASM_VERSION,
true
);
wp_localize_script('asm-dashboard-script', 'asm_ajax', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('asm_refresh_nonce')
));
}
}
4.2 创建仪表板小工具模板
创建admin/partials/dashboard-widget.php:
<div class="asm-dashboard-widget">
<div class="asm-stats-summary">
<div class="asm-stat-card">
<span class="asm-stat-label">监控API总数</span>
<span class="asm-stat-value"><?php echo $stats['total_apis'] ?? 0; ?></span>
</div>
<div class="asm-stat-card asm-stat-healthy">
<span class="asm-stat-label">正常</span>
<span class="asm-stat-value"><?php echo $stats['healthy_count'] ?? 0; ?></span>
</div>
<div class="asm-stat-card asm-stat-warning">
<span class="asm-stat-label">警告</span>
<span class="asm-stat-value"><?php echo $stats['warning_count'] ?? 0; ?></span>
</div>
<div class="asm-stat-card asm-stat-error">
<span class="asm-stat-label">异常</span>
<span class="asm-stat-value"><?php echo $stats['error_count'] ?? 0; ?></span>
</div>
<div class="asm-stat-card">
<span class="asm-stat-label">平均响应时间</span>
<span class="asm-stat-value"><?php echo round($stats['avg_response_time'] ?? 0, 2); ?>ms</span>
</div>
</div>
<div class="asm-controls">
<button id="asm-refresh-status" class="button button-primary">
<span class="dashicons dashicons-update"></span> 立即检查
</button>
<a href="<?php echo admin_url('admin.php?page=api-status-monitor'); ?>" class="button">
<span class="dashicons dashicons-dashboard"></span> 详细报告
</a>
<a href="<?php echo admin_url('admin.php?page=api-status-monitor-settings'); ?>" class="button">
<span class="dashicons dashicons-admin-settings"></span> 设置
</a>
</div>
<div class="asm-status-list">
<h3>API状态概览</h3>
<table class="widefat fixed" cellspacing="0">
<thead>
<tr>
<th>API名称</th>
<th>状态</th>
<th>响应时间</th>
<th>最后检查</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<?php if (empty($recent_status)): ?>
<tr>
<td colspan="5" style="text-align: center;">暂无监控数据</td>
</tr>
<?php else: ?>
<?php foreach ($recent_status as $status): ?>
<tr class="asm-status-row asm-status-<?php echo esc_attr($status['status']); ?>">
<td><?php echo esc_html($status['api_name']); ?></td>
<td>
<span class="asm-status-badge asm-badge-<?php echo esc_attr($status['status']); ?>">
<?php
$status_labels = array(
'healthy' => '正常',
'warning' => '警告',
'error' => '异常',
'unknown' => '未知'
);
echo $status_labels[$status['status']] ?? $status['status'];
?>
</span>
</td>
<td><?php echo esc_html($status['response_time']); ?>ms</td>
<td><?php echo human_time_diff(strtotime($status['checked_at']), current_time('timestamp')) . '前'; ?></td>
<td>
<button class="button button-small asm-test-api" data-api="<?php echo esc_attr($status['api_name']); ?>">
测试
</button>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
<div class="asm-recent-alerts">
<h3>最近报警</h3>
<?php
global $wpdb;
$alert_table = $wpdb->prefix . 'asm_alerts';
$recent_alerts = $wpdb->get_results(
"SELECT * FROM $alert_table
WHERE resolved_at IS NULL
ORDER BY sent_at DESC
LIMIT 5",
ARRAY_A
);
