日志记录和写入由`\think\Log`类完成,通常我们使用`think\facade\Log`类进行静态调用。
由于日志记录了所有的运行错误,因此养成经常查看日志文件的习惯,可以避免和及早发现很多的错误隐患。
> 日志遵循`PSR-3`规范,除非是实时写入的日志,其它日志都是在当前请求结束的时候统一写入的 所以不要在日志写入之后使用`exit`等中断操作会导致日志写入失败。
## 日志配置
日志的配置文件是配置文件目录下的`log.php`文件,系统在进行日志写入之前会读取该配置文件进行初始化。
新版的日志配置支持多通道,默认配置如下:
~~~
return [
// 默认日志记录通道
'default' => 'file',
// 日志记录级别
'level' => [],
// 日志类型记录的通道 ['error'=>'email',...]
'type_channel' => [],
// 日志通道列表
'channels' => [
'file' => [
// 日志记录方式
'type' => 'File',
// 日志保存目录
'path' => '',
// 单文件日志写入
'single' => false,
// 独立日志级别
'apart_level' => [],
// 最大日志文件数量
'max_files' => 0,
],
// 其它日志通道配置
],
];
~~~
可以添加多个日志通道,每个通道可以设置不同的日志类型。日志配置参数根据不同的日志类型有所区别,内置的日志类型包括:`file`,日志类型使用`type`参数配置即可。
> 如果是自定义驱动,`type`的值则为自定义驱动的类名(包含命名空间)
日志的全局配置参数包含:
| 参数 | 描述 |
| --- | --- |
| default | 默认的日志通道 |
| level | 允许记录的日志级别 |
| type\_channel | 日志类型记录的通道 |
> 默认的日志类型是`File`方式,可以通过驱动的方式来扩展支持更多的记录方式。
文件类型日志的话,还支持下列配置参数:
| 参数 | 描述 |
| --- | --- |
| path | 日志存储路径 |
| file\_size | 日志文件大小限制(超出会生成多个文件) |
| apart\_level | 独立记录的日志级别 |
| time\_format | 时间记录格式 |
| single | 是否单一文件日志 |
| max\_files | 最大日志文件数(超过自动清理 ) |
| format | 日志输出格式 |
| realtime\_write | 是否实时写入 |
> 为了避免同一个目录下面的日志文件过多的性能问题,日志文件会自动生成日期子目录。
## 日志写入
### 手动记录
一般情况下,系统的错误日志记录是自动的,如果需要记录应用的业务日志或者额外的日志信息,就需要手动记录日志信息,Log类主要提供了2个方法用于记录日志。
| 方法 | 描述 |
| --- | --- |
| record() | 记录日志信息到内存 |
| write() | 实时写入一条日志信息 |
系统在请求结束后会自动调用`Log::save`方法统一进行日志信息写入。
`record`方法用法如下:
~~~
Log::record('测试日志信息');
~~~
默认记录的日志级别是`info`,也可以指定日志级别:
~~~
Log::record('测试日志信息,这是警告级别','notice');
~~~
采用`record`方法记录的日志信息不是实时保存的,如果需要实时记录的话,可以采用`write`方法,例如:
~~~
Log::write('测试日志信息,这是警告级别,并且实时写入','notice');
~~~
你可以在日志通道配置开启实时写入,每次记录日志信息的时候就会实时写入。
~~~
'file' => [
// 日志记录方式
'type' => 'File',
// 日志保存目录
'path' => '',
// 单文件日志写入
'single' => false,
// 独立日志级别
'apart_level' => [],
// 最大日志文件数量
'max_files' => 0,
// 日志处理
'processor' => null,
// 实时写入
'realtime_write' => true,
],
~~~
> 为避免内存溢出,在命令行下面执行的话日志信息会自动实时写入。
### 关闭日志
要关闭日志功能,可以调用`Log::close()`方法关闭本次请求的日志写入。
~~~
// 关闭当前日志写入
Log::close();
~~~
### 日志级别
ThinkPHP对系统的日志按照级别来分类记录,按照`PSR-3`日志规范,日志的级别从低到高依次为:`debug`,`info`,`notice`,`warning`,`error`,`critical`,`alert`,`emergency`,ThinkPHP额外增加了一个`sql`日志级别仅用于记录`SQL`日志(并且仅当开启数据库调试模式有效)。
> 系统发生异常后记录的日志级别是`error`
系统提供了不同日志级别的快速记录方法,例如:
~~~
Log::error('错误信息');
Log::info('日志信息');
~~~
还封装了一个助手函数用于日志记录,例如:
~~~
trace('错误信息', 'error');
trace('日志信息', 'info');
~~~
事实上,你可以增加自定义的日志类型,例如:
~~~
Log::diy('这是一个自定义日志类型');
~~~
也支持指定级别日志的写入,需要配置信息:
~~~
return [
// 日志记录级别,使用数组表示
'level' => ['error', 'alert'],
];
~~~
上面的配置表示只记录`error`和`alert`级别的日志信息。
> 默认情况下是不会记录HTTP异常日志(避免受一些攻击的影响写入大量日志),除非你接管了系统的异常处理,重写了`report`方法。
### 上下文信息
日志可以传入上下文信息(数组),并且被替换到日志内容中,例如:
~~~
Log::info('日志信息{user}', ['user' => '流年']);
~~~
实际写入日志的时候,`{user}`会被替换为流年。
### 独立日志
为了便于分析,`File`类型的日志还支持设置某些级别的日志信息单独文件记录,例如:
~~~
return [
'default' => 'file',
'channels' => [
'file' => [
'type' => 'file',
// error和sql日志单独记录
'apart_level' => ['error','sql'],
],
],
];
~~~
设置后,就会单独生成`error`和`sql`两个类型的日志文件,主日志文件中将不再包含这两个级别的日志信息。
> 如果`apart_level`设置为`true`,则表示所有的日志类型都会独立记录。
### 单文件日志
默认情况下,日志是按照日期为目录,按天为文件生成的,但如果希望仅生成单个文件(方便其它的工具或者服务读取以及分析日志)。
~~~
return [
'default' => 'file',
'channels' => [
'file' => [
'type' => 'file',
'single' => true,
'file_size' => 1024*1024*10,
],
],
];
~~~
开启生成单个文件后,`file_size`和`apart_level`参数依然有效,超过文件大小限制后,系统会自动生成备份日志文件。
默认的单文件日志名是`single.log`,如果需要更改日志文件名,可以设置
~~~
return [
'default' => 'file',
'channels' => [
'file' => [
'type' => 'file',
'single' => 'single_file',
'file_size' => 1024*1024*10,
],
],
];
~~~
那么实际生成的日志文件名是`single_file.log`,如果设置了`apart_level`的话,可能还会生成`single_file_error.log`之类的日志。
> 单文件日志也支持`max_files`参数设置,因为单文件日志同样会生成多个日志备份文件而导致日志文件数据过大。
### 写入处理
日志支持写入回调处理,通过事件的方式处理。
~~~
Event::listen('think\event\LogWrite', function($event) {
if('file' == $event->channel) {
$event->log['info'][] = 'test info';
}
});
~~~
### 格式化日志信息
系统提供了两个参数用于日志信息的格式化,第一个是用于自定义时间显示格式的`time_format`,第二个是调整日志输出格式的`format`参数。
~~~
return [
'default' => 'file',
'channels' => [
'file' => [
'type' => 'file',
'json' => true
'file_size' => 1024*1024*10,
'time_format' => 'Y-m-d H:i:s',
'format' => '[%s][%s]:%s',
],
],
];
~~~
### 清空日志
一旦执行`save`方法后,内存中的日志信息就会被自动清空,如果需要手动清空可以使用:
~~~
Log::clear();
~~~
在清空日志方法之前,你可以使用`getLog`方法获取内存中的日志。
~~~
// 获取全部日志
$logs = Log::getLog();
~~~
> 日志清空仅仅是清空内存中的日志。
### 日志自动清理
文件类型的日志支持自动清理。可以设置`max_files`参数,超过数量的最早日志将会自动删除。
例如,下面设置日志最多保存数量为30个
~~~
return [
'default' => 'file',
'channels' => [
'file' => [
'type' => 'file',
'max_files' => 30,
'file_size' => 1024*1024*10,
],
],
];
~~~
> 设置`max_files`参数后,日志文件将不会分日期子目录存放。
### JSON格式日志
可以支持`JSON`格式记录文件日志,更加方便一些第三方日志分析工具进行日志分析。
在日志配置文件中,添加
~~~
return [
'default' => 'file',
'channels' => [
'file' => [
'type' => 'file',
'json' => true
'file_size' => 1024*1024*10,
],
],
];
~~~
即可开启`JSON`格式记录,CLI命令行的日志记录同样有效。
使用JSON格式记录后,每次请求是一行JSON数据,但如果使用`Log::write`记录的日志是例外的单独一行JSON数据。
## 日志通道
你可以配置不同的日志通道,并且把不同的日志记录到不同的通道。
~~~
Log::channel('email')->info('一条测试日志');
Log::channel('socket')->error('记录错误日志');
~~~
你可以配置不同的日志类型,记录到不同的日志通道,这样在记录日志的时候会自动选择对应的通道写入。
~~~
return [
'default' => 'file',
'type_channel' => [
'error' => 'email',
'sql' => 'sql',
],
'channels' => [
'file' => [
'type' => 'file',
],
'email' => [
'type' => 'email',
],
'sql' => [
'type' => 'sql',
],
],
];
~~~
表示如果是`error`日志和`sql`日志,会分别记录到指定的通道。同时你还需要在日志配置文件中,添加`email`和`sql`日志通道的配置。核心只有`file`日志类型,其它的可能需要自己扩展或者安装扩展。
如果需要获取内存中的通道日志信息,可以使用
~~~
// 获取某个日志通道的日志
$error = Log::getLog('file');
~~~
可以单独关闭某个通道的日志写入,只需要把日志通道的`close`配置参数设置为`true`,或者使用方法关闭。
~~~
Log::close('file');
~~~
可以单独清空某个通道的日志(如果没有开启实时写入的话)
~~~
Log::clear('file');
~~~
## 自定义驱动
如果需要自定义日志驱动,你需要实现`think\contract\LogHandlerInterface`接口。
~~~
interface LogHandlerInterface
{
/**
* 日志写入接口
* @access public
* @param array $log 日志信息
* @return bool
*/
public function save(array $log): bool;
}
~~~
- 空白目录
- php语法结构
- 安装与更新
- 开启调试模式及代码跟踪器
- 架构
- 源码分析
- 应用初始化
- 请求流程
- 中间件源码分析
- 请求处理源码分析
- Request源码分析
- 模板编译流程
- 路由与请求流程
- 容器
- 获取目录位置
- 入口文件
- 多应用模式及URL访问
- 依赖注入与容器
- 容器属性及方法
- Container
- App
- facade
- 中间件(middleware)
- 系统服务
- extend 扩展类库
- 笔记
- 配置
- env配置定义及获取
- 配置文件的配置获取
- 单应用模式-(配置)文件目录结构(默认)
- 多应用模式(配置)文件目录结构(配置文件)
- 配置文件
- 应用配置:app.php
- 缓存配置: cache.php
- 数据库配置:database.php
- 路由和URL配置:route.php
- Cookie配置:cookie.php
- Session配置:session.php
- 命令行配置:console.php
- 多语言配置:lang.php
- 日志配置:log.php
- 页面Trace配置:trace.php
- 磁盘配置: filesystem.php
- 中间件配置:middleware.php
- 视图配置:view.php
- 改成用yaconf配置
- 事件
- 例子:省略事件类的demo
- 例子2:完整事件类
- 例子3:事件订阅,监听多个事件
- 解析
- 路由
- 路由定义
- 路由地址
- 变量规则
- MISS路由
- URL生成
- 闭包支持
- 路由参数
- 路由中间件
- 路由分组
- 资源路由
- 注解路由
- 路由绑定
- 域名路由
- 路由缓存
- 跨域路由
- 控制器
- 控制器定义
- 空控制器、空操作
- 空模块处理
- RESTFul资源控制器
- 控制器中间件
- 请求对象Request(url参数)
- 请求信息
- 获取输入变量($_POST、$_GET等)
- 请求类型的获取与伪装
- HTTP头信息
- 伪静态
- 参数绑定
- 请求缓存
- 响应对象Response
- 响应输出
- 响应参数
- 重定向
- 文件下载
- 错误页面的处理办法
- 应用公共文件common.php
- 模型
- 模型定义及常规属性
- 模型数据获取与模型赋值
- 查询
- 数据集
- 增加
- 修改
- 删除
- 条件
- 查询范围scope
- 获取器
- 修改器
- 搜索器
- 软删除
- 模型事件
- 关联预载入
- 模型关联
- 一对一关联
- 一对多关联
- 多对多关联
- 自动时间戳
- 事务
- 数据库
- 查询构造器
- 查询合集
- 子查询
- 聚合查询
- 时间查询
- 视图查询(比join简单)
- 获取查询参数
- 快捷方法
- 动态查询
- 条件查询
- 打印sql语句
- 增
- 删
- 改
- 查
- 链式操作
- 查询表达式
- 分页查询
- 原生查询
- JSON字段
- 链接数据库配置
- 分布式数据库
- 查询事件
- Db获取器
- 事务操作
- 存储过程
- Db数据集
- 数据库驱动
- 视图
- 模板
- 模板配置
- 模板位置
- 模板渲染
- 模板变量与赋值(assign)
- 模板输出替换
- url生成
- 模板详解
- 内置标签
- 三元运算
- 变量输出
- 函数输出
- Request请求参数
- 模板注释及原样输出
- 模板继承
- 模板布局
- 原生PHP
- 模板引擎
- 视图过滤
- 视图驱动
- 验证
- 验证进阶之最终版
- 错误和日志
- 异常处理
- 日志处理
- 调试
- 调试模式
- Trace调试
- SQL调试
- 变量调试
- 远程调试
- 杂项
- 缓存
- Session
- Cookie
- 多语言
- 上传
- 扩展说明
- N+1查询
- TP类库
- 扩展类库
- 数据库迁移工具
- Workerman
- think助手工具库
- 验证码
- Swoole
- request
- app
- Response
- View
- Validate
- Config
- 命令行
- 助手函数
- 升级指导(功能的添加与删除说明)
- siyucms
- 开始
- 添加页面流程
- 列表页加载流程
- 弹出框
- 基础控制器
- 基础模型
- 快速构建
- 表单form构建
- 表格table构建
- MakeBuilder
- 前端组件
- 日期组件
- layer 弹层组件
- Moment.js 日期处理插件
- siyucms模板布局
- 函数即其变量
- 前端页面
- $.operate.方法
- $.modal.方法:弹出层
- $.common.方法:通用方法
- 被cms重写的表格options
- 自定义模板
- 搜索框
- 自定义form表单
- 获取表单搜索参数并组装为url字符串