ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
# 日志处理 日志记录和写入由`\think\Log`类完成,通常我们使用`think\facade\Log`类进行静态调用。 由于日志记录了所有的运行错误,因此养成经常查看日志文件的习惯,可以避免和及早发现很多的错误隐患。 > 5\.1的日志遵循`PSR-3`规范 - [日志配置](#_8) - [日志写入](#_55) - [手动记录](#_57) - [日志级别](#_93) - [上下文信息](#_127) - [独立日志](#_137) - [单文件日志](#_151) - [写入授权](#_172) - [清空日志](#_194) - [日志自动清理(`V5.1.6+`)](#V516_213) - [JSON格式日志(`V5.1.15+`)](#JSONV5115_229) ## 日志配置 日志的配置文件是配置文件目录下的`log.php`文件,如果需要针对不同的模块设置不同的日志类型,则需要在模块配置目录下的`log.php`中配置,系统在进行日志写入之前会读取该配置文件进行初始化。 日志配置参数根据不同的日志类型有所区别,内置的日志类型包括:`file`、`socket`和`test`(仅用于测试,不会实际记录任何日志),日志类型使用`type`参数配置即可。 日志的全局配置参数包含(无论使用什么日志类型都支持): 参数描述type日志类型(或者驱动类名称)level允许记录的日志级别allow\_key允许日志写入的授权keyclose是否关闭日志写入(`V5.1.8+`)> 默认的日志类型是`File`方式,可以通过驱动的方式来扩展支持更多的记录方式。 文件类型日志的话,还支持下列配置参数: 参数描述path日志存储路径file\_size日志文件大小限制(超出会生成多个文件)apart\_level独立记录的日志级别time\_format时间记录格式single是否单一文件日志max\_files最大日志文件数(超过自动清理 `V5.1.6+`)> 为了避免同一个目录下面的日志文件过多的性能问题,日志文件会自动生成日期子目录。 下面是一个`log.php`配置示例: ``` return [ // 日志记录方式,支持 file socket 或者自定义驱动类 'type' => 'File', //日志保存目录 'path' => '../logs/', //单个日志文件的大小限制,超过后会自动记录到第二个文件 'file_size' =>2097152, //日志的时间格式,默认是` c ` 'time_format' =>'c' ], ``` > 系统并未提供关闭日志的方法,但有两种方式可以关闭日志的写入,第一种方式是设置日志类型为test,即不写入任何日志。第二种方式是设置日志记录级别,只记录需要的日志。 ## 日志写入 ### 手动记录 一般情况下,系统的日志记录是自动的,无需手动记录,但是某些时候也需要手动记录日志信息,Log类提供了3个方法用于记录日志。 方法描述record()记录日志信息到内存save()把保存在内存中的日志信息(用指定的记录方式)写入,并清空内存中的日志write()实时写入一条日志信息,会触发save操作由于系统在请求结束后会自动调用`Log::save`方法,所以通常,你只需要调用`Log::record`记录日志信息即可。 record方法用法如下: ``` Log::record('测试日志信息'); ``` 默认记录的日志级别是`info`,也可以指定日志级别: ``` Log::record('测试日志信息,这是警告级别','notice'); ``` 采用`record`方法记录的日志信息不是实时保存的,如果需要实时记录的话,可以采用`write`方法,例如: ``` Log::write('测试日志信息,这是警告级别,并且实时写入','notice'); ``` > write方法同时也会把内存中的日志信息写入到文件。 > 为避免内存溢出,在命令行下面执行的话日志信息会实时写入。 `V5.1.6+`版本开始,可以使用`close`方法临时关闭当前请求的日志写入。 ### 日志级别 ThinkPHP对系统的日志按照级别来分类记录,按照`PSR-3`日志规范,日志的级别从低到高依次为: `debug`, `info`, `notice`, `warning`, `error`, `critical`, `alert`, `emergency`,ThinkPHP额外增加了一个`sql`日志级别仅用于记录`SQL`日志(并且仅当开启数据库调试模式有效)。 > 系统发生异常后记录的日志级别是`error` 系统提供了不同日志级别的快速记录方法,例如: ``` Log::error('错误信息'); Log::info('日志信息'); // 和下面的用法等效 Log::record('错误信息','error'); Log::record('日志信息','info'); ``` 还封装了一个助手函数用于日志记录,例如: ``` trace('错误信息','error'); trace('日志信息','info'); ``` 也支持指定级别日志的输入,需要配置信息: ``` return [ 'type' => 'File', // 日志记录级别,使用数组表示 'level' => ['error','alert'], ], ``` 上面的配置表示只记录`error`和`alert`级别的日志信息。 > 默认情况下是不会记录HTTP异常日志(避免受一些攻击的影响写入大量日志),除非你接管了系统的异常处理,重写了report方法。 ### 上下文信息 日志可以传入上下文信息(数组),并且被替换到日志内容中,例如: ``` Log::info('日志信息{user}', ['user'=>'流年']); ``` 实际写入日志的时候,`{user}`会被替换为流年。 ### 独立日志 为了便于分析,`File`类型的日志还支持设置某些级别的日志信息单独文件记录,例如: ``` return [ 'type' => 'file', // error和sql日志单独记录 'apart_level' => ['error','sql'], ], ``` 设置后,就会单独生成`error` 和 `sql`两个类型的日志文件,主日志文件中将不再包含这两个级别的日志信息。 ### 单文件日志 默认情况下,日志是按照日期为目录,按天为文件生成的,但如果希望仅生成单个文件(方便其它的工具或者服务读取以及分析日志)。 ``` return [ 'single' => true, 'file_size' => 1024*1024*10, ]; ``` 开启生成单个文件后,`file_size`和`apart_level`参数依然有效,超过文件大小限制后,系统会自动生成备份日志文件。 默认的单文件日志名是`single.log`,如果需要更改日志文件名,可以设置 ``` return [ 'single' => 'single_file', 'file_size' => 1024*1024*10, ]; ``` 那么实际生成的日志文件名是 `single_file.log`,如果设置了`apart_level`的话,可能还会生成 `single_file.error.log`之类的日志。 ### 写入授权 日志支持写入授权,我们可以设置某个请求的日志授权Key,然后设置允许授权写入的配置`Key`,实现个别用户日志记录的功能,从而提高高负载下的日志记录性能。 首先需要在应用配置文件或者应用公共文件中添加当前访问的授权Key定义,例如: ``` // 设置IP为授权Key Log::key(Request::ip()); ``` 然后在日志配置参数中增加`allow_key`参数,如下: ``` return [ // 日志类型为File 'type' => 'File', // 授权只有202.12.36.89 才能记录日志 'allow_key' => ['202.12.36.89'], ] ``` ### 清空日志 一旦执行save或者write方法后,内存中的日志信息就会被自动清空,如果需要手动清空可以使用: ``` Log::clear(); ``` 在清空日志或者调用`save/write`方法之前,你可以使用getLog方法获取内存中的日志。 ``` // 获取错误类型日志 $error = Log::getLog('error'); // 获取全部日志 $logs = Log::getLog(); ``` > 日志清空仅仅是清空内存中的日志。 ### 日志自动清理(`V5.1.6+`) 从`V5.1.6+`版本开始,文件类型的日志支持自动清理。可以设置`max_files`参数,超过数量的最早日志将会自动删除。 例如,下面设置日志最多保存数量为30个 ``` return [ 'type' => 'File', 'max_files' => 30, ]; ``` > 设置`max_files`参数后,日志文件将不会分日期子目录存放。 ### JSON格式日志(`V5.1.15+`) 从`V5.1.15+`版本开始,可以支持`JSON`格式记录文件日志,更加方便一些第三方日志分析工具进行日志分析。 在日志配置文件中,添加 ``` 'json' => true ``` 即可开启`JSON`格式记录,CLI命令行的日志记录同样有效。 使用JSON格式记录后,每次请求是一行JSON数据,但如果使用`Log::write`记录的日志是例外的单独一行JSON数据。 > JSON格式记录日志的时候,独立记录日志级别参数`apart_level`无效。