一、介绍
日志记录由\think\Log类完成,主要完成日志记录和跟踪调试。由于日志记录了所有的运行错误,因此养成经常查看日志文件的习惯,可以避免和及早发现很多的错误隐患。
日志初始化
在使用日志记录之前,首先需要初始化日志类,指定当前使用的日志记录方式。
Log::init([
'type' => 'File',
'path' => APP_PATH.'logs/'
]);
上面在日志初始化的时候,指定了文件方式记录日志,并且日志保存目录为APP_PATH.‘logs/’。
如果你没有执行日志初始化操作的话,默认会自动调用配置参数log来进行初始化。
不同的日志类型可能会使用不同的初始化参数。
如果应用需要扩展自己的日志驱动,可以使用:
Log::init([
'type' => '\org\Log\File',
'path' => APP_PATH.'logs/'
]);
二、日志驱动
日志驱动
日志可以通过驱动支持不同的方式写入,默认日志会记录到文件中,系统已经内置的写入驱动包括 File、Socket,如果要临时关闭日志写入,可以设置日志类型为Test即可,例如:
'log' => [
// 可以临时关闭日志写入
'type' => 'test',
],
File驱动
日志的记录方式默认是File方式,可以通过驱动的方式来扩展支持更多的记录方式。
记录方式由log.type参数配置,例如:
'log' => [
// 日志记录方式,支持 file socket
'type' => 'File',
//日志保存目录
'path' => LOG_PATH,
//单个日志文件的大小限制,超过后会自动记录到第二个文件
'file_size' =>2097152,
//日志的时间格式,默认是` c `
'time_format' =>'c'
],
为了避免同一个目录下面的日志文件过多的性能问题,file方式记录的日志文件会自动生成日期子目录。
Scoket驱动
需要在配置文件中设置如下:
'log' => [
'type' => 'socket',
'host' => 'slog.thinkphp.cn',
//日志强制记录到配置的client_id
'force_client_ids' => [],
//限制允许读取日志的client_id
'allow_client_ids' => [],
]
上面的host配置地址是官方提供的公用服务端,首先需要去申请client_id 。
使用Chrome浏览器运行后,打开审查元素->Console,可以看到如下所示:
SocketLog通过websocket将调试日志打印到浏览器的console中。你还可以用它来分析开源程序,分析SQL性能,结合taint分析程序漏洞。
安装Chrome插件
SocketLog首先需要安装chrome插件,Chrome插件安装页面 (需翻墙)
使用方法
- 首先,请在chrome浏览器上安装好插件。
- 安装服务端npm install -g socketlog-server , 运行命令 socketlog-server 即可启动服务。 将会在本地起一个websocket服务 ,监听端口是1229 。
- 如果想服务后台运行: socketlog-server > /dev/null &参数
- client_id: 在chrome浏览器中,可以设置插件的Client_ID ,Client_ID是你任意指定的字符串。
- 设置client_id后能实现以下功能:
- 1,配置allow_client_ids 配置项,让指定的浏览器才能获得日志,这样就可以把调试代码带上线。 普通用户访问不会触发调试,不会发送日志。 开发人员访问就能看的调试日志, 这样利于找线上bug。 Client_ID 建议设置为姓名拼音加上随机字符串,这样如果有员工离职可以将其对应的client_id从配置项allow_client_ids中移除。 client_id除了姓名拼音,加上随机字符串的目的,以防别人根据你公司员工姓名猜测出client_id,获取线上的调试日志。
- 设置allow_client_ids示例代码:
'allow_client_ids'=>['thinkphp_zfH5NbLn','luofei_DJq0z80H'],
- 2, 设置force_client_ids配置项,让后台脚本也能输出日志到chrome。 网站有可能用了队列,一些业务逻辑通过后台脚本处理, 如果后台脚本需要调试,你也可以将日志打印到浏览器的console中, 当然后台脚本不和浏览器接触,不知道当前触发程序的是哪个浏览器,所以我们需要强制将日志打印到指定client_id的浏览器上面。 我们在后台脚本中使用SocketLog时设置force_client_ids 配置项指定要强制输出浏览器的client_id 即可。
关闭日志
系统并未提供关闭日志的方法,但有两种方式可以关闭日志的写入,第一种方式是设置日志类型为test,即可不写入任何日志。第二种方式是后面会提到的设置日志记录级别。
三、日志写入
手动记录
一般情况下,系统的日志记录是自动的,无需手动记录,但是某些时候也需要手动记录日志信息,Log类提供了3个方法用于记录日志。
由于系统在请求结束后会自动调用Log::save方法,所以通常,你只需要调用Log::record记录日志信息即可。
record方法用法如下:
Log::record('测试日志信息');
默认的话记录的日志级别是INFO,也可以指定日志级别:
Log::record('测试日志信息,这是警告级别','notice');
采用record方法记录的日志信息不是实时保存的,如果需要实时记录的话,可以采用write方法,例如:
Log::write('测试日志信息,这是警告级别,并且实时写入','notice');
V5.0.4+版本开始,为避免内存溢出,在命令行下面执行的话 日志信息会定时自动写入。
日志级别
ThinkPHP对系统的日志按照级别来分类,并且这个日志级别完全可以自己定义,系统内部使用的级别包括:
- log 常规日志,用于记录日志
- error 错误,一般会导致程序的终止
- notice 警告,程序可以运行但是还不够完美的错误
- info 信息,程序输出信息
- debug 调试,用于调试信息
- sql SQL语句,用于SQL记录,只在数据库的调试模式开启时有效
系统提供了不同日志级别的快速记录方法,例如:
Log::error('错误信息');
Log::info('日志信息');
// 和下面的用法等效
Log::record('错误信息','error');
Log::record('日志信息','info');
还封装了一个助手函数用于日志记录,例如:
trace('错误信息','error');
trace('日志信息','info');
也支持指定级别日志的输入,需要配置信息:
'log' => [
'type' => 'File',
// 日志记录级别,使用数组表示
'level' => ['error'],
],
单文件日志
在某些情况下,需要对日志记录进行分析和处理,那么开启单文件日志写入就会方便分析。
'log' => [
'type' => 'File',
// 日志记录级别,使用数组表示
'single' => true,
],
开启后,日志文件不再区分日期文件写入,而是统一写入到single.log文件中。
日志自动清理
V5.0.16+版本开始,支持文件日志的自动清理功能,你可以设置
'max_files' => 30
则日志文件最多只会保留30个,超过会自动清理较早的日志文件,避免日志文件长期写入占满磁盘空间。
开启自动清理功能后,不会生成日期子目录。
四、独立日志
为了便于分析,File类型的日志驱动还支持设置某些级别的日志信息单独文件记录,例如:
'log' => [
'type' => 'file',
// error和sql日志单独记录
'apart_level' => ['error','sql'],
],
设置后,就会单独生成error 和 sql两个类型的日志文件,主日志文件中将不再包含这两个级别的日志信息。
独立日志文件按天保存,不限制大小。
如果开启了单文件日志写入的话,独立日志不会区分日期目录写入。
五、日志清空
日志类提供了日志清空的方法,可以在需要的时候手动清空日志,日志清空仅仅是清空内存中的日志。
使用方法如下:
Log::clear();
六、写入授权
5.0的日志功能支持写入授权,我们可以设置某个请求的日志授权Key,然后设置允许授权写入的配置Key,实现个别用户日志记录的功能,从而提高高负载下面的日志记录性能。
首先需要在应用配置文件或者应用公共文件中添加当前访问的授权Key定义,例如:
// 设置IP为授权Key
Log::key(Request::instance()->ip());
然后在日志配置参数中增加allow_key参数,如下:
'log' => [
// 日志类型为File
'type' => 'File',
// 授权只有202.12.36.89 才能记录日志
'allow_key' => ['202.12.36.89'],
]