本文目录导读:

在PHP项目中实现日志记录,通常有以下几种主流方案,从简单到专业:
使用 PHP 原生函数(最简单)
<?php
// 写入系统日志
error_log("用户登录失败:用户名不存在", 0);
// 写入自定义文件
error_log("错误信息", 3, "/var/log/myapp.log");
?>
优点:零依赖,开箱即用 缺点:功能单一,不支持分级、格式化
自定义日志函数(小项目)
<?php
class Logger {
private static $logFile;
public static function init($file = 'app.log') {
self::$logFile = __DIR__ . '/logs/' . $file;
if (!file_exists(dirname(self::$logFile))) {
mkdir(dirname(self::$logFile), 0755, true);
}
}
public static function write($level, $message, $context = []) {
$timestamp = date('Y-m-d H:i:s');
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
$caller = $trace[1] ?? null;
$file = $caller['file'] ?? 'unknown';
$line = $caller['line'] ?? 0;
$contextStr = !empty($context) ? ' ' . json_encode($context) : '';
$logMessage = "[{$timestamp}] [{$level}] [{$file}:{$line}] {$message}{$contextStr}" . PHP_EOL;
error_log($logMessage, 3, self::$logFile);
}
public static function info($message, $context = []) {
self::write('INFO', $message, $context);
}
public static function error($message, $context = []) {
self::write('ERROR', $message, $context);
}
public static function debug($message, $context = []) {
if (defined('APP_DEBUG') && APP_DEBUG) {
self::write('DEBUG', $message, $context);
}
}
}
// 使用
Logger::init('app.log');
Logger::info('用户登录成功', ['user_id' => 123, 'ip' => '192.168.1.1']);
Logger::error('数据库连接失败', ['db' => 'main', 'error' => 'timeout']);
?>
使用 Monolog 库(推荐方案)
Monolog 是 PHP 最流行的日志库,几乎所有现代框架都在使用。
安装
composer require monolog/monolog
基本使用
<?php
require 'vendor/autoload.php';
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Formatter\LineFormatter;
use Monolog\Processor\IntrospectionProcessor;
use Monolog\Processor\WebProcessor;
// 创建日志频道
$log = new Logger('app');
// 1. 简单文件日志
$log->pushHandler(new StreamHandler(__DIR__.'/logs/app.log', Logger::DEBUG));
// 2. 按天轮转(推荐)
$handler = new RotatingFileHandler(__DIR__.'/logs/app.log', 30, Logger::DEBUG);
$log->pushHandler($handler);
// 3. 自定义格式
$dateFormat = "Y-m-d H:i:s";
$output = "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n";
$formatter = new LineFormatter($output, $dateFormat);
$handler->setFormatter($formatter);
// 4. 添加上下文信息
$log->pushProcessor(new IntrospectionProcessor());
$log->pushProcessor(new WebProcessor());
// 使用
$log->info('用户登录', ['user_id' => 123]);
$log->error('数据库错误', ['exception' => $e->getMessage()]);
?>
进阶配置 - 多通道日志
<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SlackWebhookHandler;
use Monolog\Handler\SwiftMailerHandler;
// 创建多通道日志
$logger = new Logger('production');
// INFO 及以上记录到文件
$logger->pushHandler(new StreamHandler(
__DIR__.'/logs/info.log',
Logger::INFO
));
// ERROR 及以上发送到 Slack
$logger->pushHandler(new SlackWebhookHandler(
'https://hooks.slack.com/services/xxx',
'#php-errors',
'PHP Bot',
true, // use attachment
'danger',// icon emoji
true, // use short attachment
false, // include context
Logger::ERROR
));
// CRITICAL 发送邮件
$logger->pushHandler(new SwiftMailerHandler(
$mailer,
$message,
Logger::CRITICAL
));
// 使用
$logger->error('支付失败', ['order_id' => 12345]);
$logger->critical('服务器磁盘已满', ['disk_usage' => '99%']);
?>
使用框架内置日志
Laravel
// config/logging.php 配置
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['daily', 'slack'],
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => 'info',
'days' => 14,
],
],
// 使用
use Illuminate\Support\Facades\Log;
Log::info('用户登录', ['user_id' => $id]);
Log::error('数据库查询失败', ['sql' => $query, 'error' => $e->getMessage()]);
ThinkPHP
// config/log.php 配置
return [
'default' => 'file',
'channels' => [
'file' => [
'type' => 'file',
'path' => app()->getRuntimePath() . 'logs',
'level' => ['info', 'error', 'warning'],
'single' => false,
'file_size' => 2097152, // 2M
'max_files' => 30,
],
],
];
// 使用
use think\facade\Log;
Log::info('用户登录', ['user_id' => $id]);
Log::error('数据库查询失败', ['sql' => $query]);
最佳实践建议
日志级别规范
DEBUG: 调试信息(开发环境) INFO: 一般信息(用户操作) NOTICE: 正常但重要的事件 WARNING: 警告(潜在问题) ERROR: 错误(不影响系统运行) CRITICAL:严重错误(影响系统运行) ALERT: 需要立即处理 EMERGENCY:系统不可用
规范
// 好的日志
$log->info('用户登录成功', [
'user_id' => 123,
'ip' => '192.168.1.1',
'user_agent' => 'Chrome/120.0',
'duration' => 0.15
]);
// 避免这种
$log->info('登录成功'); // 缺少有用信息
环境配置
// 根据环境设置不同级别
if (getenv('APP_ENV') === 'production') {
$handler->setLevel(Logger::WARNING); // 生产只记录警告及以上
} else {
$handler->setLevel(Logger::DEBUG); // 开发环境记录所有
}
安全注意事项
- 不要记录敏感信息:密码、身份证、信用卡号等
- 日志文件权限:设置为 644,避免直接访问
- 日志目录隔离:放在 web 根目录之外
- 定期清理:设置日志保留天数
推荐方案
对于大多数 PHP 项目,推荐:
- 小项目:自定义 Logger 类 + 文件日志
- 中大型项目:Monolog + 文件 + 错误监控
- 框架项目:使用框架提供的日志功能
选择方案时考虑项目规模、维护成本、是否需要远程告警等因素。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播