本文目录导读:

在ThinkPHP项目中集成监控与告警系统,可以从以下几个方面进行:
性能监控
集成SkyWalking
// config/skywalking.php
return [
'enabled' => env('SW_ENABLED', true),
'service_name' => env('SW_SERVICE_NAME', 'thinkphp-app'),
'server' => env('SW_SERVER', '127.0.0.1:11800'),
];
// app/middleware/SkyWalkingMiddleware.php
namespace app\middleware;
use Closure;
use think\Request;
class SkyWalkingMiddleware
{
public function handle(Request $request, Closure $next)
{
$startTime = microtime(true);
$response = $next($request);
// 记录请求耗时
$duration = microtime(true) - $startTime;
// 发送追踪数据到SkyWalking
$this->sendTrace($request, $response, $duration);
return $response;
}
private function sendTrace($request, $response, $duration)
{
// 集成SkyWalking SDK发送追踪数据
}
}
使用Prometheus
// config/prometheus.php
return [
'namespace' => 'thinkphp_app',
'metrics' => [
'http_requests_total',
'http_request_duration_seconds',
],
];
// app/common/Collector.php
namespace app\common;
use Prometheus\CollectorRegistry;
use Prometheus\RenderTextFormat;
class Collector
{
protected $registry;
public function __construct()
{
// 初始化Registry
$this->registry = new CollectorRegistry();
}
public function collect()
{
// 收集性能指标
$counter = $this->registry->getOrRegisterCounter(
'app', 'http_requests_total', 'Total requests', ['method', 'uri']
);
$counter->incBy(1, [request()->method(), request()->url()]);
}
}
日志监控
配置日志系统
// config/log.php
return [
'default' => env('log.channel', 'file'),
'channels' => [
'file' => [
'type' => 'File',
'path' => './runtime/log/',
'level' => ['error', 'info', 'notice', 'warning'],
],
'stdout' => [
'type' => 'stdout',
'level' => ['error'],
],
// 集成日志服务
'elasticsearch' => [
'type' => 'custom',
'class' => \app\log\ElasticsearchLogger::class,
'hosts' => ['http://elasticsearch:9200'],
'level' => ['error', 'warning'],
],
],
];
日志告警过滤器
// app/log/LogAlert.php
namespace app\log;
class LogAlert
{
public function process($level, $message, $context)
{
// 错误日志级别
if ($level == 'error' || $level == 'critical') {
$this->sendAlert($level, $message, $context);
}
// 特定错误码
if (isset($context['code']) && in_array($context['code'], [500, 502, 503])) {
$this->sendAlert('http_error', $message, $context);
}
return $message;
}
private function sendAlert($level, $message, $context)
{
// 发送告警通知
Notification::send($level, $message, $context);
}
}
异常监控
全局异常处理
// app/ExceptionHandle.php
namespace app;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\Handle;
use think\exception\HttpException;
use think\exception\HttpResponseException;
use think\exception\ValidateException;
use Throwable;
class ExceptionHandle extends Handle
{
protected $report = [
// 需要报告的异常
\think\exception\ErrorException::class,
\think\exception\DbException::class,
];
public function render($request, Throwable $e): Response
{
// 异常监控和告警
$this->monitorException($e);
return parent::render($request, $e);
}
protected function monitorException($e)
{
$data = [
'message' => $e->getMessage(),
'code' => $e->getCode(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTraceAsString(),
'request_uri' => request()->url(),
'request_method' => request()->method(),
];
// 记录到监控系统
Monitor::reportException($data);
// 发送告警
if ($e instanceof \ErrorException) {
Alert::error('系统错误', $data);
} elseif ($e instanceof \think\exception\DbException) {
Alert::critical('数据库异常', $data);
}
}
}
数据库监控
// app/listener/DbQueryListener.php
namespace app\listener;
use think\facade\Db;
use think\facade\Event;
class DbQueryListener
{
public function handle()
{
// 监听SQL执行
Event::listen('db_query', function ($sql, $time) {
// 慢查询监控
if ($time > 1000) { // 超过1秒
$this->reportSlowQuery($sql, $time);
}
// 记录查询日志
Monitor::recordDbQuery($sql, $time);
});
}
protected function reportSlowQuery($sql, $time)
{
Alert::warning('慢查询', [
'sql' => $sql,
'time' => $time,
'uri' => request()->url(),
]);
}
}
告警通知
通知服务接口
// app/service/AlertService.php
namespace app\service;
class AlertService
{
protected $channels = [
'email',
'slack',
'dingtalk',
'wechat',
'sms',
];
public function send($level, $title, $content, $options = [])
{
$channels = $options['channels'] ?? ['email', 'slack'];
foreach ($channels as $channel) {
// 根据级别决定是否发送
if (!$this->shouldSend($level, $channel)) {
continue;
}
// 发送通知
$this->{"sendTo" . ucfirst($channel)}($title, $content, $options);
}
}
protected function shouldSend($level, $channel)
{
// 配置规则:某些级别只通过特定渠道发送
$config = [
'error' => ['email', 'slack', 'dingtalk'],
'warning' => ['slack', 'dingtalk'],
'info' => ['dingtalk'],
];
return in_array($channel, $config[$level] ?? []);
}
}
钉钉告警示例
// app/service/DingtalkAlert.php
namespace app\service;
class DingtalkAlert
{
protected $webhook;
public function __construct()
{
$this->webhook = env('DINGTALK_WEBHOOK');
}
public function send($title, $content, $mentioned = [])
{
$data = [
'msgtype' => 'markdown',
'markdown' => [
'title' => $title,
'text' => $content,
],
'at' => [
'atMobiles' => $mentioned,
'isAtAll' => false,
],
];
$result = Http::post($this->webhook, $data);
return $result->successful();
}
}
集成管理平台
Grafana监控面板配置
// public/grafana/dashboard.json
{
"dashboard": {
"templating": {
"list": [
{
"name": "app",
"query": "label_values(app)",
"type": "query"
}
]
},
"panels": [
{
"title": "请求量",
"type": "graph",
"targets": [
{
"expr": "sum(rate(http_requests_total[5m])) by (app)",
"legendFormat": "{{app}}"
}
]
},
{
"title": "错误率",
"type": "graph",
"targets": [
{
"expr": "sum(rate(http_errors_total[5m])) / sum(rate(http_requests_total[5m]))",
"legendFormat": "错误率"
}
]
}
]
}
}
健康检查接口
// app/controller/HealthCheck.php
namespace app\controller;
use think\Response;
use think\facade\Cache;
use think\facade\Db;
class HealthCheck
{
public function index()
{
$checks = [
'database' => $this->checkDatabase(),
'cache' => $this->checkCache(),
'storage' => $this->checkStorage(),
'queue' => $this->checkQueue(),
];
$status = !in_array(false, $checks);
return json([
'status' => $status ? 'UP' : 'DOWN',
'checks' => $checks,
'timestamp' => time(),
]);
}
protected function checkDatabase()
{
try {
Db::query('SELECT 1');
return true;
} catch (\Exception $e) {
return false;
}
}
protected function checkCache()
{
try {
Cache::set('health_check', 'ok', 5);
return Cache::get('health_check') === 'ok';
} catch (\Exception $e) {
return false;
}
}
}
配置文件模板
// config/monitoring.php
return [
// 是否开启监控
'enabled' => env('MONITORING_ENABLED', true),
// 告警渠道配置
'alert' => [
'channels' => [
'email' => [
'enabled' => true,
'hosts' => ['admin@example.com'],
'level' => ['error', 'critical'],
],
'dingtalk' => [
'enabled' => true,
'webhook' => env('DINGTALK_WEBHOOK'),
'level' => ['error', 'warning'],
],
'slack' => [
'enabled' => false,
'webhook' => env('SLACK_WEBHOOK'),
],
],
],
// 性能阈值
'threshold' => [
'slow_query' => 1000, // 慢查询时间(ms)
'slow_request' => 3000, // 慢请求时间(ms)
'memory_limit' => 128 * 1024 * 1024, // 内存限制
],
// 监控指标
'metrics' => [
'enabled' => true,
'prefix' => 'thinkphp_app',
'collect' => [
'status_code',
'response_time',
'db_query',
'cache_hit',
],
],
];
启动脚本
#!/bin/bash
# bin/monitor.sh
# 启动监控服务
php think monitor:start &
# 检查健康状态
while true; do
if curl -f http://localhost/health; then
echo "$(date): System is healthy"
else
echo "$(date): System is unhealthy" | mail -s "Alert" admin@example.com
fi
sleep 60
done
最佳实践建议
- 分层监控:基础监控(CPU/内存)、应用监控(状态码/响应时间)、业务监控(订单量/用户量)
- 告警分级:Warning(注意)、Error(错误)、Critical(严重)
- 告警去重:避免重复告警,设置合理的告警间隔
- 日志分级:保留不同粒度的日志,便于问题定位
- 自动化恢复:配置自动重启、故障转移等策略
通过以上方案,可以构建一个完整的ThinkPHP监控告警体系,确保项目的稳定运行。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播