本文目录导读:

在ThinkPHP项目中,日志按级别分类是一个非常实用的功能,以下是几种实现方法:
使用ThinkPHP内置的日志级别
ThinkPHP 6/8 默认支持以下日志级别:
emergency(紧急)alert(警报)critical(严重)error(错误)warning(警告)notice(提示)info(信息)debug(调试)sql(SQL查询)
配置日志按级别分类
修改配置文件
在 config/log.php 中配置:
<?php
return [
// 默认日志记录通道
'default' => 'file',
// 日志级别
'level' => [],
// 日志类型分类
'type_channel' => [
// 将不同级别的日志写到不同文件
'error' => 'error_log',
'info' => 'info_log',
'sql' => 'sql_log',
'debug' => 'debug_log',
],
// 日志通道列表
'channels' => [
'file' => [
'type' => 'File',
'path' => '',
'single' => false,
// 按日期和级别生成文件
'file_name' => 'Y-m-d',
'max_files' => 30,
'json' => false,
// 按级别分目录
'level_dir' => true,
'format' => '[%s][%s] %s',
'time_format' => 'Y-m-d H:i:s',
],
// 错误日志通道
'error_log' => [
'type' => 'File',
'path' => app()->getRuntimePath() . 'log/error/',
'level' => ['error', 'emergency', 'critical', 'alert'],
],
// 信息日志通道
'info_log' => [
'type' => 'File',
'path' => app()->getRuntimePath() . 'log/info/',
'level' => ['info', 'notice'],
],
// 调试日志通道
'debug_log' => [
'type' => 'File',
'path' => app()->getRuntimePath() . 'log/debug/',
'level' => ['debug'],
],
// SQL日志通道
'sql_log' => [
'type' => 'File',
'path' => app()->getRuntimePath() . 'log/sql/',
'level' => ['sql'],
],
],
];
使用日志通道动态选择
<?php
namespace app\common\service;
use think\facade\Log;
class LogService
{
/**
* 记录错误日志
*/
public function error($message, array $context = [])
{
Log::channel('error_log')->error($message, $context);
}
/**
* 记录信息日志
*/
public function info($message, array $context = [])
{
Log::channel('info_log')->info($message, $context);
}
/**
* 记录调试日志
*/
public function debug($message, array $context = [])
{
Log::channel('debug_log')->debug($message, $context);
}
/**
* 记录SQL日志
*/
public function sql($message, array $context = [])
{
Log::channel('sql_log')->sql($message, $context);
}
}
使用自定义日志驱动
创建自定义日志驱动类:
<?php
namespace app\common\log;
use think\contract\LogHandlerInterface;
class LevelFileLog implements LogHandlerInterface
{
protected $config = [
'path' => '',
'level' => [],
'format' => '[%s][%s] %s',
];
public function __construct(array $config = [])
{
$this->config = array_merge($this->config, $config);
}
/**
* 日志写入接口
*/
public function write(array $record): void
{
// 获取日志级别
$level = $record['level'] ?? 'info';
// 根据级别生成不同的目录
$path = $this->config['path'] . $level . '/';
// 确保目录存在
if (!is_dir($path)) {
mkdir($path, 0755, true);
}
// 生成文件名(按日期)
$filename = date('Y-m-d') . '.log';
$file = $path . $filename;
// 格式化日志内容
$content = sprintf(
$this->config['format'],
date('Y-m-d H:i:s'),
strtoupper($level),
$record['message'] . PHP_EOL
);
// 写入文件
file_put_contents($file, $content, FILE_APPEND | LOCK_EX);
}
}
然后在配置中使用:
'channels' => [
'custom_level' => [
'type' => 'app\common\log\LevelFileLog',
'path' => app()->getRuntimePath() . 'log/', // 日志按级别自动分目录
],
],
在中间件中自动分类日志
<?php
namespace app\middleware;
use think\facade\Log;
class LogMiddleware
{
public function handle($request, \Closure $next)
{
// 请求前记录
Log::info('Request: ' . $request->method() . ' ' . $request->url());
$response = $next($request);
// 请求后记录(根据状态码判断级别)
$statusCode = $response->getCode();
if ($statusCode >= 500) {
Log::error('Response Error: ' . $statusCode);
} elseif ($statusCode >= 400) {
Log::warning('Response Warning: ' . $statusCode);
} else {
Log::info('Response Success: ' . $statusCode);
}
return $response;
}
}
日志级别过滤
在控制器中动态调整日志级别:
<?php
namespace app\controller;
use think\facade\Log;
class Index
{
public function index()
{
// 设置当前请求的日志级别
Log::setLevel(['error', 'info']);
// 记录日志
Log::debug('This will not be logged'); // 不会记录
Log::info('This will be logged'); // 会记录
Log::error('Error message'); // 会记录
return 'success';
}
}
生产环境配置建议
对于生产环境,建议:
// config/log.php
return [
'default' => 'file',
// 生产环境只记录重要日志
'level' => [
'error',
'emergency',
'critical',
'alert',
'warning',
],
'channels' => [
'file' => [
'type' => 'File',
'path' => app()->getRuntimePath() . 'log/',
'single' => false,
'level' => ['error', 'warning', 'emergency', 'critical'],
'max_files' => 30,
'json' => false,
],
],
];
目录结构效果
配置完成后,日志文件会按照以下结构存储:
runtime/
├── log/
│ ├── error/
│ │ ├── 2024-01-15.log
│ │ └── 2024-01-14.log
│ ├── info/
│ │ ├── 2024-01-15.log
│ │ └── 2024-01-14.log
│ ├── sql/
│ │ ├── 2024-01-15.log
│ │ └── 2024-01-14.log
│ └── debug/
│ ├── 2024-01-15.log
│ └── 2024-01-14.log
这样配置后,不同级别的日志会自动分类存储,便于排查问题和监控系统状态。