当前位置: 首页 > news >正文

ThinkPHP的log

文章目录

  • 环境
  • ThinkPHP的log
    • 配置
    • 级别
    • 写log
    • SQL的log
    • request的log
    • response的log
  • 参考

环境

  • Windows 11 专业版
  • XAMPP v3.3.0
  • PHP 8.2.12
  • ThinkPHP v8.1.3

ThinkPHP的log

ThinkPHP的log操作由 \think\Log 类完成,通常我们使用 think\facade\Log 类进行静态调用。

app/controller/Index.php 里添加 test1() 方法如下:

......
use think\facade\Log;
......public function test1() {Log::info('test1');   return 'OK';}

然后curl一下:

curl --silent -XGET "http://localhost:8000/index/test1"

此时,系统就会记录一条log。比如今天是2025年9月1号,在 runtime/log 目录下,会自动创建一个名为 202509 的目录,然后在该目录中创建 01.log 文件,如下:

在这里插入图片描述

配置

ThinkPHP的log配置文件是 config/log.php ,默认如下:

return [// 默认日志记录通道'default'      => 'file',// 日志记录级别'level'        => [],// 日志类型记录的通道 ['error'=>'email',...]'type_channel' => [],// 关闭全局日志写入'close'        => false,// 全局日志处理 支持闭包'processor'    => null,// 日志通道列表'channels'     => ['file' => [// 日志记录方式'type'           => 'File',// 日志保存目录'path'           => '',// 单文件日志写入'single'         => false,// 独立日志级别'apart_level'    => [],// 最大日志文件数量'max_files'      => 0,// 使用JSON格式记录'json'           => false,// 日志处理'processor'      => null,// 关闭通道日志写入'close'          => false,// 日志输出格式化'format'         => '[%s][%s] %s',// 是否实时写入'realtime_write' => false,],// 其它日志通道配置],];

基本上能做到顾名思义,而且默认配置看起来已经比较合理。

补充:如果想要设置单个log文件大小,可以加上 file_size 配置,比如:

            'file_size'      => 10485760, // 10 MB

如果log文件超出了限制,就会另存为一个以时间戳命名的文件。

级别

日志的级别从低到高依次为:

  • debug
  • info
  • notice
  • warning
  • error
  • critical
  • alert
  • emergency

默认的级别是 info

ThinkPHP额外增加了一个 sql 日志级别仅用于记录SQL日志(并且仅当开启数据库调试模式有效,详见下面的介绍)。

注意:系统发生异常后记录的日志级别是 error

app/controller/Index.php 里添加 test2() 方法如下:

    public function test2() {throw new \think\Exception('出错啦!');}

然后访问该方法:

curl --silent -XGET "http://localhost:8000/index/test2"

log记录如下:

[2025-09-01T21:17:57+08:00][error] [0]出错啦!

写log

  • Log::record() :记录日志信息到内存,系统在请求结束后会自动调用 Log::save() 方法统一进行日志信息写入
  • Log::write() :实时写入一条日志信息
  • Log::info() :相当于 Log::write(xxx, 'info') ,其它级别也同理

注意:前面提到,在配置文件 config/log.php 里, realtime_write 可以设置是否实时写入log,事实上该配置只影响 Log::record() ,不影响 Log::write() ,因为后者始终是实时写入的。

日志可以传入一个数组,并且被替换到日志内容中。

例如,在 app/controller/Index.php 里添加 test3() 方法如下::

    public function test3() {Log::info('name: {name}, age: {age}', ['name' => 'Tom', 'age' => 20]);}

然后访问该方法:

curl --silent -XGET "http://localhost:8000/index/test3"

log记录如下:

[2025-09-01T21:26:32+08:00][info] name: Tom, age: 20

SQL的log

查看 config/database.php 的配置,默认如下:

......'trigger_sql'     => env('APP_DEBUG', true),
......

查看 .env 里的 APP_DEBUG 配置:

APP_DEBUG = true

注意:在生产环境中, APP_DEBUG 一般会设置为false。如果希望显示SQL,可以直接把 trigger_sql 设置为true。

测试一下,在 app/controller/Index.php 里添加 test4() 方法如下::

......
use think\facade\Db;......public function test4() {$data = Db::table('t1')->where('c1', '>', 1)->select();return json($data);}

然后访问该方法:

curl --silent -XGET "http://localhost:8000/index/test4"

log记录如下:

[2025-09-01T21:44:36+08:00][sql] SELECT * FROM `t1` WHERE  `c1` > 1 [ RunTime:0.000520s ]

request的log

如果能把ThinkPHP收到的request也记到log里,一来可以确认ThinkPHP是否收到了request,二来可以查看request的详细信息,帮助debug问题。

不过,貌似没有简单的配置可以记录request log,可以通过中间件(middleware)来完成。

首先创建中间件,可以用命令行操作(在项目根目录下):

php think make:middleware RequestLog

操作完成后,会在 app/middleware 目录下创建 RequestLog.php 文件如下:

<?php
declare (strict_types = 1);namespace app\middleware;class RequestLog
{/*** 处理请求** @param \think\Request $request* @param \Closure       $next* @return Response*/public function handle($request, \Closure $next){}
}

修改 handle() 方法如下:

......
use think\facade\Log;
......public function handle($request, \Closure $next){// 记录请求信息$logData = ['ip' => $request->ip(),'method' => $request->method(),'url' => $request->url(),'params' => $request->param(),'header' => $request->header(),'user_agent' => $request->header('user-agent'),'time' => date('Y-m-d H:i:s')];Log::info('Request Received: ' . json_encode($logData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));return $next($request);}
}

可以根据需求,记录各种详细信息,注意可能会有一些敏感信息。

注意:如果担心中间件出问题影响后续操作,可以用 try...catch 包起来,这样即使记录log时出了问题,也不会影响对request的后续操作。

然后在 app/middleware.php 里注册中间件:

return [......\app\middleware\RequestLog::class,
];

现在,ThinkPHP就会把收到的request记录到log里,比如:

[2025-09-02T10:34:45+08:00][info] Request Received: {"ip": "111.201.72.246","method": "GET","url": "\/api\/index.php\/login\/checkLogin","params": [],"header": {"priority": "u=4","cookie": "PHPSESSID=0f117871cf16d58cf74f63cbba71963d","connection": "keep-alive","referer": "http:\/\/chinatt.org.cn\/","accept-encoding": "gzip, deflate","accept-language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2","accept": "*\/*","user-agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64; rv:142.0) Gecko\/20100101 Firefox\/142.0","host": "chinatt.org.cn"},"user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64; rv:142.0) Gecko\/20100101 Firefox\/142.0","time": "2025-09-02 10:34:45"
}

response的log

既然可以在处理request前记录request的log,那么同理,也可以在生成response后记录response的log。

修改 RequestLog.php 如下:

    public function handle($request, \Closure $next){// 记录请求信息$logData = ['ip' => $request->ip(),'method' => $request->method(),'url' => $request->url(),'params' => $request->param(),'header' => $request->header(),'user_agent' => $request->header('user-agent'),'time' => date('Y-m-d H:i:s')];Log::info('Request Received: ' . json_encode($logData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));$response = $next($request);// 记录响应信息$logData = ['code' => $response->getCode(),'header' => $response->getHeader(),'content' => $response->getContent(),'time' => date('Y-m-d H:i:s')];Log::info('Response Sent: '. json_encode($logData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));return $response;}

可根据需求决定要记录哪些详细信息。另外,response有可能非常大,可能需要截取其中一部分。

参考

  • https://doc.thinkphp.cn/v8_0/log.html

文章转载自:

http://GLKUWcWA.zLxqy.cn
http://uPu8a4RJ.zLxqy.cn
http://Sr0lHlV8.zLxqy.cn
http://t5q55yUM.zLxqy.cn
http://bPmD6HwJ.zLxqy.cn
http://qLt8jgae.zLxqy.cn
http://4M1dj79l.zLxqy.cn
http://jM9KIGL4.zLxqy.cn
http://JpfvH83s.zLxqy.cn
http://Yvgtqbjx.zLxqy.cn
http://Tw9vZeyl.zLxqy.cn
http://FO3oKehs.zLxqy.cn
http://6YtsSRC4.zLxqy.cn
http://iHVCxgRy.zLxqy.cn
http://ydE1ZpOx.zLxqy.cn
http://J3lLGZra.zLxqy.cn
http://mkm9epb2.zLxqy.cn
http://AIhzCGtY.zLxqy.cn
http://wancfQDe.zLxqy.cn
http://JVAexVPg.zLxqy.cn
http://X9CXYSmu.zLxqy.cn
http://BpV0MqDb.zLxqy.cn
http://CmKk0Oq0.zLxqy.cn
http://YTzPl0dq.zLxqy.cn
http://d3QKBODw.zLxqy.cn
http://X72tWU2M.zLxqy.cn
http://jhQDohmK.zLxqy.cn
http://G74tc6fJ.zLxqy.cn
http://VrWtCak0.zLxqy.cn
http://DAIEeZ6m.zLxqy.cn
http://www.dtcms.com/a/363351.html

相关文章:

  • 使用 C 模仿 C++ 模板的拙劣方法
  • Flutter 3.35.2 主题颜色设置指南
  • 揭密设计模式:像搭乐高一样构建功能的装饰器模式
  • 《Vue进阶教程》(7)响应式系统介绍
  • 05 Centos 7尝试是否有网络
  • 基于STM32与华为云联动的智能电动车充电桩管理系统
  • Stop-Process : 由于以下错误而无法停止进程“redis-server (26392)”: 拒绝访问。
  • Python OpenCV图像处理与深度学习:Python OpenCV DNN模块深度学习与图像处理
  • PHP的error_log()函数
  • 智慧工地如何撕掉“高危低效”标签?三大社会效益重构建筑业价值坐标
  • 一款开源的CMS系统简介
  • 优秀开源内容转自公众号后端开发成长指南
  • QuickUp-Ubuntu
  • js设计模式-职责链模式
  • 【音视频】Opus 编码格式介绍
  • WPF应用程序资源和样式的使用示例
  • HarmonyOS 应用开发新范式:深入剖析 Stage 模型与 ArkUI 最佳实践
  • 基于vue3和springboot框架集成websocket
  • 网络数据包是怎么在客户端和服务端之间进行传输的?
  • C#实现与西门子S7-1200_1500 PLC通信
  • qt QWebSocket详解
  • 系统扩展策略
  • 【LeetCode_26】删除有序数组中的重复项
  • 小迪web自用笔记24
  • GPT-5论文选题实测:如何从2000篇文献中提炼出3个可快速落地的高命中选题?
  • 从零开始学Vue3:Vue3的生命周期
  • Leetcode二分查找(4)
  • 开悟篇Docker从零到实战一篇文章搞定
  • 洗衣店小程序的设计与实现
  • GDB 调试