本文目录导读:

我来为您提供一个完整的PHP监控报警系统示例,包含多种监控场景:
基础系统监控类
<?php
/**
* 系统资源监控类
*/
class SystemMonitor {
private $thresholds;
private $alertChannel;
public function __construct($thresholds = [], $alertChannel = null) {
$this->thresholds = array_merge([
'cpu_usage' => 80, // CPU使用率阈值
'memory_usage' => 80, // 内存使用率阈值
'disk_usage' => 85, // 磁盘使用率阈值
'load_average' => 10 // 负载均衡阈值
], $thresholds);
$this->alertChannel = $alertChannel ?? new AlertChannel();
}
/**
* 检查CPU使用率
*/
public function checkCpuUsage() {
$cpuUsage = $this->getCpuUsage();
$threshold = $this->thresholds['cpu_usage'];
if ($cpuUsage > $threshold) {
$this->alertChannel->send("CPU使用率过高: {$cpuUsage}%", 'critical');
}
return [
'metric' => 'cpu',
'value' => $cpuUsage,
'threshold' => $threshold,
'status' => $cpuUsage > $threshold ? 'ALERT' : 'OK'
];
}
/**
* 获取CPU使用率
*/
private function getCpuUsage() {
$load = sys_getloadavg();
if (function_exists('proc_open')) {
$cmd = "top -b -n1 | grep 'Cpu(s)' | awk '{print $2}'";
$result = exec($cmd);
return floatval($result);
}
return $load[0] * 100;
}
/**
* 检查内存使用率
*/
public function checkMemoryUsage() {
$memInfo = file('/proc/meminfo');
$totalMem = 0;
$freeMem = 0;
foreach ($memInfo as $line) {
if (strpos($line, 'MemTotal:') === 0) {
$parts = explode(':', $line);
$totalMem = (int)trim(str_replace('kB', '', $parts[1]));
} elseif (strpos($line, 'MemAvailable:') === 0) {
$parts = explode(':', $line);
$freeMem = (int)trim(str_replace('kB', '', $parts[1]));
}
}
if ($totalMem > 0) {
$usagePercent = (($totalMem - $freeMem) / $totalMem) * 100;
$threshold = $this->thresholds['memory_usage'];
if ($usagePercent > $threshold) {
$this->alertChannel->send("内存使用率过高: " . round($usagePercent, 2) . "%", 'warning');
}
return [
'metric' => 'memory',
'value' => round($usagePercent, 2),
'threshold' => $threshold,
'status' => $usagePercent > $threshold ? 'ALERT' : 'OK'
];
}
return null;
}
/**
* 检查磁盘使用率
*/
public function checkDiskUsage() {
$diskPath = '/';
$diskFree = disk_free_space($diskPath);
$diskTotal = disk_total_space($diskPath);
if ($diskTotal > 0) {
$usagePercent = (($diskTotal - $diskFree) / $diskTotal) * 100;
$threshold = $this->thresholds['disk_usage'];
if ($usagePercent > $threshold) {
$this->alertChannel->send("磁盘空间不足: " . round($usagePercent, 2) . "%", 'critical');
}
return [
'metric' => 'disk',
'value' => round($usagePercent, 2),
'threshold' => $threshold,
'status' => $usagePercent > $threshold ? 'ALERT' : 'OK'
];
}
return null;
}
/**
* 检查负载均衡
*/
public function checkLoadAverage() {
$load = sys_getloadavg();
if ($load[0] > $this->thresholds['load_average']) {
$this->alertChannel->send("系统负载过高: {$load[0]}", 'warning');
}
return [
'metric' => 'load_average',
'value' => $load[0],
'threshold' => $this->thresholds['load_average'],
'status' => $load[0] > $this->thresholds['load_average'] ? 'ALERT' : 'OK'
];
}
}
Web服务监控类
<?php
/**
* Web服务监控类
*/
class WebMonitor {
private $sites = [];
private $alertChannel;
public function __construct($sites = [], $alertChannel = null) {
$this->sites = $sites;
$this->alertChannel = $alertChannel ?? new AlertChannel();
}
/**
* 检查网站可用性
*/
public function checkWebsite($url) {
$startTime = microtime(true);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => true,
CURLOPT_NOBODY => true,
CURLOPT_TIMEOUT => 10,
CURLOPT_CONNECTTIMEOUT => 5
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$responseTime = microtime(true) - $startTime;
curl_close($ch);
// 检查HTTP状态码
if ($httpCode >= 400) {
$this->alertChannel->send("网站 {$url} 返回错误状态码: {$httpCode}", 'critical');
}
// 检查响应时间
if ($responseTime > 3.0) {
$this->alertChannel->send("网站 {$url} 响应过慢: " . round($responseTime, 2) . "s", 'warning');
}
return [
'url' => $url,
'http_code' => $httpCode,
'response_time' => round($responseTime, 2),
'status' => $httpCode >= 400 ? 'ALERT' : ($responseTime > 3.0 ? 'WARNING' : 'OK')
];
}
/**
* 监控API接口
*/
public function checkApi($url, $method = 'GET', $data = null) {
$ch = curl_init($url);
$headers = [
'Content-Type: application/json',
'Accept: application/json'
];
$options = [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_TIMEOUT => 10,
CURLOPT_CUSTOMREQUEST => $method
];
if ($data && in_array($method, ['POST', 'PUT', 'PATCH'])) {
$options[CURLOPT_POSTFIELDS] = json_encode($data);
}
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// 解析JSON响应
$responseData = json_decode($response, true);
// 检查是否包含错误信息
if (isset($responseData['error']) || isset($responseData['code']) && $responseData['code'] > 0) {
$this->alertChannel->send("API {$url} 返回错误: " . json_encode($responseData), 'critical');
}
return [
'url' => $url,
'http_code' => $httpCode,
'response' => $responseData,
'status' => $httpCode >= 400 ? 'ALERT' : 'OK'
];
}
/**
* 监控网页内容变化
*/
public function checkContent($url, $expectedContent) {
$content = file_get_contents($url);
if (strpos($content, $expectedContent) === false) {
$this->alertChannel->send("网站 {$url} 内容异常,未找到预期内容", 'warning');
return ['status' => 'ALERT', 'message' => 'Content mismatch'];
}
return ['status' => 'OK', 'message' => 'Content OK'];
}
}
数据库监控类
<?php
/**
* 数据库监控类
*/
class DatabaseMonitor {
private $pdo;
private $alertChannel;
public function __construct($config, $alertChannel = null) {
try {
$dsn = "mysql:host={$config['host']};dbname={$config['dbname']};charset=utf8mb4";
$this->pdo = new PDO($dsn, $config['user'], $config['password'], [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_TIMEOUT => 3
]);
$this->alertChannel = $alertChannel ?? new AlertChannel();
} catch (Exception $e) {
$this->alertChannel->send("数据库连接失败: " . $e->getMessage(), 'critical');
}
}
/**
* 检查数据库连接
*/
public function checkConnection() {
try {
$this->pdo->query('SELECT 1');
return ['status' => 'OK', 'message' => 'Connection successful'];
} catch (Exception $e) {
$this->alertChannel->send("数据库连接失败: " . $e->getMessage(), 'critical');
return ['status' => 'ALERT', 'error' => $e->getMessage()];
}
}
/**
* 检查表空间使用率
*/
public function checkTableSpace($tableName) {
$sql = "SELECT DATA_LENGTH + INDEX_LENGTH as table_size
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = :table";
$stmt = $this->pdo->prepare($sql);
$stmt->execute(['table' => $tableName]);
$size = $stmt->fetchColumn();
return [
'table' => $tableName,
'size_mb' => round($size / 1024 / 1024, 2),
'status' => 'OK'
];
}
/**
* 检查慢查询
*/
public function checkSlowQueries($threshold = 2.0) {
$sql = "SHOW FULL PROCESSLIST";
$queries = $this->pdo->query($sql)->fetchAll();
$slowQueries = array_filter($queries, function($query) use ($threshold) {
return $query['Time'] > $threshold && !empty($query['Info']);
});
if (count($slowQueries) > 0) {
foreach ($slowQueries as $query) {
$this->alertChannel->send(
"慢查询检测到: SQL='{$query['Info']}' 耗时={$query['Time']}s",
'warning'
);
}
}
return [
'total_queries' => count($queries),
'slow_queries' => count($slowQueries),
'status' => count($slowQueries) > 0 ? 'ALERT' : 'OK'
];
}
/**
* 监控连接池使用率
*/
public function checkConnections() {
$maxConnections = 100;
$sql = "SHOW STATUS WHERE Variable_name = 'Threads_connected'";
$current = $this->pdo->query($sql)->fetchColumn();
$usagePercent = ($current / $maxConnections) * 100;
if ($usagePercent > 80) {
$this->alertChannel->send("数据库连接数过高: {$current}/{$maxConnections}", 'warning');
}
return [
'current_connections' => $current,
'max_connections' => $maxConnections,
'usage_percent' => round($usagePercent, 2),
'status' => $usagePercent > 80 ? 'ALERT' : 'OK'
];
}
}
应用日志监控
<?php
/**
* 日志监控类
*/
class LogMonitor {
private $logFile;
private $alertChannel;
private $tailCount = 100;
public function __construct($logFile = '/var/log/php_errors.log', $alertChannel = null) {
$this->logFile = $logFile;
$this->alertChannel = $alertChannel ?? new AlertChannel();
}
/**
* 监控错误日志
*/
public function checkErrorLog($keywords = ['ERROR', 'FATAL', 'CRITICAL']) {
if (!file_exists($this->logFile)) {
return ['status' => 'OK', 'message' => 'Log file not found'];
}
$lines = $this->tailFile($this->tailCount);
$matches = [];
foreach ($lines as $line) {
foreach ($keywords as $keyword) {
if (stripos($line, $keyword) !== false) {
$matches[] = $line;
break;
}
}
}
if (count($matches) > 0) {
$this->alertChannel->send(
"日志中发现错误: " . count($matches) . "条\n" . implode("\n", array_slice($matches, 0, 5)),
'critical'
);
}
return [
'total_lines' => count($lines),
'error_lines' => count($matches),
'status' => count($matches) > 0 ? 'ALERT' : 'OK'
];
}
/**
* 读取文件末尾内容
*/
private function tailFile($lines) {
$file = new SplFileObject($this->logFile);
$file->seek(PHP_INT_MAX);
$totalLines = $file->key();
$startLine = max(0, $totalLines - $lines);
$file->seek($startLine);
$result = [];
while (!$file->eof()) {
$result[] = $file->fgets();
}
return $result;
}
}
报警通知渠道
<?php
/**
* 报警通知渠道
*/
class AlertChannel {
private $webhook;
private $emailConfig;
public function __construct() {
// 可以配置多个通知渠道
$this->webhook = 'https://example.com/webhook'; // Slack/DingTalk/企业微信
$this->emailConfig = [
'host' => 'smtp.example.com',
'port' => 465,
'username' => 'alert@example.com',
'password' => 'your_password',
'to' => 'admin@example.com'
];
}
/**
* 发送报警通知
*/
public function send($message, $level = 'warning') {
// 1. 发送到Webhook
$this->sendToWebhook($message, $level);
// 2. 发送邮件
$this->sendEmail($message, $level);
// 3. 发送短信(可选)
// $this->sendSMS($message, $level);
// 4. 记录到数据库
$this->logToDatabase($message, $level);
}
/**
* 发送Webhook通知
*/
private function sendToWebhook($message, $level) {
$data = [
'message' => $message,
'level' => $level,
'timestamp' => date('Y-m-d H:i:s'),
'host' => gethostname()
];
$ch = curl_init($this->webhook);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => ['Content-Type: application/json']
]);
curl_exec($ch);
curl_close($ch);
}
/**
* 发送邮件通知
*/
private function sendEmail($message, $level) {
// 使用PHP内置mail函数或其他邮件库
// 这里使用简单的示例
$subject = "[服务器报警] {$level} - " . date('Y-m-d H:i');
// mail($this->emailConfig['to'], $subject, $message);
}
/**
* 记录到数据库
*/
private function logToDatabase($message, $level) {
// 使用PDO连接数据库并记录报警信息
// 这里简化处理
$logEntry = [
'timestamp' => date('Y-m-d H:i:s'),
'level' => $level,
'message' => $message,
'host' => gethostname()
];
// 可以写入数据库或文件
$logFile = '/var/log/monitor_alerts.log';
file_put_contents($logFile, json_encode($logEntry) . "\n", FILE_APPEND);
}
}
主监控程序
<?php
/**
* 主监控调度器
*/
class MonitorScheduler {
private $monitors = [];
private $alerts = [];
private $runInterval = 60; // 运行间隔(秒)
public function __construct() {
$this->initializeMonitors();
}
/**
* 初始化所有监控任务
*/
private function initializeMonitors() {
// 系统监控
$this->monitors['system'] = new SystemMonitor([
'cpu_usage' => 80,
'memory_usage' => 80,
'disk_usage' => 85
]);
// Web监控
$this->monitors['web'] = new WebMonitor([
['url' => 'https://example.com', 'name' => '主站'],
['url' => 'https://api.example.com', 'name' => 'API服务']
]);
// 数据库监控
$this->monitors['database'] = new DatabaseMonitor([
'host' => 'localhost',
'dbname' => 'monitor_db',
'user' => 'monitor',
'password' => 'monitor_password'
]);
// 日志监控
$this->monitors['logs'] = new LogMonitor('/var/log/app.log');
}
/**
* 运行监控任务
*/
public function run() {
while (true) {
echo "\n=========== 开始监控 " . date('Y-m-d H:i:s') . " ===========\n";
// 执行所有监控
$results = [];
$results['system_cpu'] = $this->monitors['system']->checkCpuUsage();
$results['system_memory'] = $this->monitors['system']->checkMemoryUsage();
$results['system_disk'] = $this->monitors['system']->checkDiskUsage();
$results['system_load'] = $this->monitors['system']->checkLoadAverage();
// 打印结果
$this->printResults($results);
// 等待下一次运行
echo "\n等待 {$this->runInterval} 秒后继续监控...\n";
sleep($this->runInterval);
}
}
/**
* 打印监控结果
*/
private function printResults($results) {
foreach ($results as $name => $result) {
if ($result && isset($result['status'])) {
$status = $result['status'];
$color = $status === 'OK' ? "\033[32m" : ($status === 'ALERT' ? "\033[31m" : "\033[33m");
$reset = "\033[0m";
echo "{$color}[{$status}]{$reset} {$name}: ";
if (isset($result['value'])) {
echo "value = " . $result['value'];
}
echo "\n";
}
}
}
/**
* 单次运行(用于cron定时任务)
*/
public function runOnce() {
$this->initializeMonitors();
// 执行所有监控
$this->monitors['system']->checkCpuUsage();
$this->monitors['system']->checkMemoryUsage();
$this->monitors['system']->checkDiskUsage();
$this->monitors['system']->checkLoadAverage();
// Web监控
foreach ($this->monitors['web']->getSites() as $site) {
$this->monitors['web']->checkWebsite($site['url']);
}
// 数据库监控
$this->monitors['database']->checkConnection();
$this->monitors['database']->checkSlowQueries(2);
// 日志监控
$this->monitors['logs']->checkErrorLog();
}
}
使用示例
<?php // 启动监控程序 require_once 'monitor.php'; // 创建调度器并启动 $scheduler = new MonitorScheduler(); // 方式1:连续运行(适合开发和测试) // $scheduler->run(); // 方式2:单次运行(配合cron定时任务) // 在crontab中添加:*/5 * * * * php /path/to/monitor.php $scheduler->runOnce();
配置文件
<?php
// config.php
return [
'system' => [
'cpu_threshold' => 80,
'memory_threshold' => 80,
'disk_threshold' => 85
],
'websites' => [
['url' => 'https://example.com', 'name' => '主页'],
['url' => 'https://api.example.com', 'name' => 'API']
],
'database' => [
'host' => 'localhost',
'dbname' => 'monitor',
'user' => 'monitor_user',
'password' => 'monitor_password'
],
'alert' => [
'webhook' => 'https://hooks.slack.com/services/xxx',
'email' => 'admin@example.com',
'levels' => ['warning', 'critical']
]
];
这个监控系统包含:
- 系统监控:CPU、内存、磁盘、负载
- Web监控:网站可用性、响应时间、API状态
- 数据库监控:连接状态、慢查询、表空间
- 日志监控:错误日志检测
- 多通道报警:Webhook、邮件、短信等
- 定时调度:支持连续运行和cron定时方式
您可以根据实际需求进行调整和扩展。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播