本文目录导读:

为PHP项目设置错误监控是保障应用稳定性的关键步骤,以下是完整的实施指南,涵盖从基础配置到集成专业监控工具的全流程。
PHP 基础错误配置
php.ini 配置
; 开发环境 display_errors = On error_reporting = E_ALL ; 生产环境 display_errors = Off log_errors = On error_log = /var/log/php_errors.log error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
通过代码动态设置
// 生产环境安全配置
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', '/path/to/error.log');
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
自定义错误处理函数
基本实现
// 设置自定义错误处理器
set_error_handler(function($severity, $message, $file, $line) {
// 记录错误
error_log("Error [$severity]: $message in $file on line $line");
// 根据错误级别决定是否抛出异常
if (error_reporting() & $severity) {
throw new ErrorException($message, 0, $severity, $file, $line);
}
});
// 设置未捕获异常处理器
set_exception_handler(function($exception) {
$message = "Uncaught Exception: " . $exception->getMessage() .
" in " . $exception->getFile() . " on line " . $exception->getLine();
error_log($message);
// 生产环境显示友好错误页面
if (php_sapi_name() !== 'cli') {
http_response_code(500);
include('error_pages/500.php');
}
exit(1);
});
// 确保脚本结束前错误被记录
register_shutdown_function(function() {
$error = error_get_last();
if ($error !== null && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
error_log("Fatal Error: {$error['message']} in {$error['file']} on line {$error['line']}");
}
});
日志分类与管理
按级别分类记录
class AppLogger {
private $logDir;
public function __construct($logDir = '/var/log/app') {
$this->logDir = $logDir;
if (!is_dir($logDir)) {
mkdir($logDir, 0755, true);
}
}
public function error($message, array $context = []) {
$this->log('error', $message, $context);
}
public function warning($message, array $context = []) {
$this->log('warning', $message, $context);
}
public function info($message, array $context = []) {
$this->log('info', $message, $context);
}
public function critical($message, array $context = []) {
$this->log('critical', $message, $context);
// 发送紧急通知
$this->sendAlert($message, $context);
}
private function log($level, $message, array $context = []) {
$logFile = $this->logDir . '/' . $level . '_' . date('Y-m-d') . '.log';
$timestamp = date('Y-m-d H:i:s');
$contextStr = !empty($context) ? ' | ' . json_encode($context) : '';
$logEntry = "[$timestamp] [$level] $message $contextStr\n";
file_put_contents($logFile, $logEntry, FILE_APPEND | LOCK_EX);
}
private function sendAlert($message, $context) {
// 集成邮件、Slack、短信等通知
// ...
}
}
集成专业监控工具
使用 Sentry
安装:
composer require sentry/sentry
配置初始化:
<?php
// config/sentry.php
use Sentry\SentrySdk;
use Sentry\State\Hub;
use Sentry\ClientBuilder;
// 初始化 Sentry
SentrySdk::getCurrentHub()->bindClient(
ClientBuilder::create([
'dsn' => 'https://your-public-key@your-org.ingest.sentry.io/project-id',
'environment' => $_ENV['APP_ENV'] ?? 'production',
'release' => '1.0.0',
'error_types' => E_ALL & ~E_DEPRECATED & ~E_STRICT,
'before_send' => function (\Sentry\Event $event): ?\Sentry\Event {
// 过滤敏感信息
$event->setExtra('ip', $_SERVER['REMOTE_ADDR'] ?? 'unknown');
return $event;
},
])->getClient()
);
捕获错误:
// 捕获所有错误
\Sentry\configureScope(function (\Sentry\State\Scope $scope): void {
$scope->setUser([
'id' => $userId,
'email' => $userEmail,
]);
});
// 手动捕获异常
try {
// risky operation
} catch (\Exception $e) {
\Sentry\captureException($e);
}
// 捕获致命错误
register_shutdown_function(function () {
$error = error_get_last();
if ($error !== null) {
\Sentry\captureLastError();
}
});
使用 Airbrake
// 安装: composer require airbrake/phpbrake
$notifier = new \Airbrake\Notifier([
'projectId' => 12345,
'projectKey' => 'your-api-key',
'environment' => 'production'
]);
// 设置错误和异常处理器
$handler = new \Airbrake\ErrorHandler($notifier);
$handler->register();
使用日志聚合服务(ELK Stack)
// 发送日志到 Logstash
$context = [
'environment' => $_ENV['APP_ENV'],
'server' => gethostname(),
'request_id' => uniqid(),
];
openlog('myapp', LOG_PID | LOG_PERROR, LOG_LOCAL0);
syslog(LOG_ERR, "Database connection failed: " . $e->getMessage() . " " . json_encode($context));
closelog();
环境配置策略
配置文件分离
// config/error.php
class ErrorConfig {
public static function getConfig() {
$env = $_ENV['APP_ENV'] ?? 'production';
$configs = [
'development' => [
'display_errors' => true,
'error_reporting' => E_ALL,
'log_errors' => true,
'log_level' => 'debug'
],
'staging' => [
'display_errors' => false,
'error_reporting' => E_ALL & ~E_DEPRECATED,
'log_errors' => true,
'log_level' => 'info'
],
'production' => [
'display_errors' => false,
'error_reporting' => E_ALL & ~E_DEPRECATED & ~E_STRICT,
'log_errors' => true,
'log_level' => 'warning'
]
];
return $configs[$env] ?? $configs['production'];
}
}
// 应用配置
$config = ErrorConfig::getConfig();
ini_set('display_errors', $config['display_errors']);
error_reporting($config['error_reporting']);
框架集成示例
Laravel
// config/app.php 中的配置
'debug' => env('APP_DEBUG', false),
// app/Exceptions/Handler.php
public function register()
{
$this->reportable(function (Throwable $e) {
if (app()->bound('sentry')) {
app('sentry')->captureException($e);
}
});
$this->renderable(function (NotFoundHttpException $e, $request) {
if ($request->expectsJson()) {
return response()->json(['error' => 'Resource not found'], 404);
}
return response()->view('errors.404', [], 404);
});
}
Symfony
# config/packages/monolog.yaml
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: grouped
grouped:
type: group
members: [streamed, sentry]
streamed:
type: stream
path: '%kernel.logs_dir%/%kernel.environment%.log'
level: debug
sentry:
type: service
id: Sentry\Monolog\Handler
最佳实践总结
| 层次 | 措施 | 优先级 |
|---|---|---|
| 1️⃣ | 合理配置 php.ini 和错误报告级别 |
必须 |
| 2️⃣ | 实现自定义错误与异常处理器 | 强烈建议 |
| 3️⃣ | 使用结构化日志(JSON格式) | 推荐 |
| 4️⃣ | 集成专业监控工具(Sentry/ELK) | 按需 |
| 5️⃣ | 设置实时告警(邮件/Slack) | 生产环境必须 |
| 6️⃣ | 定期审查日志并优化 | 持续维护 |
关键注意事项:
- 生产环境绝不可开启
display_errors - 日志文件必须做日志轮转(
logrotate) - 敏感信息过滤(密码、token、信用卡号等)
- 错误信息要包含上下文(请求ID、用户ID、会话信息)
- 定期测试错误监控系统是否正常工作
通过实施上述方案,你可以有效监控PHP项目的错误,及时发现问题并快速响应。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播